Since arguments may on the stack even in the kernel, load_image() now

always copies the arguments and environment arrays.
No need for the "owns_arrays" in team_arg anymore - it now always owns
them.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@9363 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2004-10-15 01:52:07 +00:00
parent b1cec3747c
commit a7fa05a54b
+56 -12
View File
@@ -44,7 +44,6 @@ struct team_arg {
char **args; char **args;
uint32 env_count; uint32 env_count;
char **env; char **env;
bool owns_arrays;
}; };
struct fork_arg { struct fork_arg {
@@ -200,6 +199,45 @@ free_strings_array(char **strings, int32 count)
} }
/** Copy an array of strings in kernel space
*
* \param strings strings array to be copied
* \param count number of strings in array
* \param kstrings pointer to the kernel copy
* \return \c B_OK on success, or an appropriate error code on
* failure.
*/
static status_t
copy_strings_array(const char **in, int32 count, char ***_strings)
{
status_t status;
char **strings;
int32 i = 0;
strings = (char **)malloc((count + 1) * sizeof(char *));
if (strings == NULL)
return B_NO_MEMORY;
for (; i < count; i++) {
strings[i] = strdup(in[i]);
if (strings[i] == NULL) {
status = B_NO_MEMORY;
goto error;
}
}
strings[count] = NULL;
*_strings = strings;
return B_OK;
error:
free_strings_array(strings, i);
return status;
}
/** Copy an array of strings from user space to kernel space /** Copy an array of strings from user space to kernel space
* *
* \param strings userspace strings array * \param strings userspace strings array
@@ -733,17 +771,15 @@ get_arguments_data_size(char **args, int32 argc)
static void static void
free_team_arg(struct team_arg *teamArg) free_team_arg(struct team_arg *teamArg)
{ {
if (teamArg->owns_arrays) {
free_strings_array(teamArg->args, teamArg->arg_count); free_strings_array(teamArg->args, teamArg->arg_count);
free_strings_array(teamArg->env, teamArg->env_count); free_strings_array(teamArg->env, teamArg->env_count);
}
free(teamArg); free(teamArg);
} }
static struct team_arg * static struct team_arg *
create_team_arg(int32 argc, char **args, int32 envCount, char **env, bool deleteArrays) create_team_arg(int32 argc, char **args, int32 envCount, char **env)
{ {
struct team_arg *teamArg = (struct team_arg *)malloc(sizeof(struct team_arg)); struct team_arg *teamArg = (struct team_arg *)malloc(sizeof(struct team_arg));
if (teamArg == NULL) if (teamArg == NULL)
@@ -753,7 +789,6 @@ create_team_arg(int32 argc, char **args, int32 envCount, char **env, bool delete
teamArg->args = args; teamArg->args = args;
teamArg->env_count = envCount; teamArg->env_count = envCount;
teamArg->env = env; teamArg->env = env;
teamArg->owns_arrays = deleteArrays;
return teamArg; return teamArg;
} }
@@ -873,8 +908,7 @@ team_create_thread_start(void *args)
*/ */
static thread_id static thread_id
load_image_etc(int32 argCount, const char **args, int32 envCount, const char **env, load_image_etc(int32 argCount, char **args, int32 envCount, char **env, int32 priority)
bool deleteStrings, int32 priority)
{ {
struct process_group *group; struct process_group *group;
struct team *team, *parent; struct team *team, *parent;
@@ -907,7 +941,7 @@ load_image_etc(int32 argCount, const char **args, int32 envCount, const char **e
restore_interrupts(state); restore_interrupts(state);
// copy the args over // copy the args over
teamArgs = create_team_arg(argCount, (char **)args, envCount, (char **)env, deleteStrings); teamArgs = create_team_arg(argCount, args, envCount, env);
if (teamArgs == NULL) { if (teamArgs == NULL) {
err = B_NO_MEMORY; err = B_NO_MEMORY;
goto err1; goto err1;
@@ -994,7 +1028,7 @@ exec_team(int32 argCount, char **args, int32 envCount, char **env)
// ToDo: maybe we should make sure upfront that the target path is an app? // ToDo: maybe we should make sure upfront that the target path is an app?
teamArgs = create_team_arg(argCount, args, envCount, env, true); teamArgs = create_team_arg(argCount, args, envCount, env);
if (teamArgs == NULL) if (teamArgs == NULL)
return B_NO_MEMORY; return B_NO_MEMORY;
@@ -1372,12 +1406,22 @@ wait_for_child(thread_id child, uint32 flags, int32 *_reason, status_t *_returnC
thread_id thread_id
load_image(int32 argCount, const char **args, const char **env) load_image(int32 argCount, const char **args, const char **env)
{ {
// count env variables char **argsCopy, **envCopy;
int32 envCount = 0; int32 envCount = 0;
if (copy_strings_array(args, argCount, &argsCopy) != B_OK)
return B_NO_MEMORY;
// count env variables
while (env && env[envCount] != NULL) while (env && env[envCount] != NULL)
envCount++; envCount++;
return load_image_etc(argCount, args, envCount, env, false, B_NORMAL_PRIORITY); if (copy_strings_array(env, envCount, &envCopy) != B_OK) {
free_strings_array(argsCopy, argCount);
return B_NO_MEMORY;
}
return load_image_etc(argCount, argsCopy, envCount, envCopy, B_NORMAL_PRIORITY);
} }
@@ -2014,7 +2058,7 @@ _user_load_image(int32 argCount, const char **userArgs, int32 envCount,
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
} }
return load_image_etc(argCount, (const char **)args, envCount, (const char **)env, true, priority); return load_image_etc(argCount, args, envCount, env, priority);
} }