X-Git-Url: http://mj.ucw.cz/gitweb/?a=blobdiff_plain;f=isolate%2Fisolate.c;h=7902813a29ad6d962ae9159a56205674e47f4342;hb=700824d3e9bce9219819e4e5096ab94da301d44b;hp=460f1b06ec4b52b44bd520bdfdb1952d2a5315db;hpb=1994e363b0ab97560d78e7fb6bf6cbc1332a448c;p=eval.git diff --git a/isolate/isolate.c b/isolate/isolate.c index 460f1b0..7902813 100644 --- a/isolate/isolate.c +++ b/isolate/isolate.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -63,7 +64,7 @@ static uid_t orig_uid; static gid_t orig_gid; static int partial_line; -static char cleanup_cmd[256]; +static int cleanup_ownership; static struct timeval start_time; static int ticks_per_sec; @@ -79,6 +80,8 @@ static void cg_stats(void); static int get_wall_time_ms(void); static int get_run_time_ms(struct rusage *rus); +static void chowntree(char *path, uid_t uid, gid_t gid); + /*** Meta-files ***/ static FILE *metafile; @@ -132,16 +135,6 @@ final_stats(struct rusage *rus) /*** Messages and exits ***/ -static void -xsystem(const char *cmd) -{ - int ret = system(cmd); - if (ret < 0) - die("system(\"%s\"): %m", cmd); - if (!WIFEXITED(ret) || WEXITSTATUS(ret)) - die("system(\"%s\"): Exited with status %d", cmd, ret); -} - static void NONRET box_exit(int rc) { @@ -162,8 +155,10 @@ box_exit(int rc) final_stats(&rus); } - if (rc < 2 && cleanup_cmd[0]) - xsystem(cleanup_cmd); + if (rc < 2 && cleanup_ownership) + { + chowntree("box", orig_uid, orig_gid); + } meta_close(); exit(rc); @@ -265,6 +260,47 @@ static int dir_exists(char *path) return (stat(path, &st) >= 0 && S_ISDIR(st.st_mode)); } +static int rmtree_helper(const char *fpath, const struct stat *sb, + int typeflag, struct FTW *ftwbuf) +{ + if (S_ISDIR(sb->st_mode)) + { + if (rmdir(fpath) < 0) + die("Cannot rmdir %s: %m", fpath); + } + else + { + if (unlink(fpath) < 0) + die("Cannot unlink %s: %m", fpath); + } + return FTW_CONTINUE; +} + +static void +rmtree(char *path) +{ + nftw(path, rmtree_helper, 32, FTW_MOUNT | FTW_PHYS | FTW_DEPTH); +} + +static uid_t chown_uid; +static gid_t chown_gid; +static int chowntree_helper(const char *fpath, const struct stat *sb, + int typeflag, struct FTW *ftwbuf) +{ + if (lchown(fpath, chown_uid, chown_gid) < 0) + die("Cannot chown %s: %m", fpath); + else + return FTW_CONTINUE; +} + +static void +chowntree(char *path, uid_t uid, gid_t gid) +{ + chown_uid = uid; + chown_gid = gid; + nftw(path, chowntree_helper, 32, FTW_MOUNT | FTW_PHYS); +} + /*** Environment rules ***/ struct env_rule { @@ -647,7 +683,11 @@ cg_read(cg_controller controller, const char *attr, char *buf) int n = read(fd, buf, CG_BUFSIZE); if (n < 0) - die("Cannot read %s: %m", path); + { + if (maybe) + return 0; + die("Cannot read %s: %m", path); + } if (n >= CG_BUFSIZE - 1) die("Attribute %s too long", path); if (n > 0 && buf[n-1] == '\n') @@ -773,7 +813,7 @@ cg_enter(void) if (cg_memory_limit) { cg_write(CG_MEMORY, "memory.limit_in_bytes", "%lld\n", (long long) cg_memory_limit << 10); - cg_write(CG_MEMORY, "memory.memsw.limit_in_bytes", "%lld\n", (long long) cg_memory_limit << 10); + cg_write(CG_MEMORY, "?memory.memsw.limit_in_bytes", "%lld\n", (long long) cg_memory_limit << 10); } if (cg_timing) @@ -1238,7 +1278,7 @@ static void init(void) { msg("Preparing sandbox directory\n"); - xsystem("rm -rf box"); + rmtree("box"); if (mkdir("box", 0700) < 0) die("Cannot create box: %m"); if (chown("box", orig_uid, orig_gid) < 0) @@ -1257,9 +1297,7 @@ cleanup(void) die("Box directory not found, there isn't anything to clean up"); msg("Deleting sandbox directory\n"); - xsystem("rm -rf *"); - if (rmdir(box_dir) < 0) - die("Cannot remove %s: %m", box_dir); + rmtree(box_dir); cg_remove(); } @@ -1269,10 +1307,8 @@ run(char **argv) if (!dir_exists("box")) die("Box directory not found, did you run `isolate --init'?"); - char cmd[256]; - snprintf(cmd, sizeof(cmd), "chown -R %d.%d box", box_uid, box_gid); - xsystem(cmd); - snprintf(cleanup_cmd, sizeof(cleanup_cmd), "chown -R %d.%d box", orig_uid, orig_gid); + chowntree("box", box_uid, box_gid); + cleanup_ownership = 1; if (pipe(error_pipes) < 0) die("pipe: %m");