diff --git a/src/firejail/main.c b/src/firejail/main.c index 3c061e607..65569ae5f 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c @@ -494,25 +494,39 @@ static void run_cmd_and_exit(int i, int argc, char **argv) { exit(0); } else if (strcmp(argv[i], "--list") == 0) { - int rv = sbox_run(SBOX_ROOT| SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FIREMON, "--list"); - exit(rv); + if (pid_hidepid()) + sbox_run(SBOX_ROOT| SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FIREMON, "--list"); + else + sbox_run(SBOX_USER| SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FIREMON, "--list"); + exit(0); } else if (strcmp(argv[i], "--tree") == 0) { - int rv = sbox_run(SBOX_ROOT | SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FIREMON, "--tree"); - exit(rv); + if (pid_hidepid()) + sbox_run(SBOX_ROOT | SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FIREMON, "--tree"); + else + sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 2, PATH_FIREMON, "--tree"); + exit(0); } else if (strcmp(argv[i], "--top") == 0) { - int rv = sbox_run(SBOX_ROOT | SBOX_CAPS_NONE | SBOX_SECCOMP | SBOX_ALLOW_STDIN, - 2, PATH_FIREMON, "--top"); - exit(rv); + if (pid_hidepid()) + sbox_run(SBOX_ROOT | SBOX_CAPS_NONE | SBOX_SECCOMP | SBOX_ALLOW_STDIN, + 2, PATH_FIREMON, "--top"); + else + sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP | SBOX_ALLOW_STDIN, + 2, PATH_FIREMON, "--top"); + exit(0); } #ifdef HAVE_NETWORK else if (strcmp(argv[i], "--netstats") == 0) { if (checkcfg(CFG_NETWORK)) { struct stat s; - int rv = sbox_run(SBOX_ROOT | SBOX_CAPS_NONE | SBOX_SECCOMP | SBOX_ALLOW_STDIN, + if (stat("/proc/sys/kernel/grsecurity", &s) == 0 || pid_hidepid()) + sbox_run(SBOX_ROOT | SBOX_CAPS_NONE | SBOX_SECCOMP | SBOX_ALLOW_STDIN, 2, PATH_FIREMON, "--netstats"); - exit(rv); + else + sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP | SBOX_ALLOW_STDIN, + 2, PATH_FIREMON, "--netstats"); + exit(0); } else { fprintf(stderr, "Error: networking features are disabled in Firejail configuration file\n"); diff --git a/src/firemon/firemon.c b/src/firemon/firemon.c index 950311c00..1ec64bea8 100644 --- a/src/firemon/firemon.c +++ b/src/firemon/firemon.c @@ -35,6 +35,9 @@ static int arg_caps = 0; static int arg_cpu = 0; static int arg_cgroup = 0; static int arg_x11 = 0; +static int arg_top = 0; +static int arg_list = 0; +static int arg_netstats = 0; int arg_nowrap = 0; static struct termios tlocal; // startup terminal setting @@ -118,53 +121,39 @@ int main(int argc, char **argv) { } // options without a pid argument - else if (strcmp(argv[i], "--top") == 0) { - top(); // never to return - } - else if (strcmp(argv[i], "--list") == 0) { - list(); - return 0; - } + else if (strcmp(argv[i], "--top") == 0) + arg_top = 1; + else if (strcmp(argv[i], "--list") == 0) + arg_list = 1; + else if (strcmp(argv[i], "--tree") == 0) + arg_tree = 1; else if (strcmp(argv[i], "--netstats") == 0) { struct stat s; if (getuid() != 0 && stat("/proc/sys/kernel/grsecurity", &s) == 0) { fprintf(stderr, "Error: this feature is not available on Grsecurity systems\n"); exit(1); } - - netstats(); - return 0; + arg_netstats = 1; } // cumulative options with or without a pid argument - else if (strcmp(argv[i], "--x11") == 0) { + else if (strcmp(argv[i], "--x11") == 0) arg_x11 = 1; - } - else if (strcmp(argv[i], "--cgroup") == 0) { + else if (strcmp(argv[i], "--cgroup") == 0) arg_cgroup = 1; - } - else if (strcmp(argv[i], "--cpu") == 0) { + else if (strcmp(argv[i], "--cpu") == 0) arg_cpu = 1; - } - else if (strcmp(argv[i], "--seccomp") == 0) { + else if (strcmp(argv[i], "--seccomp") == 0) arg_seccomp = 1; - } - else if (strcmp(argv[i], "--caps") == 0) { + else if (strcmp(argv[i], "--caps") == 0) arg_caps = 1; - } - else if (strcmp(argv[i], "--tree") == 0) { - arg_tree = 1; - } - else if (strcmp(argv[i], "--interface") == 0) { + else if (strcmp(argv[i], "--interface") == 0) arg_interface = 1; - } - else if (strcmp(argv[i], "--route") == 0) { + else if (strcmp(argv[i], "--route") == 0) arg_route = 1; - } - else if (strcmp(argv[i], "--arp") == 0) { + else if (strcmp(argv[i], "--arp") == 0) arg_arp = 1; - } else if (strncmp(argv[i], "--name=", 7) == 0) { char *name = argv[i] + 7; @@ -201,8 +190,28 @@ int main(int argc, char **argv) { } } - if (arg_tree) - tree((pid_t) pid); + // allow only root user if /proc is mounted hidepid + if (pid_hidepid() && getuid() != 0) { + fprintf(stderr, "Error: /proc is mounted hidepid, you would need to be root to run this command\n"); + exit(1); + } + + if (arg_top) + top(); // never to return + if (arg_tree) { + tree(); + return 0; + } + if (arg_list) { + list(); + return 0; + } + if (arg_netstats) { + netstats(); + return 0; + } + + // cumulative options if (arg_interface) interface((pid_t) pid); if (arg_route) @@ -220,7 +229,7 @@ int main(int argc, char **argv) { if (arg_x11) x11((pid_t) pid); - if (!arg_route && !arg_arp && !arg_interface && !arg_tree && !arg_caps && !arg_seccomp && !arg_x11) + if (!arg_interface && !arg_route && !arg_arp && !arg_seccomp && !arg_caps && !arg_cgroup && !arg_x11) procevent((pid_t) pid); // never to return return 0; diff --git a/src/firemon/firemon.h b/src/firemon/firemon.h index a873430a3..c5607a792 100644 --- a/src/firemon/firemon.h +++ b/src/firemon/firemon.h @@ -75,7 +75,7 @@ void cpu(pid_t pid); void cgroup(pid_t pid); // tree.c -void tree(pid_t pid); +void tree(void); // netstats.c void netstats(void); diff --git a/src/firemon/tree.c b/src/firemon/tree.c index a4b92a11f..f6d22b517 100644 --- a/src/firemon/tree.c +++ b/src/firemon/tree.c @@ -19,8 +19,8 @@ */ #include "firemon.h" -void tree(pid_t pid) { - pid_read(pid); // include all processes +void tree(void) { + pid_read(0); // include all processes // print processes int i; diff --git a/src/include/common.h b/src/include/common.h index f7c8ea725..108820290 100644 --- a/src/include/common.h +++ b/src/include/common.h @@ -114,4 +114,5 @@ int name2pid(const char *name, pid_t *pid); char *pid_proc_comm(const pid_t pid); char *pid_proc_cmdline(const pid_t pid); int pid_proc_cmdline_x11_xpra_xephyr(const pid_t pid); +int pid_hidepid(void); #endif diff --git a/src/lib/common.c b/src/lib/common.c index fc4c167ba..ea0ab781a 100644 --- a/src/lib/common.c +++ b/src/lib/common.c @@ -260,5 +260,26 @@ int pid_proc_cmdline_x11_xpra_xephyr(const pid_t pid) { return 0; } +// return 1 if /proc is mounted hidepid, or if /proc/mouns access is denied +#define BUFLEN 4096 +int pid_hidepid(void) { + FILE *fp = fopen("/proc/mounts", "r"); + if (!fp) + return 1; + + char buf[BUFLEN]; + while (fgets(buf, BUFLEN, fp)) { + if (strstr(buf, "proc /proc proc")) { + fclose(fp); + // check hidepid + if (strstr(buf, "hidepid=2") || strstr(buf, "hidepid=1")) + return 1; + return 0; + } + } + + return 0; +} + diff --git a/src/lib/pid.c b/src/lib/pid.c index ef1a428fb..ed583c51d 100644 --- a/src/lib/pid.c +++ b/src/lib/pid.c @@ -29,7 +29,6 @@ //Process pids[max_pids]; Process *pids = NULL; int max_pids=32769; -#define PIDS_BUFLEN 4096 // get the memory associated with this pid void pid_getmem(unsigned pid, unsigned *rss, unsigned *shared) {