From 0021c29f7f25a5020091182c690407a753f933e4 Mon Sep 17 00:00:00 2001 From: netblue30 Date: Mon, 19 Oct 2015 14:46:24 -0400 Subject: fixed join/shutdown problem, moving browsers and mail clients to a --shell=none default in profile files --- etc/chromium.profile | 2 ++ etc/firefox.profile | 2 ++ etc/midori.profile | 1 + etc/opera.profile | 1 + etc/thunderbird.profile | 1 + src/firejail/caps.c | 11 +++-------- src/firejail/firejail.h | 1 + src/firejail/join.c | 9 ++------- src/firejail/seccomp.c | 11 +++-------- src/firejail/shutdown.c | 9 ++------- src/firejail/util.c | 43 +++++++++++++++++++++++++++++++++++++++++++ src/lib/pid.c | 4 ++-- todo | 13 +++++++++++++ 13 files changed, 76 insertions(+), 32 deletions(-) diff --git a/etc/chromium.profile b/etc/chromium.profile index 6c3a5f2f8..81a4d7861 100644 --- a/etc/chromium.profile +++ b/etc/chromium.profile @@ -5,5 +5,7 @@ include /etc/firejail/disable-secret.inc include /etc/firejail/disable-common.inc include /etc/firejail/disable-history.inc netfilter +shell none + diff --git a/etc/firefox.profile b/etc/firefox.profile index fae7d7ad4..ec95324c8 100644 --- a/etc/firefox.profile +++ b/etc/firefox.profile @@ -8,5 +8,7 @@ caps.drop all seccomp netfilter noroot +shell none + diff --git a/etc/midori.profile b/etc/midori.profile index 7ce9b7151..a1089d2d7 100644 --- a/etc/midori.profile +++ b/etc/midori.profile @@ -7,4 +7,5 @@ include /etc/firejail/disable-history.inc caps.drop all seccomp netfilter +shell none diff --git a/etc/opera.profile b/etc/opera.profile index d55c0aaa3..c20e6b614 100644 --- a/etc/opera.profile +++ b/etc/opera.profile @@ -6,5 +6,6 @@ include /etc/firejail/disable-common.inc include /etc/firejail/disable-history.inc netfilter noroot +shell none diff --git a/etc/thunderbird.profile b/etc/thunderbird.profile index 9305d06b0..e2f1f338b 100644 --- a/etc/thunderbird.profile +++ b/etc/thunderbird.profile @@ -20,4 +20,5 @@ caps.drop all seccomp netfilter noroot +shell none diff --git a/src/firejail/caps.c b/src/firejail/caps.c index 12d0eec57..7c5f9d2d9 100644 --- a/src/firejail/caps.c +++ b/src/firejail/caps.c @@ -427,14 +427,9 @@ void caps_print_filter(pid_t pid) { // check privileges for non-root users uid_t uid = getuid(); if (uid != 0) { - struct stat s; - char *dir; - if (asprintf(&dir, "/proc/%u/ns", pid) == -1) - errExit("asprintf"); - if (stat(dir, &s) < 0) - errExit("stat"); - if (s.st_uid != uid) { - printf("Error: permission denied.\n"); + uid_t sandbox_uid = pid_get_uid(pid); + if (uid != sandbox_uid) { + fprintf(stderr, "Error: permission denied.\n"); exit(1); } } diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 6a88d7e17..2e82dabc9 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -295,6 +295,7 @@ void wait_for_other(int fd); void notify_other(int fd); char *expand_home(const char *path, const char* homedir); const char *gnu_basename(const char *path); +uid_t pid_get_uid(pid_t pid); // fs_var.c void fs_var_log(void); // mounting /var/log diff --git a/src/firejail/join.c b/src/firejail/join.c index fcc5e05d1..acd17366a 100644 --- a/src/firejail/join.c +++ b/src/firejail/join.c @@ -215,13 +215,8 @@ void join(pid_t pid, const char *homedir, int argc, char **argv, int index) { // check privileges for non-root users uid_t uid = getuid(); if (uid != 0) { - struct stat s; - char *dir; - if (asprintf(&dir, "/proc/%u/ns", pid) == -1) - errExit("asprintf"); - if (stat(dir, &s) < 0) - errExit("stat"); - if (s.st_uid != uid) { + uid_t sandbox_uid = pid_get_uid(pid); + if (uid != sandbox_uid) { fprintf(stderr, "Error: permission is denied to join a sandbox created by a different user.\n"); exit(1); } diff --git a/src/firejail/seccomp.c b/src/firejail/seccomp.c index 7c0bd322d..5d6bc1de9 100644 --- a/src/firejail/seccomp.c +++ b/src/firejail/seccomp.c @@ -783,14 +783,9 @@ void seccomp_print_filter(pid_t pid) { // check privileges for non-root users uid_t uid = getuid(); if (uid != 0) { - struct stat s; - char *dir; - if (asprintf(&dir, "/proc/%u/ns", pid) == -1) - errExit("asprintf"); - if (stat(dir, &s) < 0) - errExit("stat"); - if (s.st_uid != uid) { - printf("Error: permission denied.\n"); + uid_t sandbox_uid = pid_get_uid(pid); + if (uid != sandbox_uid) { + fprintf(stderr, "Error: permission denied.\n"); exit(1); } } diff --git a/src/firejail/shutdown.c b/src/firejail/shutdown.c index f37869bd0..649f86800 100644 --- a/src/firejail/shutdown.c +++ b/src/firejail/shutdown.c @@ -60,13 +60,8 @@ void shut(pid_t pid) { // check privileges for non-root users uid_t uid = getuid(); if (uid != 0) { - struct stat s; - char *dir; - if (asprintf(&dir, "/proc/%u/ns", pid) == -1) - errExit("asprintf"); - if (stat(dir, &s) < 0) - errExit("stat"); - if (s.st_uid != uid) { + uid_t sandbox_uid = pid_get_uid(pid); + if (uid != sandbox_uid) { fprintf(stderr, "Error: permission is denied to shutdown a sandbox created by a different user.\n"); exit(1); } diff --git a/src/firejail/util.c b/src/firejail/util.c index a9e96266c..9ad937f55 100644 --- a/src/firejail/util.c +++ b/src/firejail/util.c @@ -492,3 +492,46 @@ const char *gnu_basename(const char *path) return path; return last_slash+1; } + +uid_t pid_get_uid(pid_t pid) { + uid_t rv = 0; + + // open status file + char *file; + if (asprintf(&file, "/proc/%u/status", pid) == -1) { + perror("asprintf"); + exit(1); + } + FILE *fp = fopen(file, "r"); + if (!fp) { + free(file); + fprintf(stderr, "Error: cannot open /proc file\n"); + exit(1); + } + + // extract uid + static const int PIDS_BUFLEN = 1024; + char buf[PIDS_BUFLEN]; + while (fgets(buf, PIDS_BUFLEN - 1, fp)) { + if (strncmp(buf, "Uid:", 4) == 0) { + char *ptr = buf + 5; + while (*ptr != '\0' && (*ptr == ' ' || *ptr == '\t')) { + ptr++; + } + if (*ptr == '\0') + break; + + rv = atoi(ptr); + break; // break regardless! + } + } + + fclose(fp); + free(file); + + if (rv == 0) { + fprintf(stderr, "Error: cannot read /proc file\n"); + exit(1); + } + return rv; +} diff --git a/src/lib/pid.c b/src/lib/pid.c index 1a1797ce2..720d4eeb6 100644 --- a/src/lib/pid.c +++ b/src/lib/pid.c @@ -137,7 +137,7 @@ char *pid_get_user_name(uid_t uid) { uid_t pid_get_uid(pid_t pid) { uid_t rv = 0; - // open stat file + // open statua file char *file; if (asprintf(&file, "/proc/%u/status", pid) == -1) { perror("asprintf"); @@ -149,7 +149,7 @@ uid_t pid_get_uid(pid_t pid) { return 0; } - // look for firejail executable name + // extract uid char buf[PIDS_BUFLEN]; while (fgets(buf, PIDS_BUFLEN - 1, fp)) { if (strncmp(buf, "Uid:", 4) == 0) { diff --git a/todo b/todo index 588eac18c..c9003c4d7 100644 --- a/todo +++ b/todo @@ -69,5 +69,18 @@ profile_syntax.exp (profile syntax) fs_chroot.exp (chroot as user) private-etc.exp +8. Disable /dev/tcp in bash. Compiled time: --enable-net-redirections, --disable-net-redirections +ksh and zsh seem to have it. +Tests: +a) +cat /dev/tcp/www.google.com/80 +echo -e "GET / HTTP/1.1\r\nhost: http://www.google.com\r\nConnection: close\r\n\r\n" >&3 +cat <&3 + +c) A list of attacks +http://www.lanmaster53.com/2011/05/7-linux-shells-using-built-in-tools/ -- cgit v1.2.3-54-g00ecf