diff --git a/storm-core/src/native/worker-launcher/impl/main.c b/storm-core/src/native/worker-launcher/impl/main.c index b3497a6b31e..28e841e8d23 100644 --- a/storm-core/src/native/worker-launcher/impl/main.c +++ b/storm-core/src/native/worker-launcher/impl/main.c @@ -218,11 +218,15 @@ int main(int argc, char **argv) { exit_code = INVALID_ARGUMENT_NUMBER; } else { working_dir = argv[optind++]; + // Read and parse the docker command file before setup_dir_permissions + // changes the ownership of the worker directory (which contains the + // command file) below. + char *docker_command = parse_docker_command_file(argv[optind]); exit_code = setup_dir_permissions(working_dir, 1, TRUE); if (exit_code == 0) { exit_code = setup_worker_tmp_permissions(working_dir); if (exit_code == 0) { - exit_code = run_docker_cmd(working_dir, argv[optind]); + exit_code = exec_docker_cmd(docker_command); } } } diff --git a/storm-core/src/native/worker-launcher/impl/worker-launcher.c b/storm-core/src/native/worker-launcher/impl/worker-launcher.c index 43b736ade55..3d1910105c5 100644 --- a/storm-core/src/native/worker-launcher/impl/worker-launcher.c +++ b/storm-core/src/native/worker-launcher/impl/worker-launcher.c @@ -1171,7 +1171,31 @@ char *parse_docker_command_file(const char *command_file) { exit(ERROR_CHANGING_USER); } - stream = fopen(command_file, "r"); + int fd = open(command_file, O_RDONLY | O_NOFOLLOW); + if (fd == -1) { + fprintf(ERRORFILE, "ERROR: Cannot open file %s - %s in parse_docker_command", + command_file, strerror(errno)); + fflush(ERRORFILE); + exit(ERROR_OPENING_FILE); + } + // Require the command file to be a regular file owned by the + // worker-launcher user (or root) and not writable by others. + struct stat file_stat; + if (fstat(fd, &file_stat) != 0) { + fprintf(ERRORFILE, "ERROR: Cannot stat file %s - %s in parse_docker_command", + command_file, strerror(errno)); + fflush(ERRORFILE); + exit(ERROR_OPENING_FILE); + } + if (!S_ISREG(file_stat.st_mode) + || (file_stat.st_uid != launcher_uid && file_stat.st_uid != 0) + || (file_stat.st_mode & S_IWOTH) != 0) { + fprintf(ERRORFILE, "ERROR: Refusing to use command file %s that is not a regular file" + " owned by the worker-launcher user and unwritable by others\n", command_file); + fflush(ERRORFILE); + exit(ERROR_OPENING_FILE); + } + stream = fdopen(fd, "r"); if (stream == NULL) { fprintf(ERRORFILE, "ERROR: Cannot open file %s - %s in parse_docker_command", command_file, strerror(errno)); @@ -1198,8 +1222,7 @@ char *parse_docker_command_file(const char *command_file) { return ret; } -int run_docker_cmd(const char *working_dir, const char *command_file) { - char *docker_command = parse_docker_command_file(command_file); +int exec_docker_cmd(char *docker_command) { char *docker_binary = get_docker_binary(); size_t command_size = MIN(sysconf(_SC_ARG_MAX), 128 * 1024); @@ -1228,6 +1251,10 @@ int run_docker_cmd(const char *working_dir, const char *command_file) { return -1; } +int run_docker_cmd(const char *working_dir, const char *command_file) { + return exec_docker_cmd(parse_docker_command_file(command_file)); +} + //functions below are nsenter related. //Used for running profiling inside docker container through nsenter. diff --git a/storm-core/src/native/worker-launcher/impl/worker-launcher.h b/storm-core/src/native/worker-launcher/impl/worker-launcher.h index 8dd7f8cc7fa..da105f7ae43 100644 --- a/storm-core/src/native/worker-launcher/impl/worker-launcher.h +++ b/storm-core/src/native/worker-launcher/impl/worker-launcher.h @@ -185,6 +185,18 @@ int change_effective_user(uid_t user, gid_t group); */ char *get_docker_binary(); +/** + * Read and parse a docker command file. The file must be a regular file + * owned by the worker-launcher user (or root) and not writable by others. + * Exits the process on any error. + */ +char *parse_docker_command_file(const char *command_file); + +/** + * Exec the docker binary with an already-parsed docker command. + */ +int exec_docker_cmd(char *docker_command); + /** * Run a docker command passing the command file as an argument */