aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar netblue30 <netblue30@protonmail.com>2023-02-27 17:50:02 -0500
committerLibravatar netblue30 <netblue30@protonmail.com>2023-02-27 17:50:02 -0500
commite4f9f36a47d5a0031bd181e77d9121fac1dd06ec (patch)
treee0c324bd24cf6d67f50f9dd6839e321c1d2bdb2c
parentminor clarify userns comments (#5686) (diff)
downloadfirejail-e4f9f36a4.tar.gz
firejail-e4f9f36a4.tar.zst
firejail-e4f9f36a4.zip
random hostname by default; fix --hostname and --hosts-file
-rw-r--r--src/firejail/firejail.h2
-rw-r--r--src/firejail/fs_hostname.c52
-rw-r--r--src/firejail/sandbox.c11
-rw-r--r--src/include/rundefs.h1
-rwxr-xr-xtest/private-etc/hostname.exp130
-rw-r--r--test/private-etc/hosts-file2
-rwxr-xr-xtest/private-etc/private-etc.sh3
7 files changed, 188 insertions, 13 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 824164c8a..5295393f0 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -660,7 +660,7 @@ void fs_tracefile(void);
660void fs_trace(void); 660void fs_trace(void);
661 661
662// fs_hostname.c 662// fs_hostname.c
663void fs_hostname(const char *hostname); 663void fs_hostname(void);
664char *fs_check_hosts_file(const char *fname); 664char *fs_check_hosts_file(const char *fname);
665void fs_store_hosts_file(void); 665void fs_store_hosts_file(void);
666void fs_mount_hosts_file(void); 666void fs_mount_hosts_file(void);
diff --git a/src/firejail/fs_hostname.c b/src/firejail/fs_hostname.c
index bf4435310..32b314a8b 100644
--- a/src/firejail/fs_hostname.c
+++ b/src/firejail/fs_hostname.c
@@ -24,7 +24,36 @@
24#include <dirent.h> 24#include <dirent.h>
25#include <fcntl.h> 25#include <fcntl.h>
26 26
27void fs_hostname(const char *hostname) { 27// build a random host name
28static char *random_hostname(void) {
29 char vowels[] = { 'a', 'e', 'i', 'o', 'u'};
30 char consonants[] = {'b', 'c', 'c', 'c', 'g', 'h', 'h', 'h', 'h', 'h',
31 'j', 'j', 'k', 'k', 'k', 'k', 'k', 'k', 'k', 'k', 'k', 'k', 'm', 'm', 'm', 'm', 'n', 'n', 'n', 'n', 'n',
32 'r', 'r', 's', 's', 's', 's', 's', 's', 's', 's', 't', 't', 't', 't',
33 'w', 'y', 'y', 'y', 'y', 'z', 'z'};
34 char *ending[] = {"hiko", "hiko", "suke", "suke", "suke", "shi", "shi", "ro", "ro",
35 "rou", "hito", "hito","ka"};
36
37 char *name = malloc(20);
38 if (!name)
39 errExit("malloc");
40
41 int i = 0;
42 name[i++] = consonants[rand() % sizeof(consonants)];
43 name[i++] = vowels[rand() % sizeof(vowels)];
44 name[i++] = consonants[rand() % sizeof(consonants)];
45 name[i++] = vowels[rand() % sizeof(vowels)];
46 if (rand() % 2) {
47 name[i++] = consonants[rand() % sizeof(consonants)];
48 name[i++] = vowels[rand() % sizeof(vowels)];
49 }
50 char *ptr = ending[rand() % (sizeof(ending) / sizeof(char *))];
51 strcpy(name + i, ptr);
52 return name;
53}
54
55void fs_hostname(void) {
56 const char *hostname = (cfg.hostname)? cfg.hostname: random_hostname();
28 struct stat s; 57 struct stat s;
29 58
30 // create a new /etc/hostname 59 // create a new /etc/hostname
@@ -33,6 +62,14 @@ void fs_hostname(const char *hostname) {
33 printf("Creating a new /etc/hostname file\n"); 62 printf("Creating a new /etc/hostname file\n");
34 63
35 create_empty_file_as_root(RUN_HOSTNAME_FILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 64 create_empty_file_as_root(RUN_HOSTNAME_FILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
65 FILE *fp = fopen(RUN_HOSTNAME_FILE, "we");
66 if (!fp) {
67 fclose(fp);
68 goto errexit;
69 }
70 fprintf(fp, "%s\n", hostname);
71 SET_PERMS_STREAM(fp, 0, 0, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
72 fclose(fp);
36 73
37 // bind-mount the file on top of /etc/hostname 74 // bind-mount the file on top of /etc/hostname
38 if (mount(RUN_HOSTNAME_FILE, "/etc/hostname", NULL, MS_BIND|MS_REC, NULL) < 0) 75 if (mount(RUN_HOSTNAME_FILE, "/etc/hostname", NULL, MS_BIND|MS_REC, NULL) < 0)
@@ -41,12 +78,12 @@ void fs_hostname(const char *hostname) {
41 } 78 }
42 79
43 // create a new /etc/hosts 80 // create a new /etc/hosts
44 if (cfg.hosts_file == NULL && stat("/etc/hosts", &s) == 0) { 81 if (stat(RUN_HOSTS_FILE2, &s) == 0) {
45 if (arg_debug) 82 if (arg_debug)
46 printf("Creating a new /etc/hosts file\n"); 83 printf("Creating a new /etc/hosts file\n");
47 // copy /etc/host into our new file, and modify it on the fly 84 // copy /etc/host into our new file, and modify it on the fly
48 /* coverity[toctou] */ 85 /* coverity[toctou] */
49 FILE *fp1 = fopen("/etc/hosts", "re"); 86 FILE *fp1 = fopen(RUN_HOSTS_FILE2, "re");
50 if (!fp1) 87 if (!fp1)
51 goto errexit; 88 goto errexit;
52 89
@@ -67,7 +104,7 @@ void fs_hostname(const char *hostname) {
67 // copy line 104 // copy line
68 if (strstr(buf, "127.0.0.1") && done == 0) { 105 if (strstr(buf, "127.0.0.1") && done == 0) {
69 done = 1; 106 done = 1;
70 fprintf(fp2, "%s %s\n", buf, hostname); 107 fprintf(fp2, "127.0.0.1 %s\n", hostname);
71 } 108 }
72 else 109 else
73 fprintf(fp2, "%s\n", buf); 110 fprintf(fp2, "%s\n", buf);
@@ -83,7 +120,7 @@ void fs_hostname(const char *hostname) {
83 return; 120 return;
84 121
85errexit: 122errexit:
86 fprintf(stderr, "Error: cannot create hostname file\n"); 123 fprintf(stderr, "Error: cannot create /etc/hostname and /etc/hosts files\n");
87 exit(1); 124 exit(1);
88} 125}
89 126
@@ -103,7 +140,10 @@ errexit:
103} 140}
104 141
105void fs_store_hosts_file(void) { 142void fs_store_hosts_file(void) {
106 copy_file_from_user_to_root(cfg.hosts_file, RUN_HOSTS_FILE, 0, 0, 0644); // root needed 143 if (cfg.hosts_file)
144 copy_file_from_user_to_root(cfg.hosts_file, RUN_HOSTS_FILE2, 0, 0, 0644); // root needed
145 else
146 copy_file_from_user_to_root("/etc/hosts", RUN_HOSTS_FILE2, 0, 0, 0644); // root needed
107} 147}
108 148
109void fs_mount_hosts_file(void) { 149void fs_mount_hosts_file(void) {
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index a4109cc17..88de1fc5f 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -848,8 +848,7 @@ int sandbox(void* sandbox_arg) {
848 fs_trace_touch_or_store_preload(); 848 fs_trace_touch_or_store_preload();
849 849
850 // store hosts file 850 // store hosts file
851 if (cfg.hosts_file) 851 fs_store_hosts_file();
852 fs_store_hosts_file();
853 852
854 //**************************** 853 //****************************
855 // configure filesystem 854 // configure filesystem
@@ -986,11 +985,11 @@ int sandbox(void* sandbox_arg) {
986 //**************************** 985 //****************************
987 // hosts and hostname 986 // hosts and hostname
988 //**************************** 987 //****************************
989 if (cfg.hostname) 988// if (cfg.hostname)
990 fs_hostname(cfg.hostname); 989 fs_hostname();
991 990
992 if (cfg.hosts_file) 991// if (cfg.hosts_file)
993 fs_mount_hosts_file(); 992// fs_mount_hosts_file();
994 993
995 //**************************** 994 //****************************
996 // /etc overrides from the network namespace 995 // /etc overrides from the network namespace
diff --git a/src/include/rundefs.h b/src/include/rundefs.h
index af42b0984..7fc0f21f3 100644
--- a/src/include/rundefs.h
+++ b/src/include/rundefs.h
@@ -89,6 +89,7 @@
89#define RUN_ASOUNDRC_FILE RUN_MNT_DIR "/.asoundrc" 89#define RUN_ASOUNDRC_FILE RUN_MNT_DIR "/.asoundrc"
90#define RUN_HOSTNAME_FILE RUN_MNT_DIR "/hostname" 90#define RUN_HOSTNAME_FILE RUN_MNT_DIR "/hostname"
91#define RUN_HOSTS_FILE RUN_MNT_DIR "/hosts" 91#define RUN_HOSTS_FILE RUN_MNT_DIR "/hosts"
92#define RUN_HOSTS_FILE2 RUN_MNT_DIR "/hosts2"
92#define RUN_MACHINEID RUN_MNT_DIR "/machine-id" 93#define RUN_MACHINEID RUN_MNT_DIR "/machine-id"
93#define RUN_LDPRELOAD_FILE RUN_MNT_DIR "/ld.so.preload" 94#define RUN_LDPRELOAD_FILE RUN_MNT_DIR "/ld.so.preload"
94#define RUN_UTMP_FILE RUN_MNT_DIR "/utmp" 95#define RUN_UTMP_FILE RUN_MNT_DIR "/utmp"
diff --git a/test/private-etc/hostname.exp b/test/private-etc/hostname.exp
new file mode 100755
index 000000000..791445d49
--- /dev/null
+++ b/test/private-etc/hostname.exp
@@ -0,0 +1,130 @@
1#!/usr/bin/expect -f
2# This file is part of Firejail project
3# Copyright (C) 2014-2023 Firejail Authors
4# License GPL v2
5
6set timeout 10
7spawn $env(SHELL)
8match_max 100000
9
10send -- "firejail --hostname=foo cat /etc/hostname\r"
11expect {
12 timeout {puts "TESTING ERROR 0\n";exit}
13 "Child process initialized"
14}
15expect {
16 timeout {puts "TESTING ERROR 0.1\n";exit}
17 "foo"
18}
19sleep 1
20
21send -- "firejail --hostname=foo --private-etc cat /etc/hostname\r"
22expect {
23 timeout {puts "TESTING ERROR 1\n";exit}
24 "Child process initialized"
25}
26expect {
27 timeout {puts "TESTING ERROR 1.1\n";exit}
28 "foo"
29}
30sleep 1
31
32send -- "firejail --hosts-file=hosts-file cat /etc/hosts\r"
33expect {
34 timeout {puts "TESTING ERROR 2\n";exit}
35 "Child process initialized"
36}
37expect {
38 timeout {puts "TESTING ERROR 2.1\n";exit}
39 "blablabla"
40}
41sleep 1
42
43send -- "firejail --hosts-file=hosts-file --private-etc cat /etc/hosts\r"
44expect {
45 timeout {puts "TESTING ERROR 3\n";exit}
46 "Child process initialized"
47}
48expect {
49 timeout {puts "TESTING ERROR 3.1\n";exit}
50 "blablabla"
51}
52sleep 1
53
54send -- "firejail --hosts-file=hosts-file --hostname=foo cat /etc/hosts\r"
55expect {
56 timeout {puts "TESTING ERROR 4\n";exit}
57 "Child process initialized"
58}
59expect {
60 timeout {puts "TESTING ERROR 4.1\n";exit}
61 "foo"
62}
63expect {
64 timeout {puts "TESTING ERROR 4.2\n";exit}
65 "blablabla"
66}
67sleep 1
68
69send -- "firejail --hosts-file=hosts-file --hostname=foo --private-etc cat /etc/hosts\r"
70expect {
71 timeout {puts "TESTING ERROR 5\n";exit}
72 "Child process initialized"
73}
74expect {
75 timeout {puts "TESTING ERROR 5.1\n";exit}
76 "foo"
77}
78expect {
79 timeout {puts "TESTING ERROR 5.2\n";exit}
80 "blablabla"
81}
82sleep 1
83
84# ping test
85send -- "firejail --hostname=foo --private-etc ping -c 3 foo\r"
86expect {
87 timeout {puts "TESTING ERROR 6\n";exit}
88 "3 packets transmitted, 3 received"
89}
90sleep 1
91
92send -- "firejail --hosts-file=hosts-file --private-etc ping -c 3 blablabla\r"
93expect {
94 timeout {puts "TESTING ERROR 7\n";exit}
95 "3 packets transmitted, 3 received"
96}
97sleep 1
98
99# random hostname
100send -- "firejail cat /etc/hostname\r"
101expect {
102 timeout {puts "TESTING ERROR 8\n";exit}
103 "Child process initialized"
104}
105expect {
106 timeout {puts "TESTING ERROR 8.1\n";exit}
107 "hiko" {puts "1"}
108 "suke" {puts "2"}
109 "shi" {puts "3"}
110 "ro" {puts "4"}
111 "hito" {puts "5"}
112 "ka" {puts "6"}
113}
114sleep 1
115
116# run /bin/hostname
117send -- "firejail --noblacklist=/usr/bin/hostname --noblacklist=/bin/hostname --hostname=foo /usr/bin/hostname\r"
118expect {
119 timeout {puts "TESTING ERROR 9\n";exit}
120 "Child process initialized"
121}
122expect {
123 timeout {puts "TESTING ERROR 9.1\n";exit}
124 "foo"
125}
126
127
128after 500
129puts "all done\n"
130
diff --git a/test/private-etc/hosts-file b/test/private-etc/hosts-file
new file mode 100644
index 000000000..1fb39596a
--- /dev/null
+++ b/test/private-etc/hosts-file
@@ -0,0 +1,2 @@
1127.0.0.1 debian
2127.5.5.5 blablabla
diff --git a/test/private-etc/private-etc.sh b/test/private-etc/private-etc.sh
index c46b684af..0dd61cb82 100755
--- a/test/private-etc/private-etc.sh
+++ b/test/private-etc/private-etc.sh
@@ -18,3 +18,6 @@ echo "TESTING: groups (test/private-etc/groups.exp)"
18 18
19echo "TESTING: etc-cleanup (test/private-etc/etc-cleanup.exp)" 19echo "TESTING: etc-cleanup (test/private-etc/etc-cleanup.exp)"
20./etc-cleanup.exp 20./etc-cleanup.exp
21
22echo "TESTING: hostname (test/private-etc/hostname.exp)"
23./hostname.exp