diff --git a/README.md b/README.md index 27279b4bf..0624dceb0 100644 --- a/README.md +++ b/README.md @@ -443,15 +443,21 @@ full path or a relative path for the filename. Parent is shutting down, bye… ``` -### --keep-hostname +### --hostname-randomize ```text - --keep-hostname - By default, the hostname is replaced by a random name generated - by firejail at startup. Use this option to disable this feature. + --hostname-randomize + Set sandbox hostname to a random value generated by firejail. + This is incompatible with --hostname. Example: - $ firejail --keep-hostname + $ firejail --hostname-randomize /usr/bin/firefox + Note: Changing the hostname may cause breakage related to + networking (see #7048 + ) and may + cause X11 programs to crash on startup due to not being able to + authenticate to the X server (see #7062 + ). ``` ### Landlock support - ongoing/experimental diff --git a/RELNOTES b/RELNOTES index ee68e477e..18e9b4339 100644 --- a/RELNOTES +++ b/RELNOTES @@ -7,7 +7,9 @@ firejail (0.9.79) baseline; urgency=low for sandbox escape (cbf4308 c8a6707) * feature: hide PID 1 inside of the sandbox and add --unhide-pid1 command to unhide (#7046) - * feature: add --keep-hostname command and profile option (#7069) + * feature: add --hostname-randomize command and profile option - stop + randomizing the hostname by default to fix breakage with X11 programs + (#7062 #7069 #7095) * feature: add --debug-syscall-groups command (#7049 #7055) * feature: add apparmor profiles for --nettrace command (#7093) * modif: reorganize & update syscall groups (#7024 #7027 #7034 #7039 #7042 diff --git a/contrib/syntax/lists/profile_commands_arg0.list b/contrib/syntax/lists/profile_commands_arg0.list index 9fed09678..91d3c68d1 100644 --- a/contrib/syntax/lists/profile_commands_arg0.list +++ b/contrib/syntax/lists/profile_commands_arg0.list @@ -8,6 +8,7 @@ caps deterministic-exit-code deterministic-shutdown disable-mnt +hostname-randomize ipc-namespace keep-config-pulse keep-dev-ntsync diff --git a/etc/profile-a-l/libreoffice.profile b/etc/profile-a-l/libreoffice.profile index ba4184176..dda81291f 100644 --- a/etc/profile-a-l/libreoffice.profile +++ b/etc/profile-a-l/libreoffice.profile @@ -6,6 +6,8 @@ include libreoffice.local # Persistent global definitions include globals.local +ignore hostname-randomize + noblacklist ${HOME}/.config/libreoffice noblacklist ${HOME}/.local/share/gvfs-metadata noblacklist /usr/local/sbin @@ -44,8 +46,6 @@ include whitelist-var-common.inc #ignore seccomp #ignore tracelog -keep-hostname - apparmor caps.drop all netfilter diff --git a/etc/profile-m-z/noprofile.profile b/etc/profile-m-z/noprofile.profile index c399b3747..b4712464b 100644 --- a/etc/profile-m-z/noprofile.profile +++ b/etc/profile-m-z/noprofile.profile @@ -25,7 +25,6 @@ keep-dev-ntsync keep-dev-shm keep-dev-tpm keep-fd all -keep-hostname keep-shell-rc keep-var-tmp writable-etc diff --git a/etc/templates/profile.template b/etc/templates/profile.template index ac786e912..6754f74e0 100644 --- a/etc/templates/profile.template +++ b/etc/templates/profile.template @@ -168,7 +168,6 @@ include globals.local ##keep-dev-shm ##keep-dev-tpm ##keep-fd all -##keep-hostname ##keep-shell-rc ##keep-var-tmp ##writable-etc @@ -181,6 +180,7 @@ include globals.local #caps.drop all ##caps.keep CAPS ##hostname NAME +##hostname-randomize # CLI only ##ipc-namespace # breaks audio and sometimes dbus related functions diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 8b4a86c2e..4ad489209 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h @@ -375,7 +375,7 @@ extern int arg_netlock; // netlocker extern int arg_restrict_namespaces; extern int arg_allow_bwrap; extern int arg_unhide_pid1; -extern int arg_keep_hostname; +extern int arg_hostname_randomize; typedef enum { DBUS_POLICY_ALLOW, // Allow unrestricted access to the bus @@ -691,7 +691,8 @@ void fs_tracefile(void); void fs_trace(void); // fs_hostname.c -void fs_hostname(void); +char *random_hostname(void); +void fs_hostname(const char *orig_hostname); char *fs_check_hosts_file(const char *fname); void fs_store_hosts_file(void); void fs_mount_hosts_file(void); diff --git a/src/firejail/fs_hostname.c b/src/firejail/fs_hostname.c index 168ebdcd3..e180663b4 100644 --- a/src/firejail/fs_hostname.c +++ b/src/firejail/fs_hostname.c @@ -25,9 +25,7 @@ #include // build a random host name -static char *random_hostname(void) { - assert(!arg_keep_hostname); - +char *random_hostname(void) { char vowels[] = { 'a', 'e', 'i', 'o', 'u'}; char consonants[] = {'b', 'c', 'c', 'c', 'g', 'h', 'h', 'h', 'h', 'h', 'j', 'j', 'k', 'k', 'k', 'k', 'k', 'k', 'k', 'k', 'k', 'k', 'm', 'm', 'm', 'm', 'n', 'n', 'n', 'n', 'n', @@ -54,11 +52,16 @@ static char *random_hostname(void) { return name; } -void fs_hostname(void) { - assert(!arg_keep_hostname); +void fs_hostname(const char *orig_hostname) { + char tmp[256] = ""; + const char *hostname = orig_hostname; + if (!hostname) { + if (gethostname(tmp, 256 - 1)) + errExit("gethostname"); + hostname = tmp; + } + assert(hostname); - if (!cfg.hostname) - cfg.hostname = random_hostname(); struct stat s; // create a new /etc/hostname @@ -70,7 +73,7 @@ void fs_hostname(void) { FILE *fp = fopen(RUN_HOSTNAME_FILE, "we"); if (!fp) goto errexit; - fprintf(fp, "%s\n", cfg.hostname); + fprintf(fp, "%s\n", hostname); SET_PERMS_STREAM(fp, 0, 0, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); fclose(fp); @@ -108,12 +111,12 @@ void fs_hostname(void) { // copy line if (strstr(buf, "127.0.0.1") && done_ipv4 == 0) { done_ipv4 = 1; - fprintf(fp2, "127.0.0.1 %s\n", cfg.hostname); + fprintf(fp2, "127.0.0.1 %s\n", hostname); fprintf(fp2, "127.0.0.1 localhost\n"); } else if (strstr(buf, "::1") && done_ipv6 == 0) { done_ipv6 = 1; - fprintf(fp2, "::1 %s\n", cfg.hostname); + fprintf(fp2, "::1 %s\n", hostname); fprintf(fp2, "::1 localhost\n"); } else diff --git a/src/firejail/main.c b/src/firejail/main.c index 7da2c5763..332ed2bef 100644 --- a/src/firejail/main.c +++ b/src/firejail/main.c @@ -171,7 +171,7 @@ int arg_netlock = 0; int arg_restrict_namespaces = 0; int arg_allow_bwrap = 0; int arg_unhide_pid1 = 0; -int arg_keep_hostname = 0; +int arg_hostname_randomize = 0; int parent_to_child_fds[2]; int child_to_parent_fds[2]; @@ -2128,8 +2128,8 @@ int main(int argc, char **argv, char **envp) { } } else if (strncmp(argv[i], "--hostname=", 11) == 0) { - if (arg_keep_hostname) { - fprintf(stderr, "Error: hostname and keep-hostname are mutually exclusive\n"); + if (arg_hostname_randomize) { + fprintf(stderr, "Error: hostname and hostname-randomize are mutually exclusive\n"); exit(1); } cfg.hostname = argv[i] + 11; @@ -2142,13 +2142,16 @@ int main(int argc, char **argv, char **envp) { return 1; } } - else if (strcmp(argv[i], "--keep-hostname") == 0) { + else if (strcmp(argv[i], "--hostname-randomize") == 0) { if (cfg.hostname) { - fprintf(stderr, "Error: hostname and keep-hostname are mutually exclusive\n"); + fprintf(stderr, "Error: hostname and hostname-randomize are mutually exclusive\n"); exit(1); } - arg_keep_hostname = 1; + arg_hostname_randomize = 1; } + // TODO: Fully remove keep-hostname after 0.9.80. + else if (strcmp(argv[i], "--keep-hostname") == 0) + fwarning("ignoring removed command: --keep-hostname (see --hostname-randomize)\n"); else if (strcmp(argv[i], "--nogroups") == 0) arg_nogroups = 1; #ifdef HAVE_USERNS diff --git a/src/firejail/profile.c b/src/firejail/profile.c index f612b7064..2f8118b51 100644 --- a/src/firejail/profile.c +++ b/src/firejail/profile.c @@ -1200,8 +1200,8 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { // hostname if (strncmp(ptr, "hostname ", 9) == 0) { - if (arg_keep_hostname) { - fprintf(stderr, "Error: hostname and keep-hostname are mutually exclusive\n"); + if (arg_hostname_randomize) { + fprintf(stderr, "Error: hostname and hostname-randomize are mutually exclusive\n"); exit(1); } cfg.hostname = ptr + 9; @@ -1215,12 +1215,17 @@ int profile_check_line(char *ptr, int lineno, const char *fname) { } return 0; } - if (strncmp(ptr, "keep-hostname", 13) == 0) { + if (strncmp(ptr, "hostname-randomize", 18) == 0) { if (cfg.hostname) { - fprintf(stderr, "Error: hostname and keep-hostname are mutually exclusive\n"); + fprintf(stderr, "Error: hostname and hostname-randomize are mutually exclusive\n"); exit(1); } - arg_keep_hostname = 1; + arg_hostname_randomize = 1; + return 0; + } + // TODO: Fully remove keep-hostname after 0.9.80. + if (strncmp(ptr, "keep-hostname", 13) == 0) { + fwarning("ignoring removed command: keep-hostname (see hostname-randomize)\n"); return 0; } diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c index 71d834bf3..13d80b2dc 100644 --- a/src/firejail/sandbox.c +++ b/src/firejail/sandbox.c @@ -980,15 +980,18 @@ int sandbox(void* sandbox_arg) { //**************************** // hosts and hostname //**************************** - if (!arg_keep_hostname) { - fs_hostname(); + if (!cfg.hostname && arg_hostname_randomize) + cfg.hostname = random_hostname(); + + if (cfg.hostname) { // /usr/bin/hostname is blacklisted in default.profile // test this using cat /proc/sys/kernel/hostname, - assert(cfg.hostname); if (sethostname(cfg.hostname, strlen(cfg.hostname)) < 0) errExit("sethostname"); } + fs_hostname(cfg.hostname); + //**************************** // /etc overrides from the network namespace //**************************** diff --git a/src/firejail/usage.c b/src/firejail/usage.c index 39d9d805a..4ace203a9 100644 --- a/src/firejail/usage.c +++ b/src/firejail/usage.c @@ -108,6 +108,7 @@ static const char *const usage_str = #endif " --help, -? - this help screen.\n" " --hostname=name - set sandbox hostname.\n" + " --hostname-randomize - set sandbox hostname to a random value.\n" " --hosts-file=file - use file as /etc/hosts.\n" #ifdef HAVE_NETWORK " --icmptrace - monitor Server Name Indiication (TLS/SNI).\n" @@ -136,7 +137,6 @@ static const char *const usage_str = " --keep-dev-shm - /dev/shm directory is untouched (even with --private-dev).\n" " --keep-dev-tpm - /dev/tpm* devices are untouched (even with --private-dev).\n" " --keep-fd - inherit open file descriptors to sandbox.\n" - " --keep-hostname - use the current hostname\n" " --keep-shell-rc - do not copy shell rc files from /etc/skel\n" " --keep-var-tmp - /var/tmp directory is untouched.\n" #ifdef HAVE_LANDLOCK diff --git a/src/man/firejail-profile.5.in b/src/man/firejail-profile.5.in index 12e6a67cc..35b8d5d2b 100644 --- a/src/man/firejail-profile.5.in +++ b/src/man/firejail-profile.5.in @@ -915,9 +915,8 @@ Set a DNS server for the sandbox. Up to three DNS servers can be defined. Set a hostname for the sandbox. .TP -\fBkeep\-hostname -By default, the hostname is replaced by a random name generated -by firejail at startup. Use this option to disable this feature. +\fBhostname\-randomize +Set sandbox hostname to a random value generated by firejail. .TP \fBhosts\-file file diff --git a/src/man/firejail.1.in b/src/man/firejail.1.in index be6d0e16e..87739d7fe 100644 --- a/src/man/firejail.1.in +++ b/src/man/firejail.1.in @@ -985,6 +985,8 @@ Print options end exit. \fB\-\-hostname=name Set sandbox hostname. .br +This is incompatible with \fB\-\-hostname\-randomize\fR. +.br For valid names, see the \fBNAME VALIDATION\fR section. .br @@ -993,6 +995,28 @@ Example: .br $ firejail \-\-hostname=officepc /usr/bin/firefox +.TP +\fB\-\-hostname\-randomize +Set sandbox hostname to a random value generated by firejail. +.br +This is incompatible with \fB\-\-hostname\fR. +.br + +.br +Example: +.br +$ firejail \-\-hostname-randomize /usr/bin/firefox +.br +Note: Changing the hostname may cause breakage related to networking (see +.UR https://github.com/netblue30/firejail/issues/7048 +#7048 +.UE ) +and may cause X11 programs to crash on startup due to not being able to +authenticate to the X server (see +.UR https://github.com/netblue30/firejail/issues/7062 +#7062 +.UE ). + .TP \fB\-\-hosts-file=file Use file as /etc/hosts. @@ -1357,18 +1381,6 @@ Example: .br $ firejail \-\-keep\-fd=3,4,5 -.TP -\fB\-\-keep\-hostname -By default, the hostname is replaced by a random name generated by firejail -at startup. Use this option to disable this feature. -.br - -.br -Example: -.br -$ firejail \-\-keep\-hostname -.br - .TP \fB\-\-keep\-shell\-rc By default, when using a private home directory, firejail copies files from the diff --git a/test/private-etc/hostname.exp b/test/private-etc/hostname.exp index 713750a24..328de79a7 100755 --- a/test/private-etc/hostname.exp +++ b/test/private-etc/hostname.exp @@ -108,7 +108,7 @@ expect { sleep 1 # random hostname -send -- "firejail cat /etc/hostname\r" +send -- "firejail --hostname-randomize cat /etc/hostname\r" expect { timeout {puts "TESTING ERROR 8\n";exit} "Child process initialized"