random hostname by default; fix --hostname and --hosts-file

This commit is contained in:
netblue30 2023-02-27 17:50:02 -05:00
parent 854e54fb59
commit e4f9f36a47
7 changed files with 188 additions and 13 deletions

View file

@ -660,7 +660,7 @@ void fs_tracefile(void);
void fs_trace(void);
// fs_hostname.c
void fs_hostname(const char *hostname);
void fs_hostname(void);
char *fs_check_hosts_file(const char *fname);
void fs_store_hosts_file(void);
void fs_mount_hosts_file(void);

View file

@ -24,7 +24,36 @@
#include <dirent.h>
#include <fcntl.h>
void fs_hostname(const char *hostname) {
// build a random host name
static 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',
'r', 'r', 's', 's', 's', 's', 's', 's', 's', 's', 't', 't', 't', 't',
'w', 'y', 'y', 'y', 'y', 'z', 'z'};
char *ending[] = {"hiko", "hiko", "suke", "suke", "suke", "shi", "shi", "ro", "ro",
"rou", "hito", "hito","ka"};
char *name = malloc(20);
if (!name)
errExit("malloc");
int i = 0;
name[i++] = consonants[rand() % sizeof(consonants)];
name[i++] = vowels[rand() % sizeof(vowels)];
name[i++] = consonants[rand() % sizeof(consonants)];
name[i++] = vowels[rand() % sizeof(vowels)];
if (rand() % 2) {
name[i++] = consonants[rand() % sizeof(consonants)];
name[i++] = vowels[rand() % sizeof(vowels)];
}
char *ptr = ending[rand() % (sizeof(ending) / sizeof(char *))];
strcpy(name + i, ptr);
return name;
}
void fs_hostname(void) {
const char *hostname = (cfg.hostname)? cfg.hostname: random_hostname();
struct stat s;
// create a new /etc/hostname
@ -33,6 +62,14 @@ void fs_hostname(const char *hostname) {
printf("Creating a new /etc/hostname file\n");
create_empty_file_as_root(RUN_HOSTNAME_FILE, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
FILE *fp = fopen(RUN_HOSTNAME_FILE, "we");
if (!fp) {
fclose(fp);
goto errexit;
}
fprintf(fp, "%s\n", hostname);
SET_PERMS_STREAM(fp, 0, 0, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
fclose(fp);
// bind-mount the file on top of /etc/hostname
if (mount(RUN_HOSTNAME_FILE, "/etc/hostname", NULL, MS_BIND|MS_REC, NULL) < 0)
@ -41,12 +78,12 @@ void fs_hostname(const char *hostname) {
}
// create a new /etc/hosts
if (cfg.hosts_file == NULL && stat("/etc/hosts", &s) == 0) {
if (stat(RUN_HOSTS_FILE2, &s) == 0) {
if (arg_debug)
printf("Creating a new /etc/hosts file\n");
// copy /etc/host into our new file, and modify it on the fly
/* coverity[toctou] */
FILE *fp1 = fopen("/etc/hosts", "re");
FILE *fp1 = fopen(RUN_HOSTS_FILE2, "re");
if (!fp1)
goto errexit;
@ -67,7 +104,7 @@ void fs_hostname(const char *hostname) {
// copy line
if (strstr(buf, "127.0.0.1") && done == 0) {
done = 1;
fprintf(fp2, "%s %s\n", buf, hostname);
fprintf(fp2, "127.0.0.1 %s\n", hostname);
}
else
fprintf(fp2, "%s\n", buf);
@ -83,7 +120,7 @@ void fs_hostname(const char *hostname) {
return;
errexit:
fprintf(stderr, "Error: cannot create hostname file\n");
fprintf(stderr, "Error: cannot create /etc/hostname and /etc/hosts files\n");
exit(1);
}
@ -103,7 +140,10 @@ errexit:
}
void fs_store_hosts_file(void) {
copy_file_from_user_to_root(cfg.hosts_file, RUN_HOSTS_FILE, 0, 0, 0644); // root needed
if (cfg.hosts_file)
copy_file_from_user_to_root(cfg.hosts_file, RUN_HOSTS_FILE2, 0, 0, 0644); // root needed
else
copy_file_from_user_to_root("/etc/hosts", RUN_HOSTS_FILE2, 0, 0, 0644); // root needed
}
void fs_mount_hosts_file(void) {

View file

@ -848,8 +848,7 @@ int sandbox(void* sandbox_arg) {
fs_trace_touch_or_store_preload();
// store hosts file
if (cfg.hosts_file)
fs_store_hosts_file();
fs_store_hosts_file();
//****************************
// configure filesystem
@ -986,11 +985,11 @@ int sandbox(void* sandbox_arg) {
//****************************
// hosts and hostname
//****************************
if (cfg.hostname)
fs_hostname(cfg.hostname);
// if (cfg.hostname)
fs_hostname();
if (cfg.hosts_file)
fs_mount_hosts_file();
// if (cfg.hosts_file)
// fs_mount_hosts_file();
//****************************
// /etc overrides from the network namespace

View file

@ -89,6 +89,7 @@
#define RUN_ASOUNDRC_FILE RUN_MNT_DIR "/.asoundrc"
#define RUN_HOSTNAME_FILE RUN_MNT_DIR "/hostname"
#define RUN_HOSTS_FILE RUN_MNT_DIR "/hosts"
#define RUN_HOSTS_FILE2 RUN_MNT_DIR "/hosts2"
#define RUN_MACHINEID RUN_MNT_DIR "/machine-id"
#define RUN_LDPRELOAD_FILE RUN_MNT_DIR "/ld.so.preload"
#define RUN_UTMP_FILE RUN_MNT_DIR "/utmp"

130
test/private-etc/hostname.exp Executable file
View file

@ -0,0 +1,130 @@
#!/usr/bin/expect -f
# This file is part of Firejail project
# Copyright (C) 2014-2023 Firejail Authors
# License GPL v2
set timeout 10
spawn $env(SHELL)
match_max 100000
send -- "firejail --hostname=foo cat /etc/hostname\r"
expect {
timeout {puts "TESTING ERROR 0\n";exit}
"Child process initialized"
}
expect {
timeout {puts "TESTING ERROR 0.1\n";exit}
"foo"
}
sleep 1
send -- "firejail --hostname=foo --private-etc cat /etc/hostname\r"
expect {
timeout {puts "TESTING ERROR 1\n";exit}
"Child process initialized"
}
expect {
timeout {puts "TESTING ERROR 1.1\n";exit}
"foo"
}
sleep 1
send -- "firejail --hosts-file=hosts-file cat /etc/hosts\r"
expect {
timeout {puts "TESTING ERROR 2\n";exit}
"Child process initialized"
}
expect {
timeout {puts "TESTING ERROR 2.1\n";exit}
"blablabla"
}
sleep 1
send -- "firejail --hosts-file=hosts-file --private-etc cat /etc/hosts\r"
expect {
timeout {puts "TESTING ERROR 3\n";exit}
"Child process initialized"
}
expect {
timeout {puts "TESTING ERROR 3.1\n";exit}
"blablabla"
}
sleep 1
send -- "firejail --hosts-file=hosts-file --hostname=foo cat /etc/hosts\r"
expect {
timeout {puts "TESTING ERROR 4\n";exit}
"Child process initialized"
}
expect {
timeout {puts "TESTING ERROR 4.1\n";exit}
"foo"
}
expect {
timeout {puts "TESTING ERROR 4.2\n";exit}
"blablabla"
}
sleep 1
send -- "firejail --hosts-file=hosts-file --hostname=foo --private-etc cat /etc/hosts\r"
expect {
timeout {puts "TESTING ERROR 5\n";exit}
"Child process initialized"
}
expect {
timeout {puts "TESTING ERROR 5.1\n";exit}
"foo"
}
expect {
timeout {puts "TESTING ERROR 5.2\n";exit}
"blablabla"
}
sleep 1
# ping test
send -- "firejail --hostname=foo --private-etc ping -c 3 foo\r"
expect {
timeout {puts "TESTING ERROR 6\n";exit}
"3 packets transmitted, 3 received"
}
sleep 1
send -- "firejail --hosts-file=hosts-file --private-etc ping -c 3 blablabla\r"
expect {
timeout {puts "TESTING ERROR 7\n";exit}
"3 packets transmitted, 3 received"
}
sleep 1
# random hostname
send -- "firejail cat /etc/hostname\r"
expect {
timeout {puts "TESTING ERROR 8\n";exit}
"Child process initialized"
}
expect {
timeout {puts "TESTING ERROR 8.1\n";exit}
"hiko" {puts "1"}
"suke" {puts "2"}
"shi" {puts "3"}
"ro" {puts "4"}
"hito" {puts "5"}
"ka" {puts "6"}
}
sleep 1
# run /bin/hostname
send -- "firejail --noblacklist=/usr/bin/hostname --noblacklist=/bin/hostname --hostname=foo /usr/bin/hostname\r"
expect {
timeout {puts "TESTING ERROR 9\n";exit}
"Child process initialized"
}
expect {
timeout {puts "TESTING ERROR 9.1\n";exit}
"foo"
}
after 500
puts "all done\n"

View file

@ -0,0 +1,2 @@
127.0.0.1 debian
127.5.5.5 blablabla

View file

@ -18,3 +18,6 @@ echo "TESTING: groups (test/private-etc/groups.exp)"
echo "TESTING: etc-cleanup (test/private-etc/etc-cleanup.exp)"
./etc-cleanup.exp
echo "TESTING: hostname (test/private-etc/hostname.exp)"
./hostname.exp