Disable mounting cgroups by default (miklos.szeg...@cloudera.com via rkanter)
(cherry picked from commit 351cf87c92872d90f62c476f85ae4d02e485769c) (cherry picked from commit d61d84279f7f22867c23dd95e8bfeb70ea7e0690) (cherry picked from commit f5fd5aa025c904e9a2ff8c5fd932aaed2363a6a0) (cherry picked from commit e20a840174bc2b27fcc0935e0086977bd6fbfcb3) Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/1569cc62 Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/1569cc62 Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/1569cc62 Branch: refs/heads/branch-2.7 Commit: 1569cc62cda563fed1db26c3e47d884abe1c5a45 Parents: af3b37d Author: Andrew Purtell <apurt...@salesforce.com> Authored: Mon Nov 12 12:40:47 2018 -0800 Committer: Konstantin V Shvachko <s...@apache.org> Committed: Wed Nov 28 16:49:40 2018 -0800 ---------------------------------------------------------------------- .../impl/container-executor.c | 83 +++++++++++++++++--- .../impl/container-executor.h | 7 +- .../main/native/container-executor/impl/main.c | 23 ++++-- .../src/site/markdown/NodeManagerCgroups.md | 10 +++ 4 files changed, 103 insertions(+), 20 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hadoop/blob/1569cc62/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c index 9601264..b262ef3 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.c @@ -62,6 +62,8 @@ static const int DEFAULT_MIN_USERID = 1000; static const char* DEFAULT_BANNED_USERS[] = {"mapred", "hdfs", "bin", 0}; +static const int DEFAULT_MOUNT_CGROUP_SUPPORT_ENABLED = 0; + //struct to store the user details struct passwd *user_detail = NULL; @@ -984,6 +986,36 @@ int create_log_dirs(const char *app_id, char * const * log_dirs) { } +static int is_feature_enabled(const char* feature_key, int default_value) { + char *enabled_str = get_value(feature_key, &executor_cfg); + int enabled = default_value; + + if (enabled_str != NULL) { + char *end_ptr = NULL; + enabled = strtol(enabled_str, &end_ptr, 10); + + if ((enabled_str == end_ptr || *end_ptr != '\0') || + (enabled < 0 || enabled > 1)) { + fprintf(LOGFILE, "Illegal value '%s' for '%s' in configuration. " + "Using default value: %d.\n", enabled_str, feature_key, + default_value); + fflush(LOGFILE); + free(enabled_str); + return default_value; + } + + free(enabled_str); + return enabled; + } else { + return default_value; + } +} + +int is_mount_cgroups_support_enabled() { + return is_feature_enabled(MOUNT_CGROUP_SUPPORT_ENABLED_KEY, + DEFAULT_MOUNT_CGROUP_SUPPORT_ENABLED); +} + /** * Function to prepare the application directories for the container. */ @@ -1466,20 +1498,25 @@ void chown_dir_contents(const char *dir_path, uid_t uid, gid_t gid) { DIR *dp; struct dirent *ep; - char *path_tmp = malloc(strlen(dir_path) + NAME_MAX + 2); + size_t len = strlen(dir_path) + NAME_MAX + 2; + char *path_tmp = malloc(len); if (path_tmp == NULL) { return; } - char *buf = stpncpy(path_tmp, dir_path, strlen(dir_path)); - *buf++ = '/'; - dp = opendir(dir_path); if (dp != NULL) { - while (ep = readdir(dp)) { - stpncpy(buf, ep->d_name, strlen(ep->d_name)); - buf[strlen(ep->d_name)] = '\0'; - change_owner(path_tmp, uid, gid); + while ((ep = readdir(dp)) != NULL) { + if (strcmp(ep->d_name, ".") != 0 && + strcmp(ep->d_name, "..") != 0 && + strstr(ep->d_name, "..") == NULL) { + int result = snprintf(path_tmp, len, "%s/%s", dir_path, ep->d_name); + if (result > 0 && result < len) { + change_owner(path_tmp, uid, gid); + } else { + fprintf(LOGFILE, "Ignored %s/%s due to length", dir_path, ep->d_name); + } + } } closedir(dp); } @@ -1502,13 +1539,29 @@ int mount_cgroup(const char *pair, const char *hierarchy) { char *mount_path = malloc(strlen(pair)); char hier_path[EXECUTOR_PATH_MAX]; int result = 0; + size_t len = strlen(pair); - if (get_kv_key(pair, controller, strlen(pair)) < 0 || - get_kv_value(pair, mount_path, strlen(pair)) < 0) { + if (controller == NULL || mount_path == NULL) { + fprintf(LOGFILE, "Failed to mount cgroup controller; not enough memory\n"); + result = OUT_OF_MEMORY; + goto cleanup; + } + if (hierarchy == NULL || strstr(hierarchy, "..") != NULL) { + fprintf(LOGFILE, "Unsupported cgroup hierarhy path detected.\n"); + result = INVALID_COMMAND_PROVIDED; + goto cleanup; + } + if (get_kv_key(pair, controller, len) < 0 || + get_kv_value(pair, mount_path, len) < 0) { fprintf(LOGFILE, "Failed to mount cgroup controller; invalid option: %s\n", pair); result = -1; } else { + if (strstr(mount_path, "..") != NULL) { + fprintf(LOGFILE, "Unsupported cgroup mount path detected.\n"); + result = INVALID_COMMAND_PROVIDED; + goto cleanup; + } if (mount("none", mount_path, "cgroup", 0, controller) == 0) { char *buf = stpncpy(hier_path, mount_path, strlen(mount_path)); *buf++ = '/'; @@ -1516,13 +1569,20 @@ int mount_cgroup(const char *pair, const char *hierarchy) { // create hierarchy as 0750 and chown to Hadoop NM user const mode_t perms = S_IRWXU | S_IRGRP | S_IXGRP; + struct stat sb; + if (stat(hier_path, &sb) == 0 && + (sb.st_uid != nm_uid || sb.st_gid != nm_gid)) { + fprintf(LOGFILE, "cgroup hierarchy %s already owned by another user %d\n", hier_path, sb.st_uid); + result = INVALID_COMMAND_PROVIDED; + goto cleanup; + } if (mkdirs(hier_path, perms) == 0) { change_owner(hier_path, nm_uid, nm_gid); chown_dir_contents(hier_path, nm_uid, nm_gid); } } else { fprintf(LOGFILE, "Failed to mount cgroup controller %s at %s - %s\n", - controller, mount_path, strerror(errno)); + controller, mount_path, strerror(errno)); // if controller is already mounted, don't stop trying to mount others if (errno != EBUSY) { result = -1; @@ -1530,6 +1590,7 @@ int mount_cgroup(const char *pair, const char *hierarchy) { } } +cleanup: free(controller); free(mount_path); http://git-wip-us.apache.org/repos/asf/hadoop/blob/1569cc62/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.h ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.h b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.h index d80679e..644233f 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.h +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/container-executor.h @@ -54,7 +54,8 @@ enum errorcodes { INVALID_CONFIG_FILE = 24, SETSID_OPER_FAILED = 25, WRITE_PIDFILE_FAILED = 26, - WRITE_CGROUP_FAILED = 27 + WRITE_CGROUP_FAILED = 27, + FEATURE_DISABLED = 32 }; #define NM_GROUP_KEY "yarn.nodemanager.linux-container-executor.group" @@ -66,6 +67,7 @@ enum errorcodes { #define MIN_USERID_KEY "min.user.id" #define BANNED_USERS_KEY "banned.users" #define ALLOWED_SYSTEM_USERS_KEY "allowed.system.users" +#define MOUNT_CGROUP_SUPPORT_ENABLED_KEY "feature.mount-cgroup.enabled" #define TMP_DIR "tmp" extern struct passwd *user_detail; @@ -225,3 +227,6 @@ int check_dir(char* npath, mode_t st_mode, mode_t desired, int create_validate_dir(char* npath, mode_t perm, char* path, int finalComponent); + +/** Check if cgroup mount support is enabled in configuration. */ +int is_mount_cgroups_support_enabled(); http://git-wip-us.apache.org/repos/asf/hadoop/blob/1569cc62/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/main.c ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/main.c b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/main.c index bfcd851..17852cd 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/main.c +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/main/native/container-executor/impl/main.c @@ -76,6 +76,10 @@ static void flush_and_close_log_files() { } } +static void display_feature_disabled_message(const char* name) { + fprintf(ERRORFILE, "Feature disabled: %s\n", name); +} + int main(int argc, char **argv) { int invalid_args = 0; int do_check_setup = 0; @@ -195,15 +199,18 @@ int main(int argc, char **argv) { } if (do_mount_cgroups) { - optind++; - char *hierarchy = argv[optind++]; - int result = 0; - - while (optind < argc && result == 0) { - result = mount_cgroup(argv[optind++], hierarchy); + if (is_mount_cgroups_support_enabled()) { + optind++; + char *hierarchy = argv[optind++]; + int result = 0; + while (optind < argc && result == 0) { + result = mount_cgroup(argv[optind++], hierarchy); + } + return result; + } else { + display_feature_disabled_message("mount cgroup"); + return FEATURE_DISABLED; } - - return result; } //checks done for user name http://git-wip-us.apache.org/repos/asf/hadoop/blob/1569cc62/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/NodeManagerCgroups.md ---------------------------------------------------------------------- diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/NodeManagerCgroups.md b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/NodeManagerCgroups.md index 79a428d..5014a95 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/NodeManagerCgroups.md +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-site/src/site/markdown/NodeManagerCgroups.md @@ -43,6 +43,16 @@ The following settings are related to limiting resource usage of YARN containers | `yarn.nodemanager.resource.percentage-physical-cpu-limit` | This setting lets you limit the cpu usage of all YARN containers. It sets a hard upper limit on the cumulative CPU usage of the containers. For example, if set to 60, the combined CPU usage of all YARN containers will not exceed 60%. | | `yarn.nodemanager.linux-container-executor.cgroups.strict-resource-usage` | CGroups allows cpu usage limits to be hard or soft. When this setting is true, containers cannot use more CPU usage than allocated even if spare CPU is available. This ensures that containers can only use CPU that they were allocated. When set to false, containers can use spare CPU if available. It should be noted that irrespective of whether set to true or false, at no time can the combined CPU usage of all containers exceed the value specified in "yarn.nodemanager.resource.percentage-physical-cpu-limit". | +CGroups mount options +--------------------- + +YARN uses CGroups through a directory structure mounted into the file system by the kernel. There are three options to attach to CGroups. + +| Option | Description | +|:---- |:---- | +| Discover CGroups mounted already | This should be used on newer systems like RHEL7 or Ubuntu16 or if the administrator mounts CGroups before YARN starts. Set `yarn.nodemanager.linux-container-executor.cgroups.mount` to false and leave other settings set to their defaults. YARN will locate the mount points in `/proc/mounts`. Common locations include `/sys/fs/cgroup` and `/cgroup`. The default location can vary depending on the Linux distribution in use.| +| CGroups mounted by YARN | IMPORTANT: This option is deprecated due to security reasons with the `container-executor.cfg` option `feature.mount-cgroup.enabled=0` by default. Please mount cgroups before launching YARN.| + CGroups and security -------------------- --------------------------------------------------------------------- To unsubscribe, e-mail: common-commits-unsubscr...@hadoop.apache.org For additional commands, e-mail: common-commits-h...@hadoop.apache.org