diff --git a/include/nuttx/kmalloc.h b/include/nuttx/kmalloc.h index 9ea6916d0b..334b2186f3 100644 --- a/include/nuttx/kmalloc.h +++ b/include/nuttx/kmalloc.h @@ -123,6 +123,11 @@ extern "C" FAR void *group_malloc(FAR struct task_group_s *group, size_t nbytes); +/* Functions defined in group/group_realloc.c *******************************/ + +FAR void *group_realloc(FAR struct task_group_s *group, FAR void *oldmem, + size_t newsize); + /* Functions defined in group/group_zalloc.c ********************************/ FAR void *group_zalloc(FAR struct task_group_s *group, size_t nbytes); @@ -136,9 +141,10 @@ void group_free(FAR struct task_group_s *group, FAR void *mem); * in privileges. */ -# define group_malloc(g,n) kumm_malloc(n) -# define group_zalloc(g,n) kumm_zalloc(n) -# define group_free(g,m) kumm_free(m) +# define group_malloc(g,n) kumm_malloc(n) +# define group_realloc(g,p,s) kumm_realloc((p),(s)) +# define group_zalloc(g,n) kumm_zalloc(n) +# define group_free(g,m) kumm_free(m) #endif diff --git a/sched/environ/env_dup.c b/sched/environ/env_dup.c index 5d0df69bbd..a337e62a2e 100644 --- a/sched/environ/env_dup.c +++ b/sched/environ/env_dup.c @@ -94,7 +94,7 @@ int env_dup(FAR struct task_group_s *group) { /* There is an environment, duplicate it */ - envp = (FAR char *)kumm_malloc(envlen); + envp = (FAR char *)group_malloc(ptcb->group, envlen); if (envp == NULL) { /* The parent's environment can not be inherited due to a diff --git a/sched/environ/env_release.c b/sched/environ/env_release.c index 86442dc941..412e2661a4 100644 --- a/sched/environ/env_release.c +++ b/sched/environ/env_release.c @@ -69,7 +69,7 @@ void env_release(FAR struct task_group_s *group) { /* Free the environment */ - kumm_free(group->tg_envp); + group_free(group, group->tg_envp); } /* In any event, make sure that all environment-related variables in the diff --git a/sched/environ/env_setenv.c b/sched/environ/env_setenv.c index 3fdc2117f8..5a959a14d0 100644 --- a/sched/environ/env_setenv.c +++ b/sched/environ/env_setenv.c @@ -145,7 +145,7 @@ int setenv(FAR const char *name, FAR const char *value, int overwrite) if (group->tg_envp) { newsize = group->tg_envsize + varlen; - newenvp = (FAR char *)kumm_realloc(group->tg_envp, newsize); + newenvp = (FAR char *)group_realloc(group, group->tg_envp, newsize); if (!newenvp) { ret = ENOMEM; @@ -157,7 +157,7 @@ int setenv(FAR const char *name, FAR const char *value, int overwrite) else { newsize = varlen; - newenvp = (FAR char *)kumm_malloc(varlen); + newenvp = (FAR char *)group_malloc(group, varlen); if (!newenvp) { ret = ENOMEM; diff --git a/sched/environ/env_unsetenv.c b/sched/environ/env_unsetenv.c index c83646b757..2a575739e3 100644 --- a/sched/environ/env_unsetenv.c +++ b/sched/environ/env_unsetenv.c @@ -86,7 +86,7 @@ int unsetenv(FAR const char *name) if (group->tg_envp != NULL) { - kumm_free(group->tg_envp); + group_free(group, group->tg_envp); group->tg_envp = NULL; } @@ -96,7 +96,9 @@ int unsetenv(FAR const char *name) { /* Reallocate the environment to reclaim a little memory */ - newenvp = (FAR char *)kumm_realloc(group->tg_envp, newsize); + newenvp = (FAR char *)group_realloc(group, group->tg_envp, + newsize); + if (newenvp == NULL) { set_errno(ENOMEM); diff --git a/sched/group/Make.defs b/sched/group/Make.defs index b0a2cf7e13..0fbc28183b 100644 --- a/sched/group/Make.defs +++ b/sched/group/Make.defs @@ -50,7 +50,7 @@ CSRCS += group_exitinfo.c endif ifneq ($(CONFIG_BUILD_FLAT),y) -CSRCS += group_malloc.c group_zalloc.c group_free.c +CSRCS += group_malloc.c group_realloc.c group_zalloc.c group_free.c endif # Include group build support diff --git a/sched/group/group_realloc.c b/sched/group/group_realloc.c new file mode 100644 index 0000000000..04c4140239 --- /dev/null +++ b/sched/group/group_realloc.c @@ -0,0 +1,83 @@ +/**************************************************************************** + * sched/group/group_realloc.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include + +#include +#include + +#include "sched/sched.h" +#include "group/group.h" + +#ifdef CONFIG_MM_KERNEL_HEAP + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: group_realloc + * + * Description: + * Re-allocate memory appropriate for the group type. If the memory is + * part of a privileged group, then it should be allocated so that it + * is only accessible by privileged code; Otherwise, it is a user mode + * group and must be allocated so that it accessible by unprivileged + * code. + * + ****************************************************************************/ + +FAR void *group_realloc(FAR struct task_group_s *group, FAR void *oldmem, + size_t newsize) +{ + /* A NULL group pointer means the current group */ + + if (group == NULL) + { + FAR struct tcb_s *tcb = this_task(); + DEBUGASSERT(tcb && tcb->group); + group = tcb->group; + } + + /* Check the group type */ + + if ((group->tg_flags & GROUP_FLAG_PRIVILEGED) != 0) + { + /* It is a privileged group... use the kernel mode memory allocator */ + + return kmm_realloc(oldmem, newsize); + } + else + { + /* This is an unprivileged group... use the user mode memory + * allocator. + */ + + return kumm_realloc(oldmem, newsize); + } +} + +#endif /* CONFIG_MM_KERNEL_HEAP */ diff --git a/sched/init/nx_start.c b/sched/init/nx_start.c index 7938ce38de..ba8a239964 100644 --- a/sched/init/nx_start.c +++ b/sched/init/nx_start.c @@ -558,7 +558,8 @@ void nx_start(void) */ group_initialize(&g_idletcb[i]); - g_idletcb[i].cmn.group->tg_flags = GROUP_FLAG_NOCLDWAIT; + g_idletcb[i].cmn.group->tg_flags = GROUP_FLAG_NOCLDWAIT | + GROUP_FLAG_PRIVILEGED; } g_lastpid = CONFIG_SMP_NCPUS - 1;