YARN-7590. Improve container-executor validation check. Contributed by Eric Yang.
This commit is contained in:
parent
2e0a451a8d
commit
bc285da107
|
@ -517,9 +517,31 @@ char *get_app_directory(const char * nm_root, const char *user,
|
|||
* Get the user directory of a particular user
|
||||
*/
|
||||
char *get_user_directory(const char *nm_root, const char *user) {
|
||||
int result = check_nm_local_dir(nm_uid, nm_root);
|
||||
if (result != 0) {
|
||||
return NULL;
|
||||
}
|
||||
return concatenate(USER_DIR_PATTERN, "user_dir_path", 2, nm_root, user);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check node manager local dir permission.
|
||||
*/
|
||||
int check_nm_local_dir(uid_t caller_uid, const char *nm_root) {
|
||||
struct stat info;
|
||||
errno = 0;
|
||||
int err = stat(nm_root, &info);
|
||||
if (err < 0) {
|
||||
fprintf(LOGFILE, "Error checking file stats for %s %d %s.\n", nm_root, err, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
if (caller_uid != info.st_uid) {
|
||||
fprintf(LOGFILE, "Permission mismatch for %s for caller uid: %d, owner uid: %d.\n", nm_root, caller_uid, info.st_uid);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the container directory for the given container_id
|
||||
*/
|
||||
|
@ -666,6 +688,11 @@ static int create_container_directories(const char* user, const char *app_id,
|
|||
for(local_dir_ptr = local_dir; *local_dir_ptr != NULL; ++local_dir_ptr) {
|
||||
char *container_dir = get_container_work_directory(*local_dir_ptr, user, app_id,
|
||||
container_id);
|
||||
int check = check_nm_local_dir(nm_uid, *local_dir_ptr);
|
||||
if (check != 0) {
|
||||
free(container_dir);
|
||||
continue;
|
||||
}
|
||||
if (container_dir == NULL) {
|
||||
return OUT_OF_MEMORY;
|
||||
}
|
||||
|
@ -692,6 +719,14 @@ static int create_container_directories(const char* user, const char *app_id,
|
|||
char* const* log_dir_ptr;
|
||||
for(log_dir_ptr = log_dir; *log_dir_ptr != NULL; ++log_dir_ptr) {
|
||||
char *container_log_dir = get_app_log_directory(*log_dir_ptr, combined_name);
|
||||
int check = check_nm_local_dir(nm_uid, *log_dir_ptr);
|
||||
if (check != 0) {
|
||||
container_log_dir = NULL;
|
||||
}
|
||||
if (strstr(container_log_dir, "..") != 0) {
|
||||
fprintf(LOGFILE, "Unsupported container log directory path detected.\n");
|
||||
container_log_dir = NULL;
|
||||
}
|
||||
if (container_log_dir == NULL) {
|
||||
free(combined_name);
|
||||
return OUT_OF_MEMORY;
|
||||
|
@ -1032,6 +1067,10 @@ int create_log_dirs(const char *app_id, char * const * log_dirs) {
|
|||
char *any_one_app_log_dir = NULL;
|
||||
for(log_root=log_dirs; *log_root != NULL; ++log_root) {
|
||||
char *app_log_dir = get_app_log_directory(*log_root, app_id);
|
||||
int result = check_nm_local_dir(nm_uid, *log_root);
|
||||
if (result != 0) {
|
||||
app_log_dir = NULL;
|
||||
}
|
||||
if (app_log_dir == NULL) {
|
||||
// try the next one
|
||||
} else if (create_directory_for_user(app_log_dir) != 0) {
|
||||
|
@ -2213,4 +2252,4 @@ int traffic_control_read_stats(char *command_file) {
|
|||
*/
|
||||
struct configuration* get_cfg() {
|
||||
return &CFG;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -178,6 +178,11 @@ char *get_user_directory(const char *nm_root, const char *user);
|
|||
char *get_app_directory(const char * nm_root, const char *user,
|
||||
const char *app_id);
|
||||
|
||||
/**
|
||||
* Check node manager local dir permission.
|
||||
*/
|
||||
int check_nm_local_dir(uid_t caller_uid, const char *nm_root);
|
||||
|
||||
char *get_container_work_directory(const char *nm_root, const char *user,
|
||||
const char *app_id, const char *container_id);
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ static char* username = NULL;
|
|||
static char* yarn_username = NULL;
|
||||
static char** local_dirs = NULL;
|
||||
static char** log_dirs = NULL;
|
||||
static uid_t nm_uid = -1;
|
||||
|
||||
/**
|
||||
* Run the command using the effective user id.
|
||||
|
@ -152,8 +153,8 @@ void check_pid_file(const char* pid_file, pid_t mypid) {
|
|||
}
|
||||
|
||||
void test_get_user_directory() {
|
||||
char *user_dir = get_user_directory(TMPDIR, "user");
|
||||
char *expected = TMPDIR "/usercache/user";
|
||||
char *user_dir = get_user_directory(TEST_ROOT, "user");
|
||||
char *expected = TEST_ROOT "/usercache/user";
|
||||
if (strcmp(user_dir, expected) != 0) {
|
||||
printf("test_get_user_directory expected %s got %s\n", expected, user_dir);
|
||||
exit(1);
|
||||
|
@ -161,9 +162,32 @@ void test_get_user_directory() {
|
|||
free(user_dir);
|
||||
}
|
||||
|
||||
void test_check_nm_local_dir() {
|
||||
// check filesystem is same as running user.
|
||||
int expected = 0;
|
||||
char *local_path = TEST_ROOT "target";
|
||||
char *root_path = "/";
|
||||
if (mkdirs(local_path, 0700) != 0) {
|
||||
printf("FAIL: unble to create node manager local directory: %s\n", local_path);
|
||||
exit(1);
|
||||
}
|
||||
int actual = check_nm_local_dir(nm_uid, local_path);
|
||||
if (expected != actual) {
|
||||
printf("test_nm_local_dir expected %d got %d\n", expected, actual);
|
||||
exit(1);
|
||||
}
|
||||
// check filesystem is different from running user.
|
||||
expected = 1;
|
||||
actual = check_nm_local_dir(nm_uid, root_path);
|
||||
if (expected != actual && nm_uid != 0) {
|
||||
printf("test_nm_local_dir expected %d got %d\n", expected, actual);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void test_get_app_directory() {
|
||||
char *expected = TMPDIR "/usercache/user/appcache/app_200906101234_0001";
|
||||
char *app_dir = (char *) get_app_directory(TMPDIR, "user",
|
||||
char *expected = TEST_ROOT "/usercache/user/appcache/app_200906101234_0001";
|
||||
char *app_dir = (char *) get_app_directory(TEST_ROOT, "user",
|
||||
"app_200906101234_0001");
|
||||
if (strcmp(app_dir, expected) != 0) {
|
||||
printf("test_get_app_directory expected %s got %s\n", expected, app_dir);
|
||||
|
@ -173,9 +197,9 @@ void test_get_app_directory() {
|
|||
}
|
||||
|
||||
void test_get_container_directory() {
|
||||
char *container_dir = get_container_work_directory(TMPDIR, "owen", "app_1",
|
||||
char *container_dir = get_container_work_directory(TEST_ROOT, "owen", "app_1",
|
||||
"container_1");
|
||||
char *expected = TMPDIR"/usercache/owen/appcache/app_1/container_1";
|
||||
char *expected = TEST_ROOT "/usercache/owen/appcache/app_1/container_1";
|
||||
if (strcmp(container_dir, expected) != 0) {
|
||||
printf("Fail get_container_work_directory got %s expected %s\n",
|
||||
container_dir, expected);
|
||||
|
@ -185,9 +209,9 @@ void test_get_container_directory() {
|
|||
}
|
||||
|
||||
void test_get_container_launcher_file() {
|
||||
char *expected_file = (TMPDIR"/usercache/user/appcache/app_200906101234_0001"
|
||||
char *expected_file = (TEST_ROOT "/usercache/user/appcache/app_200906101234_0001"
|
||||
"/launch_container.sh");
|
||||
char *app_dir = get_app_directory(TMPDIR, "user",
|
||||
char *app_dir = get_app_directory(TEST_ROOT, "user",
|
||||
"app_200906101234_0001");
|
||||
char *container_file = get_container_launcher_file(app_dir);
|
||||
if (strcmp(container_file, expected_file) != 0) {
|
||||
|
@ -1182,6 +1206,8 @@ int main(int argc, char **argv) {
|
|||
LOGFILE = stdout;
|
||||
ERRORFILE = stderr;
|
||||
|
||||
nm_uid = getuid();
|
||||
|
||||
printf("Attempting to clean up from any previous runs\n");
|
||||
// clean up any junk from previous run
|
||||
if (system("chmod -R u=rwx " TEST_ROOT "; rm -fr " TEST_ROOT)) {
|
||||
|
@ -1232,6 +1258,9 @@ int main(int argc, char **argv) {
|
|||
printf("\nTesting get_user_directory()\n");
|
||||
test_get_user_directory();
|
||||
|
||||
printf("\nTesting check_nm_local_dir()\n");
|
||||
test_check_nm_local_dir();
|
||||
|
||||
printf("\nTesting get_app_directory()\n");
|
||||
test_get_app_directory();
|
||||
|
||||
|
|
Loading…
Reference in New Issue