From e74fdab5d2125ce8f058c1630ce7cce19cbdac16 Mon Sep 17 00:00:00 2001 From: netblue30 Date: Wed, 4 Jan 2017 18:13:45 -0500 Subject: [PATCH] security fixes --- src/firejail/fs_home.c | 118 +++++++++++++++++++++++++++++++++++++--------- src/firejail/pulseaudio.c | 47 +++++++++++++----- src/firejail/util.c | 4 - 3 files changed, 134 insertions(+), 35 deletions(-) --- a/src/firejail/fs_home.c +++ b/src/firejail/fs_home.c @@ -108,6 +108,14 @@ static int store_xauthority(void) { char *src; char *dest = RUN_XAUTHORITY_FILE; + // create an empty file + FILE *fp = fopen(dest, "w"); + if (fp) { + fprintf(fp, "\n"); + SET_PERMS_STREAM(fp, getuid(), getgid(), 0600); + fclose(fp); + } + if (asprintf(&src, "%s/.Xauthority", cfg.homedir) == -1) errExit("asprintf"); @@ -117,12 +125,28 @@ static int store_xauthority(void) { fprintf(stderr, "Warning: invalid .Xauthority file\n"); return 0; } - - int rv = copy_file(src, dest, -1, -1, 0600); - if (rv) { - fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n"); - return 0; + + pid_t child = fork(); + if (child < 0) + errExit("fork"); + if (child == 0) { + // drop privileges + drop_privs(0); + + // copy, set permissions and ownership + int rv = copy_file(src, dest, getuid(), getgid(), 0600); + if (rv) + fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n"); + else { + fs_logger2("clone", dest); + } +#ifdef HAVE_GCOV + __gcov_flush(); +#endif + _exit(0); } + // wait for the child to finish + waitpid(child, NULL, 0); return 1; // file copied } @@ -135,6 +159,14 @@ static int store_asoundrc(void) { char *src; char *dest = RUN_ASOUNDRC_FILE; + // create an empty file + FILE *fp = fopen(dest, "w"); + if (fp) { + fprintf(fp, "\n"); + SET_PERMS_STREAM(fp, getuid(), getgid(), 0644); + fclose(fp); + } + if (asprintf(&src, "%s/.asoundrc", cfg.homedir) == -1) errExit("asprintf"); @@ -154,11 +186,27 @@ static int store_asoundrc(void) { free(rp); } - int rv = copy_file(src, dest, -1, -1, -0644); - if (rv) { - fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n"); - return 0; + pid_t child = fork(); + if (child < 0) + errExit("fork"); + if (child == 0) { + // drop privileges + drop_privs(0); + + // copy, set permissions and ownership + int rv = copy_file(src, dest, getuid(), getgid(), 0644); + if (rv) + fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n"); + else { + fs_logger2("clone", dest); + } +#ifdef HAVE_GCOV + __gcov_flush(); +#endif + _exit(0); } + // wait for the child to finish + waitpid(child, NULL, 0); return 1; // file copied } @@ -178,13 +226,27 @@ static void copy_xauthority(void) { exit(1); } - // copy, set permissions and ownership - int rv = copy_file(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR); - if (rv) - fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n"); - else { - fs_logger2("clone", dest); + pid_t child = fork(); + if (child < 0) + errExit("fork"); + if (child == 0) { + // drop privileges + drop_privs(0); + + // copy, set permissions and ownership + int rv = copy_file(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR); + if (rv) + fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n"); + else { + fs_logger2("clone", dest); + } +#ifdef HAVE_GCOV + __gcov_flush(); +#endif + _exit(0); } + // wait for the child to finish + waitpid(child, NULL, 0); // delete the temporary file unlink(src); @@ -203,13 +265,27 @@ static void copy_asoundrc(void) { exit(1); } - // copy, set permissions and ownership - int rv = copy_file(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR); - if (rv) - fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n"); - else { - fs_logger2("clone", dest); + pid_t child = fork(); + if (child < 0) + errExit("fork"); + if (child == 0) { + // drop privileges + drop_privs(0); + + // copy, set permissions and ownership + int rv = copy_file(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR); + if (rv) + fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n"); + else { + fs_logger2("clone", dest); + } +#ifdef HAVE_GCOV + __gcov_flush(); +#endif + _exit(0); } + // wait for the child to finish + waitpid(child, NULL, 0); // delete the temporary file unlink(src); --- a/src/firejail/pulseaudio.c +++ b/src/firejail/pulseaudio.c @@ -21,6 +21,7 @@ #include #include #include +#include #include static void disable_file(const char *path, const char *file) { @@ -130,13 +131,24 @@ void pulseaudio_init(void) { if (asprintf(&dir1, "%s/.config", cfg.homedir) == -1) errExit("asprintf"); if (stat(dir1, &s) == -1) { - int rv = mkdir(dir1, 0755); - if (rv == 0) { - rv = chown(dir1, getuid(), getgid()); - (void) rv; - rv = chmod(dir1, 0755); - (void) rv; + pid_t child = fork(); + if (child < 0) + errExit("fork"); + if (child == 0) { + // drop privileges + drop_privs(0); + + int rv = mkdir(dir1, 0755); + if (rv == 0) { + rv = chown(dir1, getuid(), getgid()); + (void) rv; + rv = chmod(dir1, 0755); + (void) rv; + } + _exit(0); } + // wait for the child to finish + waitpid(child, NULL, 0); } else { // make sure the directory is owned by the user @@ -150,13 +162,24 @@ void pulseaudio_init(void) { if (asprintf(&dir1, "%s/.config/pulse", cfg.homedir) == -1) errExit("asprintf"); if (stat(dir1, &s) == -1) { - int rv = mkdir(dir1, 0700); - if (rv == 0) { - rv = chown(dir1, getuid(), getgid()); - (void) rv; - rv = chmod(dir1, 0700); - (void) rv; + pid_t child = fork(); + if (child < 0) + errExit("fork"); + if (child == 0) { + // drop privileges + drop_privs(0); + + int rv = mkdir(dir1, 0700); + if (rv == 0) { + rv = chown(dir1, getuid(), getgid()); + (void) rv; + rv = chmod(dir1, 0700); + (void) rv; + } + _exit(0); } + // wait for the child to finish + waitpid(child, NULL, 0); } else { // make sure the directory is owned by the user --- a/src/firejail/util.c +++ b/src/firejail/util.c @@ -179,14 +179,14 @@ int copy_file(const char *srcname, const // open source int src = open(srcname, O_RDONLY); if (src < 0) { - fprintf(stderr, "Warning: cannot open %s, file not copied\n", srcname); + fprintf(stderr, "Warning: cannot open source file %s, file not copied\n", srcname); return -1; } // open destination int dst = open(destname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); if (dst < 0) { - fprintf(stderr, "Warning: cannot open %s, file not copied\n", destname); + fprintf(stderr, "Warning: cannot open destination file %s, file not copied\n", destname); close(src); return -1; }