firejail/firejail-CVE-2017-5180-fix2.patch

269 lines
6.9 KiB
Diff
Raw Normal View History

From e74fdab5d2125ce8f058c1630ce7cce19cbdac16 Mon Sep 17 00:00:00 2001
From: netblue30 <netblue30@yahoo.com>
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 <sys/types.h>
#include <sys/stat.h>
#include <sys/mount.h>
+#include <sys/wait.h>
#include <dirent.h>
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;
}