YARN-2701. Addendum patch. Potential race condition in startLocalizer when using LinuxContainerExecutor. Contributed by Xuan Gong

This commit is contained in:
Xuan 2014-10-31 14:36:25 -07:00
parent 1b4be91866
commit 86ff28dea0
2 changed files with 78 additions and 23 deletions

View File

@ -451,36 +451,85 @@ char *get_tmp_directory(const char *work_dir) {
* with the desired permissions. * with the desired permissions.
*/ */
int mkdirs(const char* path, mode_t perm) { int mkdirs(const char* path, mode_t perm) {
char *buffer = strdup(path); struct stat sb;
char *token; char * npath;
int cwd = open("/", O_RDONLY); char * p;
if (cwd == -1) { if (stat(path, &sb) == 0) {
fprintf(LOGFILE, "Can't open / in %s - %s\n", path, strerror(errno)); return check_dir(path, sb.st_mode, perm, 1);
free(buffer); }
npath = strdup(path);
if (npath == NULL) {
fprintf(LOGFILE, "Not enough memory to copy path string");
return -1; return -1;
} }
for(token = strtok(buffer, "/"); token != NULL; token = strtok(NULL, "/")) { /* Skip leading slashes. */
if (mkdirat(cwd, token, perm) != 0) { p = npath;
if (errno != EEXIST) { while (*p == '/') {
fprintf(LOGFILE, "Can't create directory %s in %s - %s\n", p++;
token, path, strerror(errno)); }
close(cwd);
free(buffer); while (NULL != (p = strchr(p, '/'))) {
*p = '\0';
if (create_validate_dir(npath, perm, path, 0) == -1) {
free(npath);
return -1; return -1;
} }
*p++ = '/'; /* restore slash */
while (*p == '/')
p++;
} }
int new_dir = openat(cwd, token, O_RDONLY);
close(cwd); /* Create the final directory component. */
cwd = new_dir; if (create_validate_dir(npath, perm, path, 1) == -1) {
if (cwd == -1) { free(npath);
fprintf(LOGFILE, "Can't open %s in %s - %s\n", token, path, return -1;
}
free(npath);
return 0;
}
/*
* Create the parent directory if they do not exist. Or check the permission if
* the race condition happens.
* Give 0 or 1 to represent whether this is the final component. If it is, we
* need to check the permission.
*/
int create_validate_dir(char* npath, mode_t perm, char* path, int finalComponent) {
struct stat sb;
if (stat(npath, &sb) != 0) {
if (mkdir(npath, perm) != 0) {
if (errno != EEXIST || stat(npath, &sb) != 0) {
fprintf(LOGFILE, "Can't create directory %s - %s\n", npath,
strerror(errno)); strerror(errno));
free(buffer); return -1;
}
// The directory npath should exist.
if (check_dir(npath, sb.st_mode, perm, finalComponent) == -1) {
return -1;
}
}
} else {
if (check_dir(npath, sb.st_mode, perm, finalComponent) == -1) {
return -1;
}
}
return 0;
}
// check whether the given path is a directory
// also check the access permissions whether it is the same as desired permissions
int check_dir(char* npath, mode_t st_mode, mode_t desired, int finalComponent) {
if (!S_ISDIR(st_mode)) {
fprintf(LOGFILE, "Path %s is file not dir\n", npath);
return -1;
} else if (finalComponent == 1) {
int filePermInt = st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
int desiredInt = desired & (S_IRWXU | S_IRWXG | S_IRWXO);
if (filePermInt != desiredInt) {
fprintf(LOGFILE, "Path %s does not have desired permission.\n", npath);
return -1; return -1;
} }
} }
free(buffer);
close(cwd);
return 0; return 0;
} }

View File

@ -203,3 +203,9 @@ int create_directory_for_user(const char* path);
int change_user(uid_t user, gid_t group); int change_user(uid_t user, gid_t group);
int mount_cgroup(const char *pair, const char *hierarchy); int mount_cgroup(const char *pair, const char *hierarchy);
int check_dir(char* npath, mode_t st_mode, mode_t desired,
int finalComponent);
int create_validate_dir(char* npath, mode_t perm, char* path,
int finalComponent);