diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 577c1a9ae..4babc58e7 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -26,6 +26,9 @@ // filesystem #define RUN_FIREJAIL_BASEDIR "/run" #define RUN_FIREJAIL_DIR "/run/firejail" +#define RUN_FIREJAIL_NAME_DIR "/run/firejail/name" +#define RUN_FIREJAIL_NETWORK_DIR "/run/firejail/network" +#define RUN_FIREJAIL_BANDWIDTH_DIR "/run/firejail/bandwidth" #define RUN_NETWORK_LOCK_FILE "/run/firejail/firejail.lock" #define RUN_RO_DIR "/run/firejail/firejail.ro.dir" #define RUN_RO_FILE "/run/firejail/firejail.ro.file" diff --git a/src/firejail/fs.c b/src/firejail/fs.c index c3e9890b4..616b87562 100644 --- a/src/firejail/fs.c +++ b/src/firejail/fs.c @@ -85,6 +85,27 @@ void fs_build_firejail_dir(void) { errExit("chown"); if (chmod(RUN_FIREJAIL_DIR, 0755) < 0) errExit("chmod"); + + if (mkdir(RUN_FIREJAIL_NETWORK_DIR, 0755) == -1) + errExit("mkdir"); + if (chown(RUN_FIREJAIL_NETWORK_DIR, 0, 0) < 0) + errExit("chown"); + if (chmod(RUN_FIREJAIL_NETWORK_DIR, 0755) < 0) + errExit("chmod"); + + if (mkdir(RUN_FIREJAIL_BANDWIDTH_DIR, 0755) == -1) + errExit("mkdir"); + if (chown(RUN_FIREJAIL_BANDWIDTH_DIR, 0, 0) < 0) + errExit("chown"); + if (chmod(RUN_FIREJAIL_BANDWIDTH_DIR, 0755) < 0) + errExit("chmod"); + + if (mkdir(RUN_FIREJAIL_NAME_DIR, 0755) == -1) + errExit("mkdir"); + if (chown(RUN_FIREJAIL_NAME_DIR, 0, 0) < 0) + errExit("chown"); + if (chmod(RUN_FIREJAIL_NAME_DIR, 0755) < 0) + errExit("chmod"); } else { // check /tmp/firejail directory belongs to root end exit if doesn't! if (s.st_uid != 0 || s.st_gid != 0) { diff --git a/src/firejail/main.c b/src/firejail/main.c index 688653ce2..3c714f385 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c @@ -104,6 +104,9 @@ int fullargc = 0; static pid_t child = 0; pid_t sandbox_pid; +static void set_name_file(uid_t pid); +static void delete_name_file(uid_t pid); + static void myexit(int rv) { logmsg("exiting..."); if (!arg_command && !arg_quiet) @@ -112,6 +115,7 @@ static void myexit(int rv) { // delete sandbox files in shared memory bandwidth_shm_del_file(sandbox_pid); // bandwidth file network_shm_del_file(sandbox_pid); // network map file + delete_name_file(sandbox_pid); exit(rv); } @@ -477,6 +481,36 @@ static void run_cmd_and_exit(int i, int argc, char **argv) { } +static void set_name_file(uid_t pid) { + char *fname; + if (asprintf(&fname, "%s/%d", RUN_FIREJAIL_NAME_DIR, pid) == -1) + errExit("asprintf"); + + // the file is deleted first + FILE *fp = fopen(fname, "w"); + if (!fp) { + fprintf(stderr, "Error: cannot create %s\n", fname); + exit(1); + } + fprintf(fp, "%s\n", cfg.name); + fclose(fp); + + // mode and ownership + if (chown(fname, 0, 0) == -1) + errExit("chown"); + if (chmod(fname, 0644) == -1) + errExit("chmod"); + +} + +static void delete_name_file(uid_t pid) { + char *fname; + if (asprintf(&fname, "%s/%d", RUN_FIREJAIL_NAME_DIR, pid) == -1) + errExit("asprintf"); + int rv = unlink(fname); + (void) rv; +} + //******************************************* // Main program //******************************************* @@ -1500,6 +1534,13 @@ int main(int argc, char **argv) { arg_noroot = 0; } + + // set name file + EUID_ROOT(); + if (cfg.name) + set_name_file(sandbox_pid); + EUID_USER(); + // clone environment int flags = CLONE_NEWNS | CLONE_NEWPID | CLONE_NEWUTS | SIGCHLD; @@ -1627,6 +1668,9 @@ int main(int argc, char **argv) { if (lockfd != -1) flock(lockfd, LOCK_UN); + // create name file under /run/firejail + + // handle CTRL-C in parent signal (SIGINT, my_handler); signal (SIGTERM, my_handler); diff --git a/src/lib/common.c b/src/lib/common.c index 099bb54d3..f321c5a47 100644 --- a/src/lib/common.c +++ b/src/lib/common.c @@ -95,53 +95,34 @@ int name2pid(const char *name, pid_t *pid) { free(comm); } - char *cmd = pid_proc_cmdline(newpid); - if (cmd) { - // mark the end of the name - char *ptr = strstr(cmd, "--name="); - char *start = ptr; - if (!ptr) { - free(cmd); - - // extract name for /run/mnt/firejail/fslogger file - char *fname; - if (asprintf(&fname, "/proc/%d/root/run/firejail/mnt/fslogger", newpid) == -1) - errExit("asprintf"); - - struct stat s; - if (stat(fname, &s) == 0) { - FILE *fp = fopen(fname, "r"); - if (fp) { - char buf[BUFLEN]; - if (fgets(buf, BUFLEN, fp)) { - if (strncmp(buf, "sandbox name: ", 14) == 0) { - char *ptr2 = buf + 14; - if (strncmp(name, ptr2, strlen(name)) == 0) { - fclose(fp); - *pid = newpid; - closedir(dir); - return 0; - } - } - } + // look for the sandbox name in /run/firejail/name/ + // todo: use RUN_FIREJAIL_NAME_DIR define from src/firejail/firejail.h + char *fname; + if (asprintf(&fname, "/run/firejail/name/%d", newpid) == -1) + errExit("asprintf"); + FILE *fp = fopen(fname, "r"); + if (fp) { + char buf[BUFLEN]; + if (fgets(buf, BUFLEN, fp)) { + // remove \n + char *ptr = strchr(buf, '\n'); + if (ptr) { + *ptr = '\0'; + if (strcmp(buf, name) == 0) { + // we found it! fclose(fp); + free(fname); + *pid = newpid; + closedir(dir); + return 0; } - } - - continue; + } + else + fprintf(stderr, "Error: invalid %s\n", fname); } - while (*ptr != ' ' && *ptr != '\t' && *ptr != '\0') - ptr++; - *ptr = '\0'; - int rv = strcmp(start + 7, name); - if (rv == 0) { - free(cmd); - *pid = newpid; - closedir(dir); - return 0; - } - free(cmd); + fclose(fp); } + free(fname); } closedir(dir); return 1;