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:
+58
-14
@@ -44,7 +44,6 @@ struct team_arg {
|
||||
char **args;
|
||||
uint32 env_count;
|
||||
char **env;
|
||||
bool owns_arrays;
|
||||
};
|
||||
|
||||
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
|
||||
*
|
||||
* \param strings userspace strings array
|
||||
@@ -733,17 +771,15 @@ get_arguments_data_size(char **args, int32 argc)
|
||||
static void
|
||||
free_team_arg(struct team_arg *teamArg)
|
||||
{
|
||||
if (teamArg->owns_arrays) {
|
||||
free_strings_array(teamArg->args, teamArg->arg_count);
|
||||
free_strings_array(teamArg->env, teamArg->env_count);
|
||||
}
|
||||
free_strings_array(teamArg->args, teamArg->arg_count);
|
||||
free_strings_array(teamArg->env, teamArg->env_count);
|
||||
|
||||
free(teamArg);
|
||||
}
|
||||
|
||||
|
||||
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));
|
||||
if (teamArg == NULL)
|
||||
@@ -753,7 +789,6 @@ create_team_arg(int32 argc, char **args, int32 envCount, char **env, bool delete
|
||||
teamArg->args = args;
|
||||
teamArg->env_count = envCount;
|
||||
teamArg->env = env;
|
||||
teamArg->owns_arrays = deleteArrays;
|
||||
|
||||
return teamArg;
|
||||
}
|
||||
@@ -873,8 +908,7 @@ team_create_thread_start(void *args)
|
||||
*/
|
||||
|
||||
static thread_id
|
||||
load_image_etc(int32 argCount, const char **args, int32 envCount, const char **env,
|
||||
bool deleteStrings, int32 priority)
|
||||
load_image_etc(int32 argCount, char **args, int32 envCount, char **env, int32 priority)
|
||||
{
|
||||
struct process_group *group;
|
||||
struct team *team, *parent;
|
||||
@@ -907,7 +941,7 @@ load_image_etc(int32 argCount, const char **args, int32 envCount, const char **e
|
||||
restore_interrupts(state);
|
||||
|
||||
// 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) {
|
||||
err = B_NO_MEMORY;
|
||||
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?
|
||||
|
||||
teamArgs = create_team_arg(argCount, args, envCount, env, true);
|
||||
teamArgs = create_team_arg(argCount, args, envCount, env);
|
||||
if (teamArgs == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
@@ -1372,12 +1406,22 @@ wait_for_child(thread_id child, uint32 flags, int32 *_reason, status_t *_returnC
|
||||
thread_id
|
||||
load_image(int32 argCount, const char **args, const char **env)
|
||||
{
|
||||
// count env variables
|
||||
char **argsCopy, **envCopy;
|
||||
int32 envCount = 0;
|
||||
|
||||
if (copy_strings_array(args, argCount, &argsCopy) != B_OK)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
// count env variables
|
||||
while (env && env[envCount] != NULL)
|
||||
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 load_image_etc(argCount, (const char **)args, envCount, (const char **)env, true, priority);
|
||||
return load_image_etc(argCount, args, envCount, env, priority);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user