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.

This commit is contained in:
Gregory Nutt 2017-09-18 19:02:54 -06:00
parent 41c271d032
commit d33857002a
1 changed files with 35 additions and 13 deletions

View File

@ -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 <gnutt@nuttx.org>
*
* 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();