diff --git a/headers/private/kernel/team.h b/headers/private/kernel/team.h index 510b803f3e..e33166ac72 100644 --- a/headers/private/kernel/team.h +++ b/headers/private/kernel/team.h @@ -76,7 +76,7 @@ status_t _user_kill_team(thread_id thread); thread_id _user_wait_for_child(thread_id child, uint32 flags, int32 *_reason, status_t *_returnCode); status_t _user_exec(const char *path, const char* const* flatArgs, - size_t flatArgsSize, int32 argCount, int32 envCount); + size_t flatArgsSize, int32 argCount, int32 envCount, mode_t umask); thread_id _user_fork(void); team_id _user_get_current_team(void); pid_t _user_process_info(pid_t process, int32 which); diff --git a/headers/private/system/syscalls.h b/headers/private/system/syscalls.h index 42e6d57e9e..cd510bdf2d 100644 --- a/headers/private/system/syscalls.h +++ b/headers/private/system/syscalls.h @@ -137,7 +137,8 @@ extern status_t _kern_wait_for_team(team_id team, status_t *_returnCode); extern thread_id _kern_wait_for_child(thread_id child, uint32 flags, int32 *_reason, status_t *_returnCode); extern status_t _kern_exec(const char *path, const char* const* flatArgs, - size_t flatArgsSize, int32 argCount, int32 envCount); + size_t flatArgsSize, int32 argCount, int32 envCount, + mode_t umask); extern thread_id _kern_fork(void); extern pid_t _kern_process_info(pid_t process, int32 which); extern pid_t _kern_setpgid(pid_t process, pid_t group); diff --git a/headers/private/system/user_runtime.h b/headers/private/system/user_runtime.h index 4600836e22..9bd6d1712c 100644 --- a/headers/private/system/user_runtime.h +++ b/headers/private/system/user_runtime.h @@ -28,6 +28,7 @@ struct user_space_program_args { int env_count; char **args; char **env; + mode_t umask; // (mode_t)-1 means not set }; #endif /* KERNEL_USER_RUNTIME_H_ */ diff --git a/src/system/kernel/team.cpp b/src/system/kernel/team.cpp index 064a99e151..0bed51fb2d 100644 --- a/src/system/kernel/team.cpp +++ b/src/system/kernel/team.cpp @@ -72,6 +72,7 @@ struct team_arg { size_t flat_args_size; uint32 arg_count; uint32 env_count; + mode_t umask; port_id error_port; uint32 error_token; }; @@ -975,8 +976,8 @@ free_team_arg(struct team_arg* teamArg) static status_t create_team_arg(struct team_arg** _teamArg, const char* path, char** flatArgs, - size_t flatArgsSize, int32 argCount, int32 envCount, port_id port, - uint32 token) + size_t flatArgsSize, int32 argCount, int32 envCount, mode_t umask, + port_id port, uint32 token) { struct team_arg* teamArg = (struct team_arg*)malloc(sizeof(team_arg)); if (teamArg == NULL) @@ -994,6 +995,7 @@ create_team_arg(struct team_arg** _teamArg, const char* path, char** flatArgs, teamArg->flat_args_size = flatArgsSize; teamArg->arg_count = argCount; teamArg->env_count = envCount; + teamArg->umask = umask; teamArg->error_port = port; teamArg->error_token = token; @@ -1091,6 +1093,7 @@ team_create_thread_start(void* args) sizeof(port_id)) < B_OK || user_memcpy(&programArgs->error_token, &teamArgs->error_token, sizeof(uint32)) < B_OK + || user_memcpy(&programArgs->umask, &teamArgs->umask, sizeof(mode_t)) < B_OK || user_memcpy(userArgs, teamArgs->flat_args, teamArgs->flat_args_size) < B_OK) { // the team deletion process will clean this mess @@ -1219,7 +1222,7 @@ load_image_internal(char**& _flatArgs, size_t flatArgsSize, int32 argCount, update_set_id_user_and_group(team, path); status = create_team_arg(&teamArgs, path, flatArgs, flatArgsSize, argCount, - envCount, errorPort, errorToken); + envCount, (mode_t)-1, errorPort, errorToken); if (status != B_OK) goto err1; @@ -1348,7 +1351,7 @@ err0: */ static status_t exec_team(const char* path, char**& _flatArgs, size_t flatArgsSize, - int32 argCount, int32 envCount) + int32 argCount, int32 envCount, mode_t umask) { // NOTE: Since this function normally doesn't return, don't use automatic // variables that need destruction in the function scope. @@ -1402,7 +1405,7 @@ exec_team(const char* path, char**& _flatArgs, size_t flatArgsSize, return status; status = create_team_arg(&teamArgs, path, flatArgs, flatArgsSize, argCount, - envCount, -1, 0); + envCount, umask, -1, 0); if (status != B_OK) return status; @@ -3288,7 +3291,7 @@ getsid(pid_t process) status_t _user_exec(const char* userPath, const char* const* userFlatArgs, - size_t flatArgsSize, int32 argCount, int32 envCount) + size_t flatArgsSize, int32 argCount, int32 envCount, mode_t umask) { // NOTE: Since this function normally doesn't return, don't use automatic // variables that need destruction in the function scope. @@ -3305,7 +3308,7 @@ _user_exec(const char* userPath, const char* const* userFlatArgs, if (error == B_OK) { error = exec_team(path, flatArgs, _ALIGN(flatArgsSize), argCount, - envCount); + envCount, umask); // this one only returns in case of error } diff --git a/src/system/libroot/libroot_init.c b/src/system/libroot/libroot_init.c index abcbc30e82..bceb3d9faf 100644 --- a/src/system/libroot/libroot_init.c +++ b/src/system/libroot/libroot_init.c @@ -52,6 +52,9 @@ initialize_before(image_id imageID) __gRuntimeLoader->call_atexit_hooks_for_range = _call_atexit_hooks_for_range; + if (__gRuntimeLoader->program_args->umask != (mode_t)-1) + umask(__gRuntimeLoader->program_args->umask); + __init_time(); __init_heap(); __init_env(__gRuntimeLoader->program_args); diff --git a/src/system/libroot/posix/unistd/exec.cpp b/src/system/libroot/posix/unistd/exec.cpp index 158d86aa11..78a5d08e79 100644 --- a/src/system/libroot/posix/unistd/exec.cpp +++ b/src/system/libroot/posix/unistd/exec.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -103,7 +104,8 @@ do_exec(const char *path, char * const args[], char * const environment[], environment, envCount, &flatArgs, &flatArgsSize); if (status == B_OK) { - errno = _kern_exec(path, flatArgs, flatArgsSize, argCount, envCount); + errno = _kern_exec(path, flatArgs, flatArgsSize, argCount, envCount, + __gUmask); // if this call returns, something definitely went wrong free(flatArgs);