From d33857002a6cb6b4b9504394a5244e0449e0dece Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 18 Sep 2017 19:02:54 -0600 Subject: [PATCH] sched/env_dup.c: Fix an error in the duplication of the child tasks environment in the special case where the parent's environment was created, but then all of the variables were unset. In that case, there is still an allocation in place but the size of the allocation is zero. This case was not being handled correctly when a child task attempts to create its environment and inherit the zero-size partent environment. Noted by Anthony Merlino. --- sched/environ/env_dup.c | 48 ++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/sched/environ/env_dup.c b/sched/environ/env_dup.c index 1745385daf..08b0e1b617 100644 --- a/sched/environ/env_dup.c +++ b/sched/environ/env_dup.c @@ -1,7 +1,7 @@ /**************************************************************************** * sched/environ/env_dup.c * - * Copyright (C) 2007, 2009, 2011, 2013 Gregory Nutt. All rights reserved. + * Copyright (C) 2007, 2009, 2011, 2013, 2017 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -82,7 +82,7 @@ int env_dup(FAR struct task_group_s *group) size_t envlen; int ret = OK; - DEBUGASSERT(group && ptcb && ptcb->group); + DEBUGASSERT(group != NULL && ptcb != NULL && ptcb->group != NULL); /* Pre-emption must be disabled throughout the following because the * environment may be shared. @@ -92,22 +92,44 @@ int env_dup(FAR struct task_group_s *group) /* Does the parent task have an environment? */ - if (ptcb->group && ptcb->group->tg_envp) + if (ptcb->group != NULL && ptcb->group->tg_envp != NULL) { - /* Yes..The parent task has an environment, duplicate it */ + /* Yes.. The parent task has an environment allocation. */ envlen = ptcb->group->tg_envsize; - envp = (FAR char *)kumm_malloc(envlen); - if (!envp) + envp = NULL; + + /* A special case is that the parent has an "empty" environment + * allocation, i.e., there is an allocation in place but it + * contains no variable definitions and, hence, envlen == 0. + */ + + if (envlen > 0) { - ret = -ENOMEM; - } - else - { - group->tg_envsize = envlen; - group->tg_envp = envp; - memcpy(envp, ptcb->group->tg_envp, envlen); + /* There is an environment, duplicate it */ + + envp = (FAR char *)kumm_malloc(envlen); + if (envp == NULL) + { + /* The parent's environment can not be inherited due to a + * failure in the allocation of the child environment. + */ + + envlen = 0; + ret = -ENOMEM; + } + else + { + /* Duplicate the parent environment. */ + + memcpy(envp, ptcb->group->tg_envp, envlen); + } } + + /* Save the size and child environment allocation. */ + + group->tg_envsize = envlen; + group->tg_envp = envp; } sched_unlock();