Remove trailing whitespace from src/

This commit is contained in:
Fred Barclay 2017-05-24 14:13:52 -05:00
parent 6db7fe46fb
commit 96c920e166
No known key found for this signature in database
GPG key ID: 7338CE369A928102
115 changed files with 1061 additions and 1134 deletions

View file

@ -34,6 +34,3 @@ _firecfg()
fi
} &&
complete -F _firecfg firecfg

View file

@ -109,6 +109,3 @@ _firejail()
} &&
complete -F _firejail firejail

View file

@ -34,6 +34,3 @@ _firemon()
fi
} &&
complete -F _firemon firemon

View file

@ -22,4 +22,3 @@ clean:; rm -f *.o faudit
distclean: clean
rm -fr Makefile

View file

@ -26,7 +26,7 @@ static int extract_caps(uint64_t *val) {
FILE *fp = fopen("/proc/self/status", "r");
if (!fp)
return 1;
char buf[MAXBUF];
while (fgets(buf, MAXBUF, fp)) {
if (strncmp(buf, "CapBnd:\t", 8) == 0) {
@ -47,7 +47,7 @@ static int extract_caps(uint64_t *val) {
static int check_capability(uint64_t map, int cap) {
int i;
uint64_t mask = 1ULL;
for (i = 0; i < 64; i++, mask <<= 1) {
if ((i == cap) && (mask & map))
return 1;
@ -58,22 +58,21 @@ static int check_capability(uint64_t map, int cap) {
void caps_test(void) {
uint64_t caps_val;
if (extract_caps(&caps_val)) {
printf("SKIP: cannot extract capabilities on this platform.\n");
return;
}
if (caps_val) {
printf("BAD: the capability map is %llx, it should be all zero. ", (unsigned long long) caps_val);
printf("Use \"firejail --caps.drop=all\" to fix it.\n");
if (check_capability(caps_val, CAP_SYS_ADMIN))
printf("UGLY: CAP_SYS_ADMIN is enabled.\n");
if (check_capability(caps_val, CAP_SYS_BOOT))
printf("UGLY: CAP_SYS_BOOT is enabled.\n");
}
else
printf("GOOD: all capabilities are disabled.\n");
printf("GOOD: all capabilities are disabled.\n");
}

View file

@ -28,7 +28,7 @@ int check_unix(const char *sockfile) {
// open socket
int sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock == -1)
if (sock == -1)
return rv;
// connect
@ -41,7 +41,7 @@ int check_unix(const char *sockfile) {
remote.sun_path[0] = '\0';
if (connect(sock, (struct sockaddr *)&remote, len) == 0)
rv = 0;
close(sock);
return rv;
}
@ -60,7 +60,7 @@ void dbus_test(void) {
*sockfile = '@';
char *ptr = strchr(sockfile, ',');
if (ptr)
*ptr = '\0';
*ptr = '\0';
rv = check_unix(sockfile);
*sockfile = '@';
if (rv == 0)
@ -83,13 +83,10 @@ void dbus_test(void) {
printf("UGLY: session bus configured for TCP communication.\n");
else
printf("GOOD: cannot find a D-Bus socket\n");
free(bus);
}
else
printf("GOOD: DBUS_SESSION_BUS_ADDRESS environment variable not configured.");
}

View file

@ -26,19 +26,19 @@ void dev_test(void) {
fprintf(stderr, "Error: cannot open /dev directory\n");
return;
}
struct dirent *entry;
printf("INFO: files visible in /dev directory: ");
int cnt = 0;
while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
printf("%s, ", entry->d_name);
cnt++;
}
printf("\n");
if (cnt > 20)
printf("MAYBE: /dev directory seems to be fully populated. Use --private-dev or --whitelist to restrict the access.\n");
else

View file

@ -26,7 +26,7 @@ static char *homedir = NULL;
static void check_home_file(const char *name) {
assert(homedir);
char *fname;
if (asprintf(&fname, "%s/%s", homedir, name) == -1)
errExit("asprintf");
@ -37,7 +37,7 @@ static void check_home_file(const char *name) {
}
else
printf("GOOD: I cannot access files in %s directory.\n", fname);
free(fname);
}
@ -47,14 +47,14 @@ void files_test(void) {
fprintf(stderr, "Error: cannot retrieve user account information\n");
return;
}
username = strdup(pw->pw_name);
if (!username)
errExit("strdup");
homedir = strdup(pw->pw_dir);
if (!homedir)
errExit("strdup");
// check access to .ssh directory
check_home_file(".ssh");
@ -66,10 +66,10 @@ void files_test(void) {
// check access to Chromium browser directory
check_home_file(".config/chromium");
// check access to Debian Icedove directory
check_home_file(".icedove");
// check access to Thunderbird directory
check_home_file(".thunderbird");
}

View file

@ -24,19 +24,19 @@ int main(int argc, char **argv) {
// make test-arguments helper
if (getenv("FIREJAIL_TEST_ARGUMENTS")) {
printf("Arguments:\n");
int i;
for (i = 0; i < argc; i++) {
printf("#%s#\n", argv[i]);
}
return 0;
}
if (argc != 1) {
int i;
for (i = 1; i < argc; i++) {
if (strcmp(argv[i], "syscall")) {
syscall_helper(argc, argv);
@ -56,16 +56,16 @@ int main(int argc, char **argv) {
errExit("strdup");
}
printf("INFO: starting %s.\n", prog);
// check pid namespace
pid_test();
printf("\n");
// check seccomp
seccomp_test();
printf("\n");
// check capabilities
caps_test();
printf("\n");
@ -73,11 +73,11 @@ int main(int argc, char **argv) {
// check some well-known problematic files and directories
files_test();
printf("\n");
// network
network_test();
printf("\n");
// dbus
dbus_test();
printf("\n");

View file

@ -35,15 +35,15 @@ static void check_ssh(void) {
struct sockaddr_in server;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(22);
server.sin_port = htons(22);
if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
printf("GOOD: SSH server not available on localhost.\n");
else {
printf("MAYBE: an SSH server is accessible on localhost. ");
printf("It could be a good idea to create a new network namespace using \"--net=none\" or \"--net=eth0\".\n");
}
close(sock);
}
@ -59,15 +59,15 @@ static void check_http(void) {
struct sockaddr_in server;
server.sin_addr.s_addr = inet_addr("127.0.0.1");
server.sin_family = AF_INET;
server.sin_port = htons(80);
server.sin_port = htons(80);
if (connect(sock , (struct sockaddr *)&server , sizeof(server)) < 0)
printf("GOOD: HTTP server not available on localhost.\n");
else {
printf("MAYBE: an HTTP server is accessible on localhost. ");
printf("It could be a good idea to create a new network namespace using \"--net=none\" or \"--net=eth0\".\n");
}
close(sock);
}
@ -88,12 +88,12 @@ void check_netlink(void) {
close(sock);
return;
}
close(sock);
printf("MAYBE: I can connect to netlink socket. Network utilities such as iproute2 will work fine in the sandbox. ");
printf("You can use \"--protocol\" to disable the socket.\n");
}
void network_test(void) {
check_ssh();
check_http();

View file

@ -32,7 +32,7 @@ void pid_test(void) {
// look at the first 10 processes
int not_visible = 1;
for (i = 1; i <= 10; i++) {
for (i = 1; i <= 10; i++) {
struct stat s;
char *fname;
if (asprintf(&fname, "/proc/%d/comm", i) == -1)
@ -41,7 +41,7 @@ void pid_test(void) {
free(fname);
continue;
}
// open file
/* coverity[toctou] */
FILE *fp = fopen(fname, "r");
@ -49,7 +49,7 @@ void pid_test(void) {
free(fname);
continue;
}
// read file
char buf[100];
if (fgets(buf, 10, fp) == NULL) {
@ -63,7 +63,7 @@ void pid_test(void) {
char *ptr;
if ((ptr = strchr(buf, '\n')) != NULL)
*ptr = '\0';
// check process name against the kernel list
int j = 0;
while (kern_proc[j] != NULL) {
@ -76,7 +76,7 @@ void pid_test(void) {
}
j++;
}
fclose(fp);
free(fname);
}
@ -86,7 +86,7 @@ void pid_test(void) {
printf("BAD: Process %d is not running in a PID namespace.\n", pid);
else
printf("GOOD: process %d is running in a PID namespace.\n", pid);
// try to guess the type of container/sandbox
char *str = getenv("container");
if (str)

View file

@ -24,7 +24,7 @@ static int extract_seccomp(int *val) {
FILE *fp = fopen("/proc/self/status", "r");
if (!fp)
return 1;
char buf[MAXBUF];
while (fgets(buf, MAXBUF, fp)) {
if (strncmp(buf, "Seccomp:\t", 8) == 0) {
@ -44,12 +44,12 @@ static int extract_seccomp(int *val) {
void seccomp_test(void) {
int seccomp_status;
int rv = extract_seccomp(&seccomp_status);
if (rv) {
printf("INFO: cannot extract seccomp configuration on this platform.\n");
return;
}
if (seccomp_status == 0) {
printf("BAD: seccomp disabled. Use \"firejail --seccomp\" to enable it.\n");
}
@ -67,10 +67,10 @@ void seccomp_test(void) {
printf("ptrace... "); fflush(0);
syscall_run("ptrace");
printf("swapon... "); fflush(0);
syscall_run("swapon");
printf("swapoff... "); fflush(0);
syscall_run("swapoff");
@ -79,20 +79,20 @@ void seccomp_test(void) {
printf("delete_module... "); fflush(0);
syscall_run("delete_module");
printf("chroot... "); fflush(0);
syscall_run("chroot");
printf("pivot_root... "); fflush(0);
syscall_run("pivot_root");
#if defined(__i386__) || defined(__x86_64__)
printf("iopl... "); fflush(0);
syscall_run("iopl");
printf("ioperm... "); fflush(0);
syscall_run("ioperm");
#endif
#endif
printf("\n");
}
else

View file

@ -33,7 +33,7 @@ extern int pivot_root(const char *new_root, const char *put_old);
void syscall_helper(int argc, char **argv) {
(void) argc;
if (strcmp(argv[2], "mount") == 0) {
int rv = mount(NULL, NULL, NULL, 0, NULL);
(void) rv;
@ -87,7 +87,7 @@ void syscall_helper(int argc, char **argv) {
void syscall_run(const char *name) {
assert(prog);
pid_t child = fork();
if (child < 0)
errExit("fork");
@ -96,7 +96,7 @@ void syscall_run(const char *name) {
perror("execl");
_exit(1);
}
// wait for the child to finish
waitpid(child, NULL, 0);
}

View file

@ -29,7 +29,7 @@ void x11_test(void) {
if (check_unix("@/tmp/.X11-unix/X0") == 0)
printf("MAYBE: X11 socket @/tmp/.X11-unix/X0 is available\n");
// check all unix sockets in /tmp/.X11-unix directory
DIR *dir;
if (!(dir = opendir("/tmp/.X11-unix"))) {
@ -39,7 +39,7 @@ void x11_test(void) {
;
}
}
if (dir == NULL)
printf("GOOD: cannot open /tmp/.X11-unix directory\n");
else {

View file

@ -42,4 +42,3 @@ clean:; rm -f *.o fcopy *.gcov *.gcda *.gcno
distclean: clean
rm -fr Makefile

View file

@ -37,4 +37,3 @@ clean:; rm -f *.o firecfg firecfg.1 firecfg.1.gz *.gcov *.gcda *.gcno
distclean: clean
rm -fr Makefile

View file

@ -79,7 +79,7 @@ static void sound(void) {
if (!home) {
goto errexit;
}
// the input file is /etc/pulse/client.conf
FILE *fpin = fopen("/etc/pulse/client.conf", "r");
if (!fpin) {
@ -95,18 +95,18 @@ static void sound(void) {
free(fname);
if (!fpout)
goto errexit;
// copy default config
char buf[MAX_BUF];
while (fgets(buf, MAX_BUF, fpin))
fputs(buf, fpout);
// disable shm
fprintf(fpout, "\nenable-shm = no\n");
fclose(fpin);
fclose(fpout);
printf("PulseAudio configured, please logout and login back again\n");
return;
return;
errexit:
fprintf(stderr, "Error: cannot configure sound file\n");
@ -116,18 +116,18 @@ errexit:
// return 1 if the program is found
static int find(const char *program, const char *directory) {
int retval = 0;
char *fname;
if (asprintf(&fname, "/%s/%s", directory, program) == -1)
errExit("asprintf");
struct stat s;
if (stat(fname, &s) == 0) {
if (arg_debug)
printf("found %s in directory %s\n", program, directory);
retval = 1;
}
free(fname);
return retval;
}
@ -140,14 +140,14 @@ static int which(const char *program) {
find(program, "/sbin") || find(program, "/usr/sbin") ||
find(program, "/usr/games"))
return 1;
// check environment
char *path1 = getenv("PATH");
if (path1) {
char *path2 = strdup(path1);
if (!path2)
errExit("strdup");
// use path2 to count the entries
char *ptr = strtok(path2, ":");
while (ptr) {
@ -159,7 +159,7 @@ static int which(const char *program) {
}
free(path2);
}
return 0;
}
@ -193,11 +193,11 @@ static void list(void) {
while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
char *fullname;
if (asprintf(&fullname, "/usr/local/bin/%s", entry->d_name) == -1)
errExit("asprintf");
if (is_link(fullname)) {
char* fname = realpath(fullname, NULL);
if (fname) {
@ -208,7 +208,7 @@ static void list(void) {
}
free(fullname);
}
closedir(dir);
free(firejail_exec);
}
@ -233,11 +233,11 @@ static void clear(void) {
while ((entry = readdir(dir)) != NULL) {
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0)
continue;
char *fullname;
if (asprintf(&fullname, "/usr/local/bin/%s", entry->d_name) == -1)
errExit("asprintf");
if (is_link(fullname)) {
char* fname = realpath(fullname, NULL);
if (fname) {
@ -250,7 +250,7 @@ static void clear(void) {
}
free(fullname);
}
closedir(dir);
free(firejail_exec);
}
@ -262,7 +262,7 @@ static void set_file(const char *name, const char *firejail_exec) {
char *fname;
if (asprintf(&fname, "/usr/local/bin/%s", name) == -1)
errExit("asprintf");
struct stat s;
if (stat(fname, &s) != 0) {
int rv = symlink(firejail_exec, fname);
@ -273,7 +273,7 @@ static void set_file(const char *name, const char *firejail_exec) {
else
printf(" %s created\n", name);
}
free(fname);
}
@ -292,7 +292,7 @@ static void set_links(void) {
exit(1);
}
printf("Configuring symlinks in /usr/local/bin\n");
char buf[MAX_BUF];
int lineno = 0;
while (fgets(buf, MAX_BUF,fp)) {
@ -305,18 +305,18 @@ static void set_links(void) {
fprintf(stderr, "Error: invalid line %d in %s\n", lineno, cfgfile);
exit(1);
}
// remove \n
char *ptr = strchr(buf, '\n');
if (ptr)
*ptr = '\0';
// trim spaces
ptr = buf;
while (*ptr == ' ' || *ptr == '\t')
ptr++;
char *start = ptr;
// empty line
if (*start == '\0')
continue;
@ -334,7 +334,7 @@ int have_profile(const char *filename) {
// remove .desktop extension
char *f1 = strdup(filename);
if (!f1)
errExit("strdup");
errExit("strdup");
f1[strlen(filename) - 8] = '\0';
// build profile name
@ -358,7 +358,7 @@ static void fix_desktop_files(char *homedir) {
fprintf(stderr, "Error: this option is not supported for root user; please run as a regular user.\n");
exit(1);
}
// destination
// create ~/.local/share/applications directory if necessary
char *user_apps_dir;
@ -373,7 +373,7 @@ static void fix_desktop_files(char *homedir) {
}
rv = chmod(user_apps_dir, 0700);
(void) rv;
}
}
// source
DIR *dir = opendir("/usr/share/applications");
@ -527,7 +527,7 @@ static void fix_desktop_files(char *homedir) {
int main(int argc, char **argv) {
int i;
for (i = 1; i < argc; i++) {
// default options
if (strcmp(argv[i], "--help") == 0 ||
@ -572,7 +572,7 @@ int main(int argc, char **argv) {
return 1;
}
}
// set symlinks in /usr/local/bin
if (getuid() != 0) {
fprintf(stderr, "Error: cannot set the symbolic links in /usr/local/bin\n");
@ -615,11 +615,10 @@ int main(int argc, char **argv) {
printf("%s %d %d %d %d\n", user, getuid(), getgid(), geteuid(), getegid());
fix_desktop_files(home);
}
return 0;
errexit:
fprintf(stderr, "Error: cannot detect login user in order to set desktop files in ~/.local/share/applications\n");
return 1;
}

View file

@ -42,4 +42,3 @@ clean:; rm -f *.o firejail firejail.1 firejail.1.gz *.gcov *.gcda *.gcno
distclean: clean
rm -fr Makefile

View file

@ -28,7 +28,7 @@
#include <linux/loop.h>
#include <errno.h>
static char *devloop = NULL; // device file
static char *devloop = NULL; // device file
static char *mntdir = NULL; // mount point in /tmp directory
static void err_loop(void) {
@ -40,7 +40,7 @@ void appimage_set(const char *appimage) {
assert(appimage);
assert(devloop == NULL); // don't call this twice!
EUID_ASSERT();
#ifdef LOOP_CTL_GET_FREE // test for older kernels; this definition is found in /usr/include/linux/loop.h
// check appimage file
invalid_filename(appimage);
@ -74,13 +74,13 @@ void appimage_set(const char *appimage) {
close(cfd);
if (asprintf(&devloop, "/dev/loop%d", devnr) == -1)
errExit("asprintf");
int lfd = open(devloop, O_RDONLY);
if (lfd == -1)
err_loop();
if (ioctl(lfd, LOOP_SET_FD, ffd) == -1)
err_loop();
if (size) {
struct loop_info64 info;
memset(&info, 0, sizeof(struct loop_info64));
@ -88,7 +88,7 @@ void appimage_set(const char *appimage) {
if (ioctl(lfd, LOOP_SET_STATUS64, &info) == -1)
err_loop();
}
close(lfd);
close(ffd);
EUID_USER();
@ -99,13 +99,13 @@ void appimage_set(const char *appimage) {
EUID_ROOT();
mkdir_attr(mntdir, 0700, getuid(), getgid());
EUID_USER();
// mount
char *mode;
if (asprintf(&mode, "mode=700,uid=%d,gid=%d", getuid(), getgid()) == -1)
errExit("asprintf");
EUID_ROOT();
if (size == 0) {
if (mount(devloop, mntdir, "iso9660",MS_MGC_VAL|MS_RDONLY, mode) < 0)
errExit("mounting appimage");
@ -128,7 +128,7 @@ void appimage_set(const char *appimage) {
// build new command line
if (asprintf(&cfg.command_line, "%s/AppRun", mntdir) == -1)
errExit("asprintf");
free(mode);
#ifdef HAVE_GCOV
__gcov_flush();
@ -151,7 +151,7 @@ void appimage_clear(void) {
if (rv == 0) {
if (!arg_quiet)
printf("AppImage unmounted\n");
break;
}
if (rv == -1 && errno == EBUSY) {
@ -159,14 +159,14 @@ void appimage_clear(void) {
sleep(2);
continue;
}
// rv = -1
if (!arg_quiet) {
fwarning("error trying to unmount %s\n", mntdir);
perror("umount");
}
}
if (rv == 0) {
rmdir(mntdir);
free(mntdir);

View file

@ -156,5 +156,3 @@ getout:
close(fd);
return size;
}

View file

@ -49,7 +49,7 @@ arg checking:
- checking no link
- checking no ".."
- unit test
8. --private=dirname
- supported in profiles
- expand "~"
@ -58,7 +58,7 @@ arg checking:
- checking no ".."
- check same owner
- unit test
9. --private-home=filelist
- supported in profiles
- checking no ".."
@ -66,7 +66,7 @@ arg checking:
- checking same owner
- checking no link
- unit test
10. --netfilter=filename
- supported in profiles
- check access as real GID/UID
@ -74,7 +74,7 @@ arg checking:
- checking no link
- checking no ".."
- unit test
11. --shell=filename
- not supported in profiles
- check access as real GID/UID
@ -82,4 +82,3 @@ arg checking:
- checking no link
- checking no ".."
- unit test

View file

@ -47,7 +47,7 @@ int arp_check(const char *dev, uint32_t destaddr, uint32_t srcaddr) {
fprintf(stderr, "Error: invalid network device name %s\n", dev);
exit(1);
}
if (arg_debug)
printf("Trying %d.%d.%d.%d ...\n", PRINT_IP(destaddr));
@ -66,7 +66,7 @@ int arp_check(const char *dev, uint32_t destaddr, uint32_t srcaddr) {
if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0)
errExit("ioctl");
close(sock);
// configure layer2 socket address information
struct sockaddr_ll addr;
memset(&addr, 0, sizeof(addr));
@ -105,7 +105,7 @@ int arp_check(const char *dev, uint32_t destaddr, uint32_t srcaddr) {
if ((len = sendto (sock, frame, 14 + sizeof(ArpHdr), 0, (struct sockaddr *) &addr, sizeof (addr))) <= 0)
errExit("send");
fflush(0);
// wait not more than one second for an answer
fd_set fds;
FD_ZERO(&fds);
@ -130,7 +130,7 @@ int arp_check(const char *dev, uint32_t destaddr, uint32_t srcaddr) {
close(sock);
return -1;
}
// parse the incoming packet
if ((unsigned int) len < 14 + sizeof(ArpHdr))
continue;
@ -147,7 +147,7 @@ int arp_check(const char *dev, uint32_t destaddr, uint32_t srcaddr) {
memcpy(&ip, hdr.target_ip, 4);
if (ip != srcaddr) {
continue;
}
}
close(sock);
return -1;
}
@ -180,13 +180,13 @@ static uint32_t arp_random(const char *dev, Bridge *br) {
return 0; // the user will have to set the IP address manually
range -= 2; // subtract the network address and the broadcast address
uint32_t start = (ifip & ifmask) + 1;
// adjust range based on --iprange params
if (br->iprange_start && br->iprange_end) {
start = br->iprange_start;
range = br->iprange_end - br->iprange_start;
}
if (arg_debug)
printf("IP address range from %d.%d.%d.%d to %d.%d.%d.%d\n",
PRINT_IP(start), PRINT_IP(start + range));
@ -198,13 +198,13 @@ static uint32_t arp_random(const char *dev, Bridge *br) {
dest = start + ((uint32_t) rand()) % range;
if (dest == ifip) // do not allow the interface address
continue; // try again
// if we've made it up to here, we have a valid address
break;
}
if (i == 10) // we failed 10 times
return 0;
// check address
uint32_t rv = arp_check(dev, dest, ifip);
if (!rv)
@ -237,7 +237,7 @@ static uint32_t arp_sequential(const char *dev, Bridge *br) {
uint32_t last = dest + range - 1;
if (br->iprange_end)
last = br->iprange_end;
if (arg_debug)
printf("Trying IP address range from %d.%d.%d.%d to %d.%d.%d.%d\n",
PRINT_IP(dest), PRINT_IP(last));
@ -272,19 +272,17 @@ uint32_t arp_assign(const char *dev, Bridge *br) {
ip = arp_random(dev, br);
if (!ip)
ip = arp_random(dev, br);
// try all possible IP addresses one by one
if (!ip)
ip = arp_sequential(dev, br);
// print result
if (!ip) {
fprintf(stderr, "Error: cannot assign an IP address; it looks like all of them are in use.\n");
logerr("Cannot assign an IP address; it looks like all of them are in use.");
exit(1);
}
return ip;
}

View file

@ -58,30 +58,30 @@ IFBW *ifbw_find(const char *dev) {
assert(dev);
int len = strlen(dev);
assert(len);
if (ifbw == NULL)
return NULL;
IFBW *ptr = ifbw;
while (ptr) {
if (strncmp(ptr->txt, dev, len) == 0 && ptr->txt[len] == ':')
return ptr;
ptr = ptr->next;
}
return NULL;
}
void ifbw_remove(IFBW *r) {
if (ifbw == NULL)
return;
// remove the first element
if (ifbw == r) {
ifbw = ifbw->next;
return;
}
// walk the list
IFBW *ptr = ifbw->next;
IFBW *prev = ifbw;
@ -90,11 +90,11 @@ void ifbw_remove(IFBW *r) {
prev->next = ptr->next;
return;
}
prev = ptr;
ptr = ptr->next;
}
}
return;
}
@ -106,10 +106,10 @@ int fibw_count(void) {
rv++;
ptr = ptr->next;
}
return rv;
}
//***********************************
// run file handling
@ -118,7 +118,7 @@ static void bandwidth_create_run_file(pid_t pid) {
char *fname;
if (asprintf(&fname, "%s/%d-bandwidth", RUN_FIREJAIL_BANDWIDTH_DIR, (int) pid) == -1)
errExit("asprintf");
// if the file already exists, do nothing
struct stat s;
if (stat(fname, &s) == 0) {
@ -137,7 +137,7 @@ static void bandwidth_create_run_file(pid_t pid) {
fprintf(stderr, "Error: cannot create bandwidth file\n");
exit(1);
}
free(fname);
}
@ -162,7 +162,7 @@ void network_set_run_file(pid_t pid) {
char *fname;
if (asprintf(&fname, "%s/%d-netmap", RUN_FIREJAIL_NETWORK_DIR, (int) pid) == -1)
errExit("asprintf");
// create an empty file and set mod and ownership
FILE *fp = fopen(fname, "w");
if (fp) {
@ -182,7 +182,7 @@ void network_set_run_file(pid_t pid) {
fprintf(stderr, "Error: cannot create network map file\n");
exit(1);
}
free(fname);
}
@ -204,7 +204,7 @@ static void read_bandwidth_file(pid_t pid) {
*ptr = '\0';
if (strlen(buf) == 0)
continue;
// create a new IFBW entry
IFBW *ifbw_new = malloc(sizeof(IFBW));
if (!ifbw_new)
@ -213,12 +213,12 @@ static void read_bandwidth_file(pid_t pid) {
ifbw_new->txt = strdup(buf);
if (!ifbw_new->txt)
errExit("strdup");
// add it to the linked list
ifbw_add(ifbw_new);
}
fclose(fp);
}
fclose(fp);
}
}
@ -256,17 +256,17 @@ errout:
// remove interface from run file
void bandwidth_remove(pid_t pid, const char *dev) {
bandwidth_create_run_file(pid);
// read bandwidth file
read_bandwidth_file(pid);
// find the element and remove it
IFBW *elem = ifbw_find(dev);
if (elem) {
ifbw_remove(elem);
write_bandwidth_file(pid) ;
}
// remove the file if there are no entries in the list
if (ifbw == NULL) {
bandwidth_del_run_file(pid);
@ -282,7 +282,7 @@ void bandwidth_set(pid_t pid, const char *dev, int down, int up) {
char *txt;
if (asprintf(&txt, "%s: RX %dKB/s, TX %dKB/s", dev, down, up) == -1)
errExit("asprintf");
// read bandwidth file
read_bandwidth_file(pid);
@ -300,7 +300,7 @@ void bandwidth_set(pid_t pid, const char *dev, int down, int up) {
errExit("malloc");
memset(ifbw_new, 0, sizeof(IFBW));
ifbw_new->txt = txt;
// add it to the linked list
ifbw_add(ifbw_new);
}
@ -330,7 +330,7 @@ void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, in
exit(1);
}
free(comm);
// check network namespace
char *name;
if (asprintf(&name, "/run/firejail/network/%d-netmap", pid) == -1)
@ -376,7 +376,7 @@ void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, in
fprintf(stderr, "Error: cannot read network map file %s\n", fname);
exit(1);
}
char buf[1024];
int len = strlen(dev);
while (fgets(buf, 1024, fp)) {
@ -402,7 +402,7 @@ void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, in
free(fname);
fclose(fp);
}
// build fshaper.sh command
char *cmd = NULL;
if (devname) {
@ -442,7 +442,7 @@ void bandwidth_pid(pid_t pid, const char *command, const char *dev, int down, in
arg[3] = NULL;
clearenv();
execvp(arg[0], arg);
// it will never get here
errExit("execvp");
}

View file

@ -154,12 +154,12 @@ static CapsEntry capslist[] = {
// not in Debian 7
#ifdef CAP_BLOCK_SUSPEND
{"block_suspend", CAP_BLOCK_SUSPEND },
#else
#else
{"block_suspend", 36 },
#endif
#ifdef CAP_AUDIT_READ
{"audit_read", CAP_AUDIT_READ },
#else
#else
{"audit_read", 37 },
#endif
@ -176,7 +176,7 @@ static int caps_find_name(const char *name) {
if (strcmp(name, capslist[i].name) == 0)
return capslist[i].nr;
}
return -1;
}
@ -205,32 +205,32 @@ void caps_check_list(const char *clist, void (*callback)(int)) {
goto errexit;
else if (callback != NULL)
callback(nr);
start = ptr + 1;
}
ptr++;
}
if (*start != '\0') {
int nr = caps_find_name(start);
if (nr == -1)
if (nr == -1)
goto errexit;
else if (callback != NULL)
callback(nr);
}
free(str);
free(str);
return;
errexit:
fprintf(stderr, "Error: capability \"%s\" not found\n", start);
exit(1);
exit(1);
}
void caps_print(void) {
EUID_ASSERT();
int i;
int elems = sizeof(capslist) / sizeof(capslist[0]);
// check current caps supported by the kernel
int cnt = 0;
unsigned long cap;
@ -242,7 +242,7 @@ void caps_print(void) {
}
EUID_USER();
printf("Your kernel supports %d capabilities.\n", cnt);
for (i = 0; i < elems; i++) {
printf("%d\t- %s\n", capslist[i].nr, capslist[i].name);
}
@ -300,7 +300,7 @@ int caps_default_filter(void) {
errexit:
fprintf(stderr, "Error: cannot drop capabilities\n");
exit(1);
exit(1);
}
void caps_drop_all(void) {
@ -359,7 +359,7 @@ void caps_keep_list(const char *clist) {
#define MAXBUF 4098
static uint64_t extract_caps(int pid) {
EUID_ASSERT();
char *file;
if (asprintf(&file, "/proc/%d/status", pid) == -1)
errExit("asprintf");
@ -369,7 +369,7 @@ static uint64_t extract_caps(int pid) {
EUID_USER(); // grsecurity
if (!fp)
goto errexit;
char buf[MAXBUF];
while (fgets(buf, MAXBUF, fp)) {
if (strncmp(buf, "CapBnd:\t", 8) == 0) {
@ -383,7 +383,7 @@ static uint64_t extract_caps(int pid) {
}
fclose(fp);
errexit:
errexit:
free(file);
fprintf(stderr, "Error: cannot read caps configuration\n");
exit(1);
@ -391,7 +391,7 @@ errexit:
void caps_print_filter(pid_t pid) {
EUID_ASSERT();
// if the pid is that of a firejail process, use the pid of the first child process
EUID_ROOT(); // grsecurity
char *comm = pid_proc_comm(pid);

View file

@ -25,7 +25,7 @@
void save_cgroup(void) {
if (cfg.cgroup == NULL)
return;
FILE *fp = fopen(RUN_CGROUP_CFG, "w");
if (fp) {
fprintf(fp, "%s", cfg.cgroup);
@ -36,7 +36,7 @@ void save_cgroup(void) {
}
else
goto errout;
return;
errout:
@ -58,7 +58,7 @@ void load_cgroup(const char *fname) {
}
else
goto errout;
fclose(fp);
return;
}
@ -71,34 +71,34 @@ errout:
void set_cgroup(const char *path) {
EUID_ASSERT();
invalid_filename(path);
// path starts with /sys/fs/cgroup
if (strncmp(path, "/sys/fs/cgroup", 14) != 0)
goto errout;
// path ends in tasks
char *ptr = strstr(path, "tasks");
if (!ptr)
goto errout;
if (*(ptr + 5) != '\0')
goto errout;
// no .. traversal
ptr = strstr(path, "..");
if (ptr)
goto errout;
// tasks file exists
struct stat s;
if (stat(path, &s) == -1)
goto errout;
// task file belongs to the user running the sandbox
if (s.st_uid != getuid() && s.st_gid != getgid())
goto errout2;
// add the task to cgroup
/* coverity[toctou] */
FILE *fp = fopen(path, "a");
@ -110,10 +110,10 @@ void set_cgroup(const char *path) {
fclose(fp);
return;
errout:
errout:
fprintf(stderr, "Error: invalid cgroup\n");
exit(1);
errout2:
errout2:
fprintf(stderr, "Error: you don't have permissions to use this control group\n");
exit(1);
}

View file

@ -49,33 +49,33 @@ int checkcfg(int val) {
cfg_val[CFG_FIREJAIL_PROMPT] = 0;
cfg_val[CFG_FOLLOW_SYMLINK_PRIVATE_BIN] = 0;
cfg_val[CFG_DISABLE_MNT] = 0;
// open configuration file
const char *fname = SYSCONFDIR "/firejail.config";
fp = fopen(fname, "r");
if (!fp) {
#ifdef HAVE_GLOBALCFG
#ifdef HAVE_GLOBALCFG
fprintf(stderr, "Error: Firejail configuration file %s not found\n", fname);
exit(1);
#else
initialized = 1;
return cfg_val[val];
#endif
#endif
}
// read configuration file
char buf[MAX_READ];
while (fgets(buf,MAX_READ, fp)) {
line++;
if (*buf == '#' || *buf == '\n')
if (*buf == '#' || *buf == '\n')
continue;
// parse line
// parse line
ptr = line_remove_spaces(buf);
if (!ptr)
continue;
// file transfer
// file transfer
else if (strncmp(ptr, "file-transfer ", 14) == 0) {
if (strcmp(ptr + 14, "yes") == 0)
cfg_val[CFG_FILE_TRANSFER] = 1;
@ -209,14 +209,14 @@ int checkcfg(int val) {
char *end = strchr(fname, ' ');
if (end)
*end = '\0';
// is the file present?
struct stat s;
if (stat(fname, &s) == -1) {
fprintf(stderr, "Error: netfilter-default file %s not available\n", fname);
exit(1);
}
if (netfilter_default)
goto errout;
netfilter_default = strdup(fname);
@ -225,7 +225,7 @@ int checkcfg(int val) {
if (arg_debug)
printf("netfilter default file %s\n", fname);
}
// Xephyr screen size
else if (strncmp(ptr, "xephyr-screen ", 14) == 0) {
// expecting two numbers and an x between them
@ -237,7 +237,7 @@ int checkcfg(int val) {
if (asprintf(&xephyr_screen, "%dx%d", n1, n2) == -1)
errExit("asprintf");
}
// xephyr window title
else if (strncmp(ptr, "xephyr-window-title ", 20) == 0) {
if (strcmp(ptr + 20, "yes") == 0)
@ -247,7 +247,7 @@ int checkcfg(int val) {
else
goto errout;
}
// Xephyr command extra parameters
else if (strncmp(ptr, "xephyr-extra-params ", 20) == 0) {
if (*xephyr_extra_params != '\0')
@ -256,7 +256,7 @@ int checkcfg(int val) {
if (!xephyr_extra_params)
errExit("strdup");
}
// xpra server extra parameters
else if (strncmp(ptr, "xpra-extra-params ", 18) == 0) {
if (*xpra_extra_params != '\0')
@ -287,7 +287,7 @@ int checkcfg(int val) {
if (!xvfb_extra_params)
errExit("strdup");
}
// quiet by default
else if (strncmp(ptr, "quiet-by-default ", 17) == 0) {
if (strcmp(ptr + 17, "yes") == 0)
@ -355,9 +355,9 @@ int checkcfg(int val) {
fclose(fp);
initialized = 1;
}
return cfg_val[val];
errout:
assert(ptr);
free(ptr);
@ -477,5 +477,5 @@ void print_compiletime_support(void) {
"disabled"
#endif
);
}

View file

@ -28,7 +28,7 @@
static int cmdline_length(int argc, char **argv, int index) {
assert(index != -1);
unsigned i,j;
int len = 0;
unsigned argcnt = argc - index;
@ -91,7 +91,7 @@ static void quote_cmdline(char *command_line, char *window_title, int len, int a
if (j > 0 && argv[i + index][j-1] == '\'') {
ptr1--;
sprintf(ptr1, "\'\"");
}
}
// this first in series
else
{
@ -151,9 +151,9 @@ void build_cmdline(char **command_line, char **window_title, int argc, char **ar
*window_title = malloc(len + 1);
if (!*window_title)
errExit("malloc");
quote_cmdline(*command_line, *window_title, len, argc, argv, index);
if (arg_debug)
printf("Building quoted command line: %s\n", *command_line);

View file

@ -26,13 +26,13 @@
static void set_cpu(const char *str) {
if (strlen(str) == 0)
return;
int val = atoi(str);
if (val < 0 || val >= 32) {
fprintf(stderr, "Error: invalid cpu number. Accepted values are between 0 and 31.\n");
exit(1);
}
uint32_t mask = 1;
int i;
for (i = 0; i < val; i++, mask <<= 1);
@ -41,11 +41,11 @@ static void set_cpu(const char *str) {
void read_cpu_list(const char *str) {
EUID_ASSERT();
char *tmp = strdup(str);
if (tmp == NULL)
errExit("strdup");
char *ptr = tmp;
while (*ptr != '\0') {
if (*ptr == ',' || isdigit(*ptr))
@ -56,7 +56,7 @@ void read_cpu_list(const char *str) {
}
ptr++;
}
char *start = tmp;
ptr = tmp;
while (*ptr != '\0') {
@ -107,17 +107,17 @@ void set_cpu_affinity(void) {
// set cpu affinity
cpu_set_t mask;
CPU_ZERO(&mask);
int i;
uint32_t m = 1;
for (i = 0; i < 32; i++, m <<= 1) {
if (cfg.cpus & m)
CPU_SET(i, &mask);
}
if (sched_setaffinity(0, sizeof(mask), &mask) == -1)
fwarning("cannot set cpu affinity\n");
// verify cpu affinity
cpu_set_t mask2;
CPU_ZERO(&mask2);
@ -147,7 +147,7 @@ static void print_cpu(int pid) {
return;
}
#define MAXBUF 4096
#define MAXBUF 4096
char buf[MAXBUF];
while (fgets(buf, MAXBUF, fp)) {
if (strncmp(buf, "Cpus_allowed_list:", 18) == 0) {
@ -164,7 +164,7 @@ static void print_cpu(int pid) {
void cpu_print_filter(pid_t pid) {
EUID_ASSERT();
// if the pid is that of a firejail process, use the pid of the first child process
EUID_ROOT(); // grsecurity
char *comm = pid_proc_comm(pid);
@ -192,4 +192,3 @@ void cpu_print_filter(pid_t pid) {
print_cpu(pid);
exit(0);
}

View file

@ -33,13 +33,13 @@ static Env *envlist = NULL;
static void env_add(Env *env) {
env->next = NULL;
// add the new entry at the end of the list
if (envlist == NULL) {
envlist = env;
return;
}
Env *ptr = envlist;
while (1) {
if (ptr->next == NULL) {
@ -77,7 +77,7 @@ void env_ibus_load(void) {
continue;
if (strlen(ptr) != 6)
continue;
// open the file
char *fname;
if (asprintf(&fname, "%s/%s", dirname, entry->d_name) == -1)
@ -86,7 +86,7 @@ void env_ibus_load(void) {
free(fname);
if (!fp)
continue;
// read the file
const int maxline = 4096;
char buf[maxline];
@ -137,24 +137,24 @@ void env_defaults(void) {
if (prompt && strcmp(prompt, "yes") == 0)
set_prompt = 1;
}
if (set_prompt) {
//export PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] '
if (setenv("PROMPT_COMMAND", "export PS1=\"\\[\\e[1;32m\\][\\u@\\h \\W]\\$\\[\\e[0m\\] \"", 1) < 0)
errExit("setenv");
}
// set the window title
if (!arg_quiet)
printf("\033]0;firejail %s\007", cfg.window_title);
fflush(0);
}
// parse and store the environment setting
// parse and store the environment setting
void env_store(const char *str, ENV_OP op) {
EUID_ASSERT();
assert(str);
// some basic checking
if (*str == '\0')
goto errexit;
@ -182,11 +182,11 @@ void env_store(const char *str, ENV_OP op) {
env->value = ptr2 + 1;
}
env->op = op;
// add entry to the list
env_add(env);
return;
errexit:
fprintf(stderr, "Error: invalid --env setting\n");
exit(1);
@ -195,7 +195,7 @@ errexit:
// set env variables in the new sandbox process
void env_apply(void) {
Env *env = envlist;
while (env) {
if (env->op == SETENV) {
if (setenv(env->name, env->value, 1) < 0)

View file

@ -55,7 +55,7 @@ static void disable_file(OPERATION op, const char *filename) {
assert(filename);
assert(op <OPERATION_MAX);
last_disable = UNSUCCESSFUL;
// Resolve all symlinks
char* fname = realpath(filename, NULL);
if (fname == NULL && errno != EACCES) {
@ -87,10 +87,10 @@ static void disable_file(OPERATION op, const char *filename) {
if (arg_debug)
printf("Warning (blacklisting): %s is an invalid file, skipping...\n", filename);
}
return;
}
// if the file is not present, do nothing
struct stat s;
if (fname == NULL)
@ -124,7 +124,7 @@ static void disable_file(OPERATION op, const char *filename) {
else
printf(" - no logging\n");
}
if (S_ISDIR(s.st_mode)) {
if (mount(RUN_RO_DIR, fname, "none", MS_BIND, "mode=400,gid=0") < 0)
errExit("disable file");
@ -243,7 +243,7 @@ void fs_blacklist(void) {
ProfileEntry *entry = cfg.profile;
if (!entry)
return;
size_t noblacklist_c = 0;
size_t noblacklist_m = 32;
char **noblacklist = calloc(noblacklist_m, sizeof(*noblacklist));
@ -256,7 +256,7 @@ void fs_blacklist(void) {
char *ptr;
// whitelist commands handled by fs_whitelist()
if (strncmp(entry->data, "whitelist ", 10) == 0 ||
if (strncmp(entry->data, "whitelist ", 10) == 0 ||
strncmp(entry->data, "nowhitelist ", 12) == 0 ||
*entry->data == '\0') {
entry = entry->next;
@ -275,7 +275,7 @@ void fs_blacklist(void) {
entry = entry->next;
continue;
}
// mount --bind olddir newdir
if (arg_debug)
printf("Mount-bind %s on top of %s\n", dname1, dname2);
@ -284,8 +284,8 @@ void fs_blacklist(void) {
errExit("mount bind");
/* coverity[toctou] */
if (set_perms(dname2, s.st_uid, s.st_gid,s.st_mode))
errExit("set_perms");
errExit("set_perms");
entry = entry->next;
continue;
}
@ -348,33 +348,33 @@ void fs_blacklist(void) {
else if (strncmp(entry->data, "read-only ", 10) == 0) {
ptr = entry->data + 10;
op = MOUNT_READONLY;
}
}
else if (strncmp(entry->data, "read-write ", 11) == 0) {
ptr = entry->data + 11;
op = MOUNT_RDWR;
}
}
else if (strncmp(entry->data, "noexec ", 7) == 0) {
ptr = entry->data + 7;
op = MOUNT_NOEXEC;
}
}
else if (strncmp(entry->data, "tmpfs ", 6) == 0) {
ptr = entry->data + 6;
op = MOUNT_TMPFS;
}
}
else if (strncmp(entry->data, "mkdir ", 6) == 0) {
EUID_USER();
fs_mkdir(entry->data + 6);
EUID_ROOT();
entry = entry->next;
continue;
}
}
else if (strncmp(entry->data, "mkfile ", 7) == 0) {
EUID_USER();
fs_mkfile(entry->data + 7);
EUID_ROOT();
entry = entry->next;
continue;
}
}
else {
fprintf(stderr, "Error: invalid profile line %s\n", entry->data);
entry = entry->next;
@ -446,10 +446,10 @@ static void fs_rdwr(const char *dir) {
fwarning("you are not allowed to change %s to read-write\n", dir);
return;
}
// mount --bind /bin /bin
// mount --bind -o remount,rw /bin
if (mount(dir, dir, NULL, MS_BIND|MS_REC, NULL) < 0 ||
if (mount(dir, dir, NULL, MS_BIND|MS_REC, NULL) < 0 ||
mount(NULL, dir, NULL, MS_BIND|MS_REMOUNT|MS_REC, NULL) < 0)
errExit("mount read-write");
fs_logger2("read-write", dir);
@ -464,7 +464,7 @@ void fs_noexec(const char *dir) {
if (rv == 0) {
// mount --bind /bin /bin
// mount --bind -o remount,ro /bin
if (mount(dir, dir, NULL, MS_BIND|MS_REC, NULL) < 0 ||
if (mount(dir, dir, NULL, MS_BIND|MS_REC, NULL) < 0 ||
mount(NULL, dir, NULL, MS_BIND|MS_REMOUNT|MS_NOEXEC|MS_NODEV|MS_NOSUID|MS_REC, NULL) < 0)
errExit("mount noexec");
fs_logger2("noexec", dir);
@ -504,11 +504,11 @@ void fs_proc_sys_dev_boot(void) {
fwarning("failed to mount /sys\n");
else
fs_logger("remount /sys");
disable_file(BLACKLIST_FILE, "/sys/firmware");
disable_file(BLACKLIST_FILE, "/sys/hypervisor");
{ // allow user access to /sys/fs if "--noblacklist=/sys/fs" is present on the command line
EUID_USER();
EUID_USER();
profile_add("blacklist /sys/fs");
EUID_ROOT();
}
@ -519,11 +519,11 @@ void fs_proc_sys_dev_boot(void) {
disable_file(BLACKLIST_FILE, "/sys/kernel/uevent_helper");
// various /proc/sys files
disable_file(BLACKLIST_FILE, "/proc/sys/security");
disable_file(BLACKLIST_FILE, "/proc/sys/efi/vars");
disable_file(BLACKLIST_FILE, "/proc/sys/fs/binfmt_misc");
disable_file(BLACKLIST_FILE, "/proc/sys/kernel/core_pattern");
disable_file(BLACKLIST_FILE, "/proc/sys/kernel/modprobe");
disable_file(BLACKLIST_FILE, "/proc/sys/security");
disable_file(BLACKLIST_FILE, "/proc/sys/efi/vars");
disable_file(BLACKLIST_FILE, "/proc/sys/fs/binfmt_misc");
disable_file(BLACKLIST_FILE, "/proc/sys/kernel/core_pattern");
disable_file(BLACKLIST_FILE, "/proc/sys/kernel/modprobe");
disable_file(BLACKLIST_FILE, "/proc/sysrq-trigger");
disable_file(BLACKLIST_FILE, "/proc/sys/kernel/hotplug");
disable_file(BLACKLIST_FILE, "/proc/sys/vm/panic_on_oom");
@ -531,15 +531,15 @@ void fs_proc_sys_dev_boot(void) {
// various /proc files
disable_file(BLACKLIST_FILE, "/proc/irq");
disable_file(BLACKLIST_FILE, "/proc/bus");
disable_file(BLACKLIST_FILE, "/proc/config.gz");
disable_file(BLACKLIST_FILE, "/proc/sched_debug");
disable_file(BLACKLIST_FILE, "/proc/timer_list");
disable_file(BLACKLIST_FILE, "/proc/timer_stats");
disable_file(BLACKLIST_FILE, "/proc/config.gz");
disable_file(BLACKLIST_FILE, "/proc/sched_debug");
disable_file(BLACKLIST_FILE, "/proc/timer_list");
disable_file(BLACKLIST_FILE, "/proc/timer_stats");
disable_file(BLACKLIST_FILE, "/proc/kcore");
disable_file(BLACKLIST_FILE, "/proc/kallsyms");
disable_file(BLACKLIST_FILE, "/proc/mem");
disable_file(BLACKLIST_FILE, "/proc/kmem");
// remove kernel symbol information
if (!arg_allow_debuggers) {
disable_file(BLACKLIST_FILE, "/usr/src/linux");
@ -547,18 +547,18 @@ void fs_proc_sys_dev_boot(void) {
disable_file(BLACKLIST_FILE, "/usr/lib/debug");
disable_file(BLACKLIST_FILE, "/boot");
}
// disable /selinux
disable_file(BLACKLIST_FILE, "/selinux");
// disable /dev/port
disable_file(BLACKLIST_FILE, "/dev/port");
// disable various ipc sockets in /run/user
struct stat s;
struct stat s;
char *fname;
if (asprintf(&fname, "/run/usr/%d", getuid()) == -1)
errExit("asprintf");
@ -567,24 +567,24 @@ void fs_proc_sys_dev_boot(void) {
char *fnamegpg;
if (asprintf(&fnamegpg, "/run/user/%d/gnupg", getuid()) == -1)
errExit("asprintf");
if (stat(fnamegpg, &s) == -1)
if (stat(fnamegpg, &s) == -1)
mkdir_attr(fnamegpg, 0700, getuid(), getgid());
if (stat(fnamegpg, &s) == 0)
disable_file(BLACKLIST_FILE, fnamegpg);
free(fnamegpg);
// disable /run/user/{uid}/systemd
char *fnamesysd;
if (asprintf(&fnamesysd, "/run/user/%d/systemd", getuid()) == -1)
errExit("asprintf");
if (stat(fnamesysd, &s) == -1)
if (stat(fnamesysd, &s) == -1)
mkdir_attr(fnamesysd, 0755, getuid(), getgid());
if (stat(fnamesysd, &s) == 0)
disable_file(BLACKLIST_FILE, fnamesysd);
free(fnamesysd);
}
free(fname);
if (getuid() != 0) {
// disable /dev/kmsg and /proc/kmsg
disable_file(BLACKLIST_FILE, "/dev/kmsg");
@ -602,7 +602,7 @@ static void disable_config(void) {
if (stat(fname, &s) == 0)
disable_file(BLACKLIST_FILE, fname);
free(fname);
// disable run time information
if (stat(RUN_FIREJAIL_NETWORK_DIR, &s) == 0)
disable_file(BLACKLIST_FILE, RUN_FIREJAIL_NETWORK_DIR);
@ -618,7 +618,7 @@ static void disable_config(void) {
// build a basic read-only filesystem
void fs_basic_fs(void) {
uid_t uid = getuid();
if (arg_debug)
printf("Mounting read-only /bin, /sbin, /lib, /lib32, /lib64, /usr");
if (!arg_writable_etc) {
@ -649,15 +649,15 @@ void fs_basic_fs(void) {
fs_var_log();
else
fs_rdwr("/var/log");
fs_var_lib();
fs_var_cache();
fs_var_utmp();
fs_machineid();
// don't leak user information
restrict_users();
// when starting as root, firejail config is not disabled;
// this mode could be used to install and test new software by chaining
// firejail sandboxes (firejail --force)
@ -675,7 +675,7 @@ char *fs_check_overlay_dir(const char *subdirname, int allow_reuse) {
// create ~/.firejail directory
if (asprintf(&dirname, "%s/.firejail", cfg.homedir) == -1)
errExit("asprintf");
if (is_link(dirname)) {
fprintf(stderr, "Error: invalid ~/.firejail directory\n");
exit(1);
@ -688,7 +688,7 @@ char *fs_check_overlay_dir(const char *subdirname, int allow_reuse) {
if (child == 0) {
// drop privileges
drop_privs(0);
// create directory
if (mkdir(dirname, 0700))
errExit("mkdir");
@ -770,7 +770,7 @@ void fs_overlayfs(void) {
fprintf(stderr, "Error: cannot extract Linux kernel version: %s\n", u.version);
exit(1);
}
if (arg_debug)
printf("Linux kernel version %d.%d\n", major, minor);
int oldkernel = 0;
@ -780,7 +780,7 @@ void fs_overlayfs(void) {
}
if (major == 3 && minor < 18)
oldkernel = 1;
char *oroot;
if(asprintf(&oroot, "%s/oroot", RUN_MNT_DIR) == -1)
errExit("asprintf");
@ -818,7 +818,7 @@ void fs_overlayfs(void) {
}
else if (set_perms(odiff, 0, 0, 0755))
errExit("set_perms");
char *owork;
if(asprintf(&owork, "%s/owork", basedir) == -1)
errExit("asprintf");
@ -829,7 +829,7 @@ void fs_overlayfs(void) {
}
else if (set_perms(owork, 0, 0, 0755))
errExit("chown");
// mount overlayfs
if (arg_debug)
printf("Mounting OverlayFS\n");
@ -849,11 +849,11 @@ void fs_overlayfs(void) {
errExit("asprintf");
if (mount("overlay", oroot, "overlay", MS_MGC_VAL, option) < 0)
errExit("mounting overlayfs");
//***************************
// issue #263 start code
// My setup has a separate mount point for /home. When the overlay is mounted,
// the overlay does not contain the original /home contents.
// the overlay does not contain the original /home contents.
// I added code to create a second overlay for /home if the overlay home dir is empty and this seems to work
// @dshmgh, Jan 2016
{
@ -862,22 +862,22 @@ void fs_overlayfs(void) {
char *hroot;
char *hdiff;
char *hwork;
// dons add debug
if (arg_debug) printf ("DEBUG: chroot dirs are oroot %s odiff %s owork %s\n",oroot,odiff,owork);
// BEFORE NEXT, WE NEED TO TEST IF /home has any contents or do we need to mount it?
// must create var for oroot/cfg.homedir
if (asprintf(&overlayhome,"%s%s",oroot,cfg.homedir) == -1)
errExit("asprintf");
if (arg_debug) printf ("DEBUG: overlayhome var holds ##%s##\n",overlayhome);
// if no homedir in overlay -- create another overlay for /home
if (stat(overlayhome, &s) == -1) {
if(asprintf(&hroot, "%s/oroot/home", RUN_MNT_DIR) == -1)
errExit("asprintf");
if(asprintf(&hdiff, "%s/hdiff", basedir) == -1)
errExit("asprintf");
@ -887,7 +887,7 @@ void fs_overlayfs(void) {
}
else if (set_perms(hdiff, 0, 0, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH))
errExit("set_perms");
if(asprintf(&hwork, "%s/hwork", basedir) == -1)
errExit("asprintf");
@ -897,13 +897,13 @@ void fs_overlayfs(void) {
}
else if (set_perms(hwork, 0, 0, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH))
errExit("set_perms");
// no homedir in overlay so now mount another overlay for /home
if (asprintf(&option, "lowerdir=/home,upperdir=%s,workdir=%s", hdiff, hwork) == -1)
errExit("asprintf");
if (mount("overlay", hroot, "overlay", MS_MGC_VAL, option) < 0)
errExit("mounting overlayfs for mounted home directory");
printf("OverlayFS for /home configured in %s directory\n", basedir);
} // stat(overlayhome)
free(overlayhome);
@ -913,7 +913,7 @@ void fs_overlayfs(void) {
}
if (!arg_quiet)
printf("OverlayFS configured in %s directory\n", basedir);
// mount-bind dev directory
if (arg_debug)
printf("Mounting /dev\n");
@ -964,7 +964,7 @@ void fs_overlayfs(void) {
fs_var_log();
else
fs_rdwr("/var/log");
fs_var_lib();
fs_var_cache();
fs_var_utmp();
@ -987,7 +987,7 @@ void fs_overlayfs(void) {
#endif
#ifdef HAVE_CHROOT
#ifdef HAVE_CHROOT
// return 1 if error
void fs_check_chroot_dir(const char *rootdir) {
EUID_ASSERT();
@ -1035,7 +1035,7 @@ void fs_check_chroot_dir(const char *rootdir) {
exit(1);
}
free(name);
// check /proc
if (asprintf(&name, "%s/proc", rootdir) == -1)
errExit("asprintf");
@ -1048,7 +1048,7 @@ void fs_check_chroot_dir(const char *rootdir) {
exit(1);
}
free(name);
// check /tmp
if (asprintf(&name, "%s/tmp", rootdir) == -1)
errExit("asprintf");
@ -1110,7 +1110,7 @@ void fs_check_chroot_dir(const char *rootdir) {
// chroot into an existing directory; mount exiting /dev and update /etc/resolv.conf
void fs_chroot(const char *rootdir) {
assert(rootdir);
if (checkcfg(CFG_CHROOT_DESKTOP)) {
// mount-bind a /dev in rootdir
char *newdev;
@ -1121,7 +1121,7 @@ void fs_chroot(const char *rootdir) {
if (mount("/dev", newdev, NULL, MS_BIND|MS_REC, NULL) < 0)
errExit("mounting /dev");
free(newdev);
// x11
if (getenv("FIREJAIL_X11")) {
char *newx11;
@ -1133,7 +1133,7 @@ void fs_chroot(const char *rootdir) {
errExit("mounting /tmp/.X11-unix");
free(newx11);
}
// some older distros don't have a /run directory
// create one by default
// create /run/firejail directory in chroot
@ -1150,7 +1150,7 @@ void fs_chroot(const char *rootdir) {
errExit("asprintf");
create_empty_dir_as_root(rundir, 0755);
free(rundir);
// create /run/firejail/mnt directory in chroot and mount the current one
if (asprintf(&rundir, "%s%s", rootdir, RUN_MNT_DIR) == -1)
errExit("asprintf");
@ -1173,7 +1173,7 @@ void fs_chroot(const char *rootdir) {
if (copy_file("/etc/resolv.conf", fname, 0, 0, 0644) == -1) // root needed
fwarning("/etc/resolv.conf not initialized\n");
}
// chroot into the new directory
#ifdef HAVE_GCOV
__gcov_flush();
@ -1196,15 +1196,15 @@ void fs_chroot(const char *rootdir) {
fs_var_log();
else
fs_rdwr("/var/log");
fs_var_lib();
fs_var_cache();
fs_var_utmp();
fs_machineid();
// don't leak user information
restrict_users();
// when starting as root, firejail config is not disabled;
// this mode could be used to install and test new software by chaining
// firejail sandboxes (firejail --force)
@ -1229,10 +1229,10 @@ void fs_private_tmp(void) {
if (rp)
free(rp);
}
// whitelist x11 directory
profile_add("whitelist /tmp/.X11-unix");
// whitelist any pulse* file in /tmp directory
// some distros use PulseAudio sockets under /tmp instead of the socket in /urn/user
DIR *dir;

View file

@ -39,10 +39,10 @@ static char *paths[] = {
// return 1 if found, 0 if not found
static char *check_dir_or_file(const char *name) {
assert(name);
struct stat s;
char *fname = NULL;
int i = 0;
while (paths[i]) {
// private-bin-no-local can be disabled in /etc/firejail/firejail.config
@ -50,12 +50,12 @@ static char *check_dir_or_file(const char *name) {
i++;
continue;
}
// check file
// check file
if (asprintf(&fname, "%s/%s", paths[i], name) == -1)
errExit("asprintf");
if (arg_debug)
printf("Checking %s/%s\n", paths[i], name);
printf("Checking %s/%s\n", paths[i], name);
if (stat(fname, &s) == 0 && !S_ISDIR(s.st_mode)) { // do not allow directories
// check symlink to firejail executable in /usr/local/bin
if (strcmp(paths[i], "/usr/local/bin") == 0 && is_link(fname)) {
@ -74,11 +74,11 @@ static char *check_dir_or_file(const char *name) {
}
free(actual_path);
}
}
}
break; // file found
}
free(fname);
fname = NULL;
i++;
@ -89,7 +89,7 @@ static char *check_dir_or_file(const char *name) {
fwarning("file %s not found\n", name);
return NULL;
}
free(fname);
return paths[i];
}
@ -109,7 +109,7 @@ static void duplicate(char *fname) {
char *full_path;
if (asprintf(&full_path, "%s/%s", path, fname) == -1)
errExit("asprintf");
// copy the file
if (checkcfg(CFG_FOLLOW_SYMLINK_PRIVATE_BIN))
sbox_run(SBOX_ROOT| SBOX_SECCOMP, 4, PATH_FCOPY, "--follow-link", full_path, RUN_BIN_DIR);
@ -123,10 +123,10 @@ static void duplicate(char *fname) {
void fs_private_bin_list(void) {
char *private_list = cfg.bin_private_keep;
assert(private_list);
// create /run/firejail/mnt/bin directory
mkdir_attr(RUN_BIN_DIR, 0755, 0, 0);
if (arg_debug)
printf("Copying files in the new bin directory\n");
@ -134,12 +134,12 @@ void fs_private_bin_list(void) {
char *dlist = strdup(private_list);
if (!dlist)
errExit("strdup");
char *ptr = strtok(dlist, ",");
duplicate(ptr);
while ((ptr = strtok(NULL, ",")) != NULL)
duplicate(ptr);
free(dlist);
free(dlist);
fs_logger_print();
// mount-bind
@ -157,4 +157,3 @@ void fs_private_bin_list(void) {
i++;
}
}

View file

@ -36,20 +36,20 @@ void fs_machineid(void) {
return;
if (arg_debug)
printf("Generating a new machine-id\n");
// init random number generator
srand(time(NULL));
// generate random id
mid.u32[0] = rand();
mid.u32[1] = rand();
mid.u32[2] = rand();
mid.u32[3] = rand();
// UUID version 4 and DCE variant
mid.u8[6] = (mid.u8[6] & 0x0F) | 0x40;
mid.u8[8] = (mid.u8[8] & 0x3F) | 0x80;
// write it in a file
FILE *fp = fopen(RUN_MACHINEID, "w");
if (!fp)
@ -58,7 +58,7 @@ void fs_machineid(void) {
fclose(fp);
if (set_perms(RUN_MACHINEID, 0, 0, 0444))
errExit("set_perms");
struct stat s;
if (stat("/etc/machine-id", &s) == 0) {
@ -93,7 +93,7 @@ static int check_dir_or_file(const char *fname) {
if (S_ISDIR(s.st_mode) || S_ISREG(s.st_mode) || !is_link(fname))
return 1; // normal exit
errexit:
errexit:
fprintf(stderr, "Error: invalid file type, %s.\n", fname);
exit(1);
}
@ -116,7 +116,7 @@ static void duplicate(const char *fname, const char *private_dir, const char *pr
if (arg_debug)
printf("copying %s to private %s\n", src, private_dir);
struct stat s;
if (stat(src, &s) == 0 && S_ISDIR(s.st_mode)) {
// create the directory in RUN_ETC_DIR
@ -139,11 +139,11 @@ void fs_private_dir_list(const char *private_dir, const char *private_run_dir, c
assert(private_dir);
assert(private_run_dir);
assert(private_list);
// create /run/firejail/mnt/etc directory
mkdir_attr(private_run_dir, 0755, 0, 0);
fs_logger2("tmpfs", private_dir);
fs_logger_print(); // save the current log
@ -157,21 +157,20 @@ void fs_private_dir_list(const char *private_dir, const char *private_run_dir, c
char *dlist = strdup(private_list);
if (!dlist)
errExit("strdup");
char *ptr = strtok(dlist, ",");
duplicate(ptr, private_dir, private_run_dir);
while ((ptr = strtok(NULL, ",")) != NULL)
duplicate(ptr, private_dir, private_run_dir);
free(dlist);
free(dlist);
fs_logger_print();
}
if (arg_debug)
printf("Mount-bind %s on top of %s\n", private_run_dir, private_dir);
if (mount(private_run_dir, private_dir, NULL, MS_BIND|MS_REC, NULL) < 0)
errExit("mount bind");
fs_logger2("mount", private_dir);
}

View file

@ -63,7 +63,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
if (asprintf(&fname, "%s/.cshrc", homedir) == -1)
errExit("asprintf");
struct stat s;
// don't copy it if we already have the file
if (stat(fname, &s) == 0)
return;
@ -88,7 +88,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
errExit("asprintf");
struct stat s;
// don't copy it if we already have the file
if (stat(fname, &s) == 0)
if (stat(fname, &s) == 0)
return;
if (is_link(fname)) { // stat on dangling symlinks fails, try again using lstat
fprintf(stderr, "Error: invalid %s file\n", fname);
@ -113,10 +113,10 @@ static int store_xauthority(void) {
SET_PERMS_STREAM(fp, getuid(), getgid(), 0600);
fclose(fp);
}
if (asprintf(&src, "%s/.Xauthority", cfg.homedir) == -1)
errExit("asprintf");
struct stat s;
if (stat(src, &s) == 0) {
if (is_link(src)) {
@ -128,7 +128,7 @@ static int store_xauthority(void) {
fs_logger2("clone", dest);
return 1; // file copied
}
return 0;
}
@ -143,10 +143,10 @@ static int store_asoundrc(void) {
SET_PERMS_STREAM(fp, getuid(), getgid(), 0644);
fclose(fp);
}
if (asprintf(&src, "%s/.asoundrc", cfg.homedir) == -1)
errExit("asprintf");
struct stat s;
if (stat(src, &s) == 0) {
if (is_link(src)) {
@ -168,7 +168,7 @@ static int store_asoundrc(void) {
fs_logger2("clone", dest);
return 1; // file copied
}
return 0;
}
@ -178,7 +178,7 @@ static void copy_xauthority(void) {
char *dest;
if (asprintf(&dest, "%s/.Xauthority", cfg.homedir) == -1)
errExit("asprintf");
// if destination is a symbolic link, exit the sandbox!!!
if (is_link(dest)) {
fprintf(stderr, "Error: %s is a symbolic link\n", dest);
@ -187,7 +187,7 @@ static void copy_xauthority(void) {
copy_file_as_user(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR); // regular user
fs_logger2("clone", dest);
// delete the temporary file
unlink(src);
}
@ -198,7 +198,7 @@ static void copy_asoundrc(void) {
char *dest;
if (asprintf(&dest, "%s/.asoundrc", cfg.homedir) == -1)
errExit("asprintf");
// if destination is a symbolic link, exit the sandbox!!!
if (is_link(dest)) {
fprintf(stderr, "Error: %s is a symbolic link\n", dest);
@ -222,10 +222,10 @@ void fs_private_homedir(void) {
char *private_homedir = cfg.home_private;
assert(homedir);
assert(private_homedir);
int xflag = store_xauthority();
int aflag = store_asoundrc();
uid_t u = getuid();
gid_t g = getgid();
@ -258,7 +258,7 @@ void fs_private_homedir(void) {
errExit("mounting home directory");
fs_logger("tmpfs /home");
}
skel(homedir, u, g);
if (xflag)
@ -309,7 +309,7 @@ void fs_private(void) {
errExit("chown");
fs_logger2("mkdir", homedir);
}
skel(homedir, u, g);
if (xflag)
copy_xauthority();
@ -322,12 +322,12 @@ void fs_private(void) {
void fs_check_private_dir(void) {
EUID_ASSERT();
invalid_filename(cfg.home_private);
// Expand the home directory
char *tmp = expand_home(cfg.home_private, cfg.homedir);
cfg.home_private = realpath(tmp, NULL);
free(tmp);
if (!cfg.home_private
|| !is_dir(cfg.home_private)
|| is_link(cfg.home_private)
@ -383,7 +383,7 @@ static char *check_dir_or_file(const char *name) {
// we allow only files in user home directory or symbolic links to files or directories owned by the user
struct stat s;
if (lstat(fname, &s) == 0 && S_ISLNK(s.st_mode)) {
if (stat(fname, &s) == 0) {
if (stat(fname, &s) == 0) {
if (s.st_uid != getuid()) {
fprintf(stderr, "Error: symbolic link %s to file or directory not owned by the user\n", fname);
exit(1);
@ -404,7 +404,7 @@ static char *check_dir_or_file(const char *name) {
fprintf(stderr, "Error: invalid file %s\n", name);
exit(1);
}
// only top files and directories in user home are allowed
char *ptr = rname + strlen(cfg.homedir);
assert(*ptr != '\0');
@ -480,7 +480,7 @@ void fs_private_home_list(void) {
char *dlist = strdup(cfg.home_private_keep);
if (!dlist)
errExit("strdup");
char *ptr = strtok(dlist, ",");
duplicate(ptr);
while ((ptr = strtok(NULL, ",")) != NULL)

View file

@ -27,7 +27,7 @@
void fs_hostname(const char *hostname) {
struct stat s;
// create a new /etc/hostname
if (stat("/etc/hostname", &s) == 0) {
if (arg_debug)
@ -40,7 +40,7 @@ void fs_hostname(const char *hostname) {
errExit("mount bind /etc/hostname");
fs_logger("create /etc/hostname");
}
// create a new /etc/hosts
if (cfg.hosts_file == NULL && stat("/etc/hosts", &s) == 0) {
if (arg_debug)
@ -56,7 +56,7 @@ void fs_hostname(const char *hostname) {
fclose(fp1);
goto errexit;
}
char buf[4096];
int done = 0;
while (fgets(buf, sizeof(buf), fp1)) {
@ -64,7 +64,7 @@ void fs_hostname(const char *hostname) {
char *ptr = strchr(buf, '\n');
if (ptr)
*ptr = '\0';
// copy line
if (strstr(buf, "127.0.0.1") && done == 0) {
done = 1;
@ -77,7 +77,7 @@ void fs_hostname(const char *hostname) {
// mode and owner
SET_PERMS_STREAM(fp2, 0, 0, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH);
fclose(fp2);
// bind-mount the file on top of /etc/hostname
fs_mount_hosts_file();
}
@ -93,7 +93,7 @@ void fs_resolvconf(void) {
return;
struct stat s;
// create a new /etc/hostname
if (stat("/etc/resolv.conf", &s) == 0) {
if (arg_debug)
@ -103,7 +103,7 @@ void fs_resolvconf(void) {
fprintf(stderr, "Error: cannot create %s\n", RUN_RESOLVCONF_FILE);
exit(1);
}
if (cfg.dns1)
fprintf(fp, "nameserver %d.%d.%d.%d\n", PRINT_IP(cfg.dns1));
if (cfg.dns2)
@ -115,7 +115,7 @@ void fs_resolvconf(void) {
SET_PERMS_STREAM(fp, 0, 0, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH);
fclose(fp);
// bind-mount the file on top of /etc/hostname
if (mount(RUN_RESOLVCONF_FILE, "/etc/resolv.conf", NULL, MS_BIND|MS_REC, NULL) < 0)
errExit("mount bind /etc/resolv.conf");
@ -135,7 +135,7 @@ char *fs_check_hosts_file(const char *fname) {
// no a link
if (is_link(rv))
goto errexit;
// the user has read access to the file
if (access(rv, R_OK))
goto errexit;
@ -175,4 +175,3 @@ errexit:
fprintf(stderr, "Error: invalid /etc/hosts file\n");
exit(1);
}

View file

@ -17,7 +17,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "firejail.h"
#include <sys/types.h>
#include <sys/stat.h>
@ -47,7 +47,7 @@ static inline void insertmsg(FsMsg *ptr) {
last = ptr;
return;
}
assert(last);
last->next = ptr;
last = ptr;
@ -91,14 +91,14 @@ void fs_logger3(const char *msg1, const char *msg2, const char *msg3) {
void fs_logger_print(void) {
if (!head)
return;
FILE *fp = fopen(RUN_FSLOGGER_FILE, "a");
if (!fp) {
perror("fopen");
perror("fopen");
return;
}
SET_PERMS_STREAM_NOERR(fp, getuid(), getgid(), 0644);
FsMsg *ptr = head;
while (ptr) {
fprintf(fp, "%s\n", ptr->msg);
@ -162,7 +162,7 @@ void fs_logger_print_log(pid_t pid) {
fprintf(stderr, "Error: Cannot open filesystem log\n");
exit(1);
}
char buf[MAXBUF];
while (fgets(buf, MAXBUF, fp))
printf("%s", buf);

View file

@ -57,7 +57,7 @@ static void mkdir_recursive(char *path) {
void fs_mkdir(const char *name) {
EUID_ASSERT();
// check directory name
invalid_filename(name);
char *expanded = expand_home(name, cfg.homedir);
@ -93,11 +93,11 @@ void fs_mkdir(const char *name) {
doexit:
free(expanded);
}
}
void fs_mkfile(const char *name) {
EUID_ASSERT();
// check file name
invalid_filename(name);
char *expanded = expand_home(name, cfg.homedir);
@ -115,7 +115,7 @@ void fs_mkfile(const char *name) {
// create file
touch_file_as_user(expanded, getuid(), getgid(), 0600);
doexit:
free(expanded);
}

View file

@ -58,11 +58,11 @@ void fs_trace(void) {
fprintf(fp, "%s/firejail/libtracelog.so\n", LIBDIR);
if (!arg_quiet)
printf("Blacklist violations are logged to syslog\n");
}
}
SET_PERMS_STREAM(fp, 0, 0, S_IRUSR | S_IWRITE | S_IRGRP | S_IROTH);
fclose(fp);
// mount the new preload file
if (arg_debug)
printf("Mount the new ld.so.preload file\n");
@ -70,4 +70,3 @@ void fs_trace(void) {
errExit("mount bind ld.so.preload");
fs_logger("create /etc/ld.so.preload");
}

View file

@ -48,7 +48,7 @@ static void release_all(void) {
}
dirlist = NULL;
}
static void build_list(const char *srcdir) {
// extract current /var/log directory data
struct dirent *dir;
@ -77,7 +77,7 @@ static void build_list(const char *srcdir) {
// s.st_uid,
// s.st_gid,
// dir->d_name);
DirData *ptr = malloc(sizeof(DirData));
if (ptr == NULL)
errExit("malloc");
@ -87,8 +87,8 @@ static void build_list(const char *srcdir) {
ptr->st_uid = s.st_uid;
ptr->st_gid = s.st_gid;
ptr->next = dirlist;
dirlist = ptr;
}
dirlist = ptr;
}
}
closedir(d);
}
@ -102,10 +102,10 @@ static void build_dirs(void) {
ptr = ptr->next;
}
}
void fs_var_log(void) {
build_list("/var/log");
// note: /var/log is not created here, if it does not exist, this section fails.
// create /var/log if it doesn't exit
if (is_dir("/var/log")) {
@ -114,17 +114,17 @@ void fs_var_log(void) {
gid_t wtmp_group = 0;
if (stat("/var/log/wtmp", &s) == 0)
wtmp_group = s.st_gid;
// mount a tmpfs on top of /var/log
if (arg_debug)
printf("Mounting tmpfs on /var/log\n");
if (mount("tmpfs", "/var/log", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
errExit("mounting /var/log");
fs_logger("tmpfs /var/log");
build_dirs();
release_all();
// create an empty /var/log/wtmp file
/* coverity[toctou] */
FILE *fp = fopen("/var/log/wtmp", "w");
@ -133,7 +133,7 @@ void fs_var_log(void) {
fclose(fp);
}
fs_logger("touch /var/log/wtmp");
// create an empty /var/log/btmp file
fp = fopen("/var/log/btmp", "w");
if (fp) {
@ -148,7 +148,7 @@ void fs_var_log(void) {
void fs_var_lib(void) {
struct stat s;
// ISC DHCP multiserver
if (stat("/var/lib/dhcp", &s) == 0) {
if (arg_debug)
@ -156,10 +156,10 @@ void fs_var_lib(void) {
if (mount("tmpfs", "/var/lib/dhcp", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
errExit("mounting /var/lib/dhcp");
fs_logger("tmpfs /var/lib/dhcp");
// isc dhcp server requires a /var/lib/dhcp/dhcpd.leases file
FILE *fp = fopen("/var/lib/dhcp/dhcpd.leases", "w");
if (fp) {
fprintf(fp, "\n");
SET_PERMS_STREAM(fp, 0, 0, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH);
@ -175,7 +175,7 @@ void fs_var_lib(void) {
if (mount("tmpfs", "/var/lib/nginx", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
errExit("mounting /var/lib/nginx");
fs_logger("tmpfs /var/lib/nginx");
}
}
// net-snmp multiserver
if (stat("/var/lib/snmp", &s) == 0) {
@ -184,7 +184,7 @@ void fs_var_lib(void) {
if (mount("tmpfs", "/var/lib/snmp", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
errExit("mounting /var/lib/snmp");
fs_logger("tmpfs /var/lib/snmp");
}
}
// this is where sudo remembers its state
if (stat("/var/lib/sudo", &s) == 0) {
@ -193,7 +193,7 @@ void fs_var_lib(void) {
if (mount("tmpfs", "/var/lib/sudo", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
errExit("mounting /var/lib/sudo");
fs_logger("tmpfs /var/lib/sudo");
}
}
}
void fs_var_cache(void) {
@ -205,7 +205,7 @@ void fs_var_cache(void) {
if (mount("tmpfs", "/var/cache/apache2", "tmpfs", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
errExit("mounting /var/cache/apache2");
fs_logger("tmpfs /var/cache/apache2");
}
}
if (stat("/var/cache/lighttpd", &s) == 0) {
if (arg_debug)
@ -221,13 +221,13 @@ void fs_var_cache(void) {
uid = p->pw_uid;
gid = p->pw_gid;
}
mkdir_attr("/var/cache/lighttpd/compress", 0755, uid, gid);
fs_logger("mkdir /var/cache/lighttpd/compress");
mkdir_attr("/var/cache/lighttpd/uploads", 0755, uid, gid);
fs_logger("/var/cache/lighttpd/uploads");
}
}
}
void dbg_test_dir(const char *dir) {
@ -312,7 +312,7 @@ void fs_var_utmp(void) {
FILE *fp = fopen(RUN_UTMP_FILE, "w");
if (!fp)
errExit("fopen");
// read current utmp
struct utmp *u;
struct utmp u_boot;
@ -324,12 +324,12 @@ void fs_var_utmp(void) {
}
}
endutent();
// save new utmp file
fwrite(&u_boot, sizeof(u_boot), 1, fp);
SET_PERMS_STREAM(fp, 0, utmp_group, S_IRUSR | S_IWRITE | S_IRGRP | S_IWGRP | S_IROTH);
fclose(fp);
// mount the new utmp file
if (arg_debug)
printf("Mount the new utmp file\n");

View file

@ -44,11 +44,11 @@ static char *resolve_downloads(int nowhitelist_flag) {
while (dentry[i] != NULL) {
if (asprintf(&fname, "%s/%s", cfg.homedir, dentry[i]) == -1)
errExit("asprintf");
if (stat(fname, &s) == 0) {
if (arg_debug || arg_debug_whitelists)
printf("Downloads directory resolved as \"%s\"\n", fname);
char *rv;
if (nowhitelist_flag) {
if (asprintf(&rv, "nowhitelist ~/%s", dentry[i]) == -1)
@ -72,14 +72,14 @@ static char *resolve_downloads(int nowhitelist_flag) {
if (!fp) {
free(fname);
return NULL;
}
}
free(fname);
// extract downloads directory
char buf[MAXBUF];
while (fgets(buf, MAXBUF, fp)) {
char *ptr = buf;
// skip blanks
while (*ptr == ' ' || *ptr == '\t')
ptr++;
@ -97,15 +97,15 @@ static char *resolve_downloads(int nowhitelist_flag) {
if (strlen(ptr1) != 0) {
if (arg_debug || arg_debug_whitelists)
printf("Downloads directory resolved as \"%s\"\n", ptr1);
if (asprintf(&fname, "%s/%s", cfg.homedir, ptr1) == -1)
errExit("asprintf");
if (stat(fname, &s) == -1) {
free(fname);
goto errout;
}
char *rv;
if (nowhitelist_flag) {
if (asprintf(&rv, "nowhitelist ~/%s", ptr + 24) == -1)
@ -122,7 +122,7 @@ static char *resolve_downloads(int nowhitelist_flag) {
}
}
}
fclose(fp);
return NULL;
@ -131,13 +131,13 @@ errout:
fprintf(stderr, "*** Error: Downloads directory was not found in user home.\n");
fprintf(stderr, "*** \tAny files saved by the program, will be lost when the sandbox is closed.\n");
fprintf(stderr, "***\n");
return NULL;
}
static int mkpath(const char* path, mode_t mode) {
assert(path && *path);
mode |= 0111;
// create directories with uid/gid as root or as current user if inside home directory
@ -168,13 +168,13 @@ static int mkpath(const char* path, mode_t mode) {
if (set_perms(file_path, uid, gid, mode))
errExit("set_perms");
done = 1;
}
}
*p='/';
}
if (done)
fs_logger2("mkpath", path);
free(file_path);
return 0;
}
@ -187,14 +187,14 @@ static void whitelist_path(ProfileEntry *entry) {
char *wfile = NULL;
if (entry->home_dir) {
if (strncmp(path, cfg.homedir, strlen(cfg.homedir)) == 0) {
if (strncmp(path, cfg.homedir, strlen(cfg.homedir)) == 0) {
fname = path + strlen(cfg.homedir);
if (*fname == '\0')
goto errexit;
}
else
fname = path;
if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_HOME_USER_DIR, fname) == -1)
errExit("asprintf");
}
@ -202,7 +202,7 @@ static void whitelist_path(ProfileEntry *entry) {
fname = path + 4; // strlen("/tmp")
if (*fname == '\0')
goto errexit;
if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_TMP_DIR, fname) == -1)
errExit("asprintf");
}
@ -210,7 +210,7 @@ static void whitelist_path(ProfileEntry *entry) {
fname = path + 6; // strlen("/media")
if (*fname == '\0')
goto errexit;
if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_MEDIA_DIR, fname) == -1)
errExit("asprintf");
}
@ -226,7 +226,7 @@ static void whitelist_path(ProfileEntry *entry) {
fname = path + 4; // strlen("/var")
if (*fname == '\0')
goto errexit;
if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_VAR_DIR, fname) == -1)
errExit("asprintf");
}
@ -234,7 +234,7 @@ static void whitelist_path(ProfileEntry *entry) {
fname = path + 4; // strlen("/dev")
if (*fname == '\0')
goto errexit;
if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_DEV_DIR, fname) == -1)
errExit("asprintf");
}
@ -242,7 +242,7 @@ static void whitelist_path(ProfileEntry *entry) {
fname = path + 4; // strlen("/opt")
if (*fname == '\0')
goto errexit;
if (asprintf(&wfile, "%s/%s", RUN_WHITELIST_OPT_DIR, fname) == -1)
errExit("asprintf");
}
@ -263,18 +263,18 @@ static void whitelist_path(ProfileEntry *entry) {
else {
return;
}
// create the path if necessary
mkpath(path, s.st_mode);
fs_logger2("whitelist", path);
// process directory
if (S_ISDIR(s.st_mode)) {
if (S_ISDIR(s.st_mode)) {
// create directory
int rv = mkdir(path, 0755);
(void) rv;
}
// process regular file
else {
if (access(path, R_OK)) {
@ -291,7 +291,7 @@ static void whitelist_path(ProfileEntry *entry) {
else
return; // the file is already present
}
// mount
if (mount(wfile, path, NULL, MS_BIND|MS_REC, NULL) < 0)
errExit("mount bind");
@ -328,11 +328,11 @@ void fs_whitelist(void) {
char **nowhitelist = calloc(nowhitelist_m, sizeof(*nowhitelist));
if (nowhitelist == NULL)
errExit("failed allocating memory for nowhitelist entries");
// verify whitelist files, extract symbolic links, etc.
while (entry) {
int nowhitelist_flag = 0;
// handle only whitelist and nowhitelist commands
if (strncmp(entry->data, "whitelist ", 10) == 0)
nowhitelist_flag = 0;
@ -412,16 +412,16 @@ void fs_whitelist(void) {
else if (strncmp(new_name, "/srv/", 5) == 0)
opt_dir = 1;
}
*entry->data = '\0';
continue;
}
if (nowhitelist_flag) {
// store the path in nowhitelist array
if (arg_debug || arg_debug_whitelists)
printf("Storing nowhitelist %s\n", fname);
if (nowhitelist_c >= nowhitelist_m) {
nowhitelist_m *= 2;
nowhitelist = realloc(nowhitelist, sizeof(*nowhitelist) * nowhitelist_m);
@ -432,8 +432,8 @@ void fs_whitelist(void) {
*entry->data = 0;
continue;
}
// check for supported directories
if (strncmp(new_name, cfg.homedir, strlen(cfg.homedir)) == 0) {
// whitelisting home directory is disabled if --private option is present
@ -544,7 +544,7 @@ void fs_whitelist(void) {
free(fname);
continue;
}
}
}
// mark symbolic links
if (is_link(new_name))
@ -566,29 +566,29 @@ void fs_whitelist(void) {
free(fname);
entry = entry->next;
}
// release nowhitelist memory
assert(nowhitelist);
free(nowhitelist);
// /home/user
if (home_dir) {
// keep a copy of real home dir in RUN_WHITELIST_HOME_USER_DIR
mkdir_attr(RUN_WHITELIST_HOME_USER_DIR, 0755, getuid(), getgid());
if (mount(cfg.homedir, RUN_WHITELIST_HOME_USER_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
errExit("mount bind");
// mount a tmpfs and initialize /home/user
fs_private();
}
// /tmp mountpoint
if (tmp_dir) {
// keep a copy of real /tmp directory in
// keep a copy of real /tmp directory in
mkdir_attr(RUN_WHITELIST_TMP_DIR, 1777, 0, 0);
if (mount("/tmp", RUN_WHITELIST_TMP_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
errExit("mount bind");
// mount tmpfs on /tmp
if (arg_debug || arg_debug_whitelists)
printf("Mounting tmpfs on /tmp directory\n");
@ -596,7 +596,7 @@ void fs_whitelist(void) {
errExit("mounting tmpfs on /tmp");
fs_logger("tmpfs /tmp");
}
// /media mountpoint
if (media_dir) {
// some distros don't have a /media directory
@ -606,7 +606,7 @@ void fs_whitelist(void) {
mkdir_attr(RUN_WHITELIST_MEDIA_DIR, 0755, 0, 0);
if (mount("/media", RUN_WHITELIST_MEDIA_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
errExit("mount bind");
// mount tmpfs on /media
if (arg_debug || arg_debug_whitelists)
printf("Mounting tmpfs on /media directory\n");
@ -646,7 +646,7 @@ void fs_whitelist(void) {
mkdir_attr(RUN_WHITELIST_VAR_DIR, 0755, 0, 0);
if (mount("/var", RUN_WHITELIST_VAR_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
errExit("mount bind");
// mount tmpfs on /var
if (arg_debug || arg_debug_whitelists)
printf("Mounting tmpfs on /var directory\n");
@ -661,7 +661,7 @@ void fs_whitelist(void) {
mkdir_attr(RUN_WHITELIST_DEV_DIR, 0755, 0, 0);
if (mount("/dev", RUN_WHITELIST_DEV_DIR, NULL, MS_BIND|MS_REC, "mode=755,gid=0") < 0)
errExit("mount bind");
// mount tmpfs on /dev
if (arg_debug || arg_debug_whitelists)
printf("Mounting tmpfs on /dev directory\n");
@ -676,7 +676,7 @@ void fs_whitelist(void) {
mkdir_attr(RUN_WHITELIST_OPT_DIR, 0755, 0, 0);
if (mount("/opt", RUN_WHITELIST_OPT_DIR, NULL, MS_BIND|MS_REC, NULL) < 0)
errExit("mount bind");
// mount tmpfs on /opt
if (arg_debug || arg_debug_whitelists)
printf("Mounting tmpfs on /opt directory\n");
@ -707,7 +707,7 @@ void fs_whitelist(void) {
}
// go through profile rules again, and interpret whitelist commands
entry = cfg.profile;
while (entry) {
@ -719,7 +719,7 @@ void fs_whitelist(void) {
//printf("here %d#%s#\n", __LINE__, entry->data);
// whitelist the real file
if (strcmp(entry->data, "whitelist /run") == 0 &&
if (strcmp(entry->data, "whitelist /run") == 0 &&
(strcmp(entry->link, "/var/run") == 0 || strcmp(entry->link, "/var/lock") == 0)) {
int rv = symlink(entry->data + 10, entry->link);
if (rv)
@ -729,7 +729,7 @@ void fs_whitelist(void) {
}
else {
whitelist_path(entry);
// create the link if any
if (entry->link) {
// if the link is already there, do not bother
@ -737,7 +737,7 @@ void fs_whitelist(void) {
if (stat(entry->link, &s) != 0) {
// create the path if necessary
mkpath(entry->link, s.st_mode);
int rv = symlink(entry->data + 10, entry->link);
if (rv)
fprintf(stderr, "Warning cannot create symbolic link %s\n", entry->link);
@ -756,7 +756,7 @@ void fs_whitelist(void) {
errExit("mount tmpfs");
fs_logger2("tmpfs", RUN_WHITELIST_HOME_USER_DIR);
}
// mask the real /tmp directory, currently mounted on RUN_WHITELIST_TMP_DIR
if (tmp_dir) {
if (mount("tmpfs", RUN_WHITELIST_TMP_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC, "mode=755,gid=0") < 0)
@ -808,7 +808,7 @@ void fs_whitelist(void) {
if (new_name)
free(new_name);
return;
errexit:

View file

@ -19,7 +19,7 @@
*/
#ifdef HAVE_GIT_INSTALL
#include "firejail.h"
#include <sys/utsname.h>
#include <sched.h>
@ -46,7 +46,7 @@ static void sbox_ns(void) {
errExit("setgid/getgid");
if (setuid(getuid()) < 0)
errExit("setuid/getuid");
assert(getenv("LD_PRELOAD") == NULL);
assert(getenv("LD_PRELOAD") == NULL);
printf("Running as "); fflush(0);
int rv = system("whoami");
@ -55,16 +55,16 @@ static void sbox_ns(void) {
rv = system("ls -l /tmp");
(void) rv;
}
void git_install(void) {
// redirect to "/usr/bin/firejail --noprofile --private-tmp /usr/lib/firejail/fgit-install.sh"
EUID_ASSERT();
EUID_ROOT();
// install a mount namespace with a tmpfs on top of /tmp
sbox_ns();
// run command
const char *cmd = LIBDIR "/firejail/fgit-install.sh";
int rv = system(cmd);
@ -76,15 +76,15 @@ void git_uninstall(void) {
// redirect to "/usr/bin/firejail --noprofile --private-tmp /usr/lib/firejail/fgit-install.sh"
EUID_ASSERT();
EUID_ROOT();
// install a mount namespace with a tmpfs on top of /tmp
sbox_ns();
// run command
const char *cmd = LIBDIR "/firejail/fgit-uninstall.sh";
int rv = system(cmd);
(void) rv;
exit(0);
}
#endif // HAVE_GIT_INSTALL

View file

@ -48,7 +48,7 @@ static void extract_command(int argc, char **argv, int index) {
if (index >= argc)
return;
}
// first argv needs to be a valid command
if (arg_doubledash == 0 && *argv[index] == '-') {
fprintf(stderr, "Error: invalid option %s after --join\n", argv[index]);
@ -66,7 +66,7 @@ static void extract_nogroups(pid_t pid) {
char *fname;
if (asprintf(&fname, "/proc/%d/root%s", pid, RUN_GROUPS_CFG) == -1)
errExit("asprintf");
struct stat s;
if (stat(fname, &s) == -1)
return;
@ -79,11 +79,11 @@ static void extract_cpu(pid_t pid) {
char *fname;
if (asprintf(&fname, "/proc/%d/root%s", pid, RUN_CPU_CFG) == -1)
errExit("asprintf");
struct stat s;
if (stat(fname, &s) == -1)
return;
// there is a CPU_CFG file, load it!
load_cpu(fname);
free(fname);
@ -93,11 +93,11 @@ static void extract_cgroup(pid_t pid) {
char *fname;
if (asprintf(&fname, "/proc/%d/root%s", pid, RUN_CGROUP_CFG) == -1)
errExit("asprintf");
struct stat s;
if (stat(fname, &s) == -1)
return;
// there is a cgroup file CGROUP_CFG, load it!
load_cgroup(fname);
free(fname);
@ -127,7 +127,7 @@ static void extract_caps_seccomp(pid_t pid) {
apply_seccomp = 1;
break;
}
else if (strncmp(buf, "CapBnd:", 7) == 0) {
else if (strncmp(buf, "CapBnd:", 7) == 0) {
char *ptr = buf + 7;
unsigned long long val;
sscanf(ptr, "%llx", &val);
@ -149,7 +149,7 @@ static void extract_user_namespace(pid_t pid) {
stat("/proc/self/gid_map", &s3) == 0);
else
return;
// read uid map
char *uidmap;
if (asprintf(&uidmap, "/proc/%u/uid_map", pid) == -1)
@ -215,11 +215,11 @@ void join(pid_t pid, int argc, char **argv, int index) {
extract_nogroups(pid);
extract_user_namespace(pid);
}
// set cgroup
if (cfg.cgroup) // not available for uid 0
set_cgroup(cfg.cgroup);
// join namespaces
if (arg_join_network) {
if (join_namespace(pid, "net"))
@ -246,14 +246,14 @@ void join(pid_t pid, int argc, char **argv, int index) {
char *rootdir;
if (asprintf(&rootdir, "/proc/%d/root", pid) == -1)
errExit("asprintf");
int rv;
if (!arg_join_network) {
rv = chroot(rootdir); // this will fail for processes in sandboxes not started with --chroot option
if (rv == 0)
printf("changing root to %s\n", rootdir);
}
prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // kill the child in case the parent died
if (chdir("/") < 0)
errExit("chdir");
@ -265,11 +265,11 @@ void join(pid_t pid, int argc, char **argv, int index) {
errExit("chdir");
}
}
// set cpu affinity
if (cfg.cpus) // not available for uid 0
set_cpu_affinity();
// set caps filter
if (apply_caps == 1) // not available for uid 0
caps_set(caps);
@ -278,9 +278,9 @@ void join(pid_t pid, int argc, char **argv, int index) {
if (getuid() != 0)
protocol_filter_load(RUN_PROTOCOL_CFG);
if (cfg.protocol) { // not available for uid 0
seccomp_load(RUN_SECCOMP_PROTOCOL); // install filter
seccomp_load(RUN_SECCOMP_PROTOCOL); // install filter
}
// set seccomp filter
if (apply_seccomp == 1) // not available for uid 0
seccomp_load(RUN_SECCOMP_CFG);
@ -298,7 +298,7 @@ void join(pid_t pid, int argc, char **argv, int index) {
if (apply_caps == 1) // not available for uid 0
caps_set(caps);
}
else
else
drop_privs(arg_nogroups); // nogroups not available for uid 0
@ -349,6 +349,3 @@ void join(pid_t pid, int argc, char **argv, int index) {
flush_stdin();
exit(0);
}

View file

@ -17,7 +17,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "firejail.h"
#include <sys/types.h>
#include <sys/stat.h>
@ -36,7 +36,7 @@ static char *c_uid_name = NULL;
static void print_file_or_dir(const char *path, const char *fname, int separator) {
assert(fname);
char *name;
if (separator) {
if (asprintf(&name, "%s/%s", path, fname) == -1)
@ -46,7 +46,7 @@ static void print_file_or_dir(const char *path, const char *fname, int separator
if (asprintf(&name, "%s%s", path, fname) == -1)
errExit("asprintf");
}
struct stat s;
if (stat(name, &s) == -1) {
if (lstat(name, &s) == -1) {
@ -78,7 +78,7 @@ static void print_file_or_dir(const char *path, const char *fname, int separator
printf( (s.st_mode & S_IWOTH) ? "w" : "-");
printf( (s.st_mode & S_IXOTH) ? "x" : "-");
printf(" ");
// user name
char *username;
int allocated = 0;
@ -100,7 +100,7 @@ static void print_file_or_dir(const char *path, const char *fname, int separator
if (!username)
errExit("asprintf");
}
if (c_uid == 0) {
c_uid = s.st_uid;
c_uid_name = strdup(username);
@ -108,7 +108,7 @@ static void print_file_or_dir(const char *path, const char *fname, int separator
errExit("asprintf");
}
}
// print user name, 8 chars maximum
int len = strlen(username);
if (len > 8) {
@ -121,7 +121,7 @@ static void print_file_or_dir(const char *path, const char *fname, int separator
printf(" ");
if (allocated)
free(username);
// group name
char *groupname;
@ -141,7 +141,7 @@ static void print_file_or_dir(const char *path, const char *fname, int separator
errExit("asprintf");
}
}
// print grup name, 8 chars maximum
len = strlen(groupname);
if (len > 8) {
@ -159,7 +159,7 @@ static void print_file_or_dir(const char *path, const char *fname, int separator
errExit("asprintf");
printf("%11.10s %s\n", sz, fname);
free(sz);
}
static void print_directory(const char *path) {
@ -168,7 +168,7 @@ static void print_directory(const char *path) {
if (stat(path, &s) == -1)
return;
assert(S_ISDIR(s.st_mode));
struct dirent **namelist;
int i;
int n;
@ -200,7 +200,7 @@ char *expand_path(const char *path) {
// assume the file is in current working directory
if (asprintf(&fname, "%s/%s", cfg.cwd, path) == -1)
errExit("asprintf");
}
}
return fname;
}
@ -241,7 +241,7 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) {
printf("file1 %s\n", fname1);
printf("file2 %s\n", fname2);
}
// sandbox root directory
char *rootdir;
if (asprintf(&rootdir, "/proc/%d/root", pid) == -1)
@ -254,7 +254,7 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) {
errExit("chroot");
if (chdir("/") < 0)
errExit("chdir");
// drop privileges
drop_privs(0);
@ -271,8 +271,8 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) {
}
if (arg_debug)
printf("realpath %s\n", rp);
// list directory contents
struct stat s;
if (stat(rp, &s) == -1) {
@ -283,7 +283,7 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) {
char *dir;
if (asprintf(&dir, "%s/", rp) == -1)
errExit("asprintf");
print_directory(dir);
free(dir);
}
@ -299,7 +299,7 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) {
}
free(rp);
}
// get file from sandbox and store it in the current directory
else if (op == SANDBOX_FS_GET) {
char *src_fname =fname1;
@ -320,7 +320,7 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) {
SET_PERMS_FD(fd, getuid(), getgid(), 0600);
close(fd);
}
// copy the source file into the temporary file - we need to chroot
pid_t child = fork();
if (child < 0)
@ -331,10 +331,10 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) {
errExit("chroot");
if (chdir("/") < 0)
errExit("chdir");
// drop privileges
drop_privs(0);
// copy the file
if (copy_file(src_fname, tmp_fname, getuid(), getgid(), 0600)) // already a regular user
_exit(1);
@ -352,7 +352,7 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) {
unlink(tmp_fname);
exit(1);
}
// copy the temporary file into the destionation file
child = fork();
if (child < 0)
@ -360,7 +360,7 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) {
if (child == 0) {
// drop privileges
drop_privs(0);
// copy the file
if (copy_file(tmp_fname, dest_fname, getuid(), getgid(), 0600)) // already a regular user
_exit(1);
@ -378,7 +378,7 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) {
unlink(tmp_fname);
exit(1);
}
// remove the temporary file
unlink(tmp_fname);
EUID_USER();
@ -401,7 +401,7 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) {
}
SET_PERMS_FD(fd, getuid(), getgid(), 0600);
close(fd);
// copy the source file into the temporary file - we need to chroot
pid_t child = fork();
if (child < 0)
@ -409,7 +409,7 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) {
if (child == 0) {
// drop privileges
drop_privs(0);
// copy the file
if (copy_file(src_fname, tmp_fname, getuid(), getgid(), 0600)) // already a regular user
_exit(1);
@ -427,7 +427,7 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) {
unlink(tmp_fname);
exit(1);
}
// copy the temporary file into the destionation file
child = fork();
if (child < 0)
@ -438,10 +438,10 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) {
errExit("chroot");
if (chdir("/") < 0)
errExit("chdir");
// drop privileges
drop_privs(0);
// copy the file
if (copy_file(tmp_fname, dest_fname, getuid(), getgid(), 0600)) // already a regular user
_exit(1);
@ -459,7 +459,7 @@ void sandboxfs(int op, pid_t pid, const char *path1, const char *path2) {
unlink(tmp_fname);
exit(1);
}
// remove the temporary file
unlink(tmp_fname);
EUID_USER();

View file

@ -46,7 +46,7 @@ static char *client_filter =
void check_netfilter_file(const char *fname) {
EUID_ASSERT();
invalid_filename(fname);
if (is_dir(fname) || is_link(fname) || strstr(fname, "..") || access(fname, R_OK )) {
fprintf(stderr, "Error: invalid network filter file %s\n", fname);
exit(1);
@ -95,14 +95,14 @@ void netfilter(const char *fname) {
// push filter
if (arg_debug)
printf("Installing network filter:\n%s\n", filter);
// first run of iptables on this platform installs a number of kernel modules such as ip_tables, x_tables, iptable_filter
// we run this command with caps and seccomp disabled in order to allow the loading of these modules
sbox_run(SBOX_ROOT /* | SBOX_CAPS_NETWORK | SBOX_SECCOMP*/ | SBOX_STDIN_FROM_FILE, 1, iptables_restore);
unlink(SBOX_STDIN_FILE);
// debug
if (arg_debug)
if (arg_debug)
sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 2, iptables, "-vL");
if (allocated)
@ -113,7 +113,7 @@ void netfilter(const char *fname) {
void netfilter6(const char *fname) {
if (fname == NULL)
return;
// find iptables command
char *ip6tables = NULL;
char *ip6tables_restore = NULL;
@ -149,7 +149,7 @@ void netfilter6(const char *fname) {
// we run this command with caps and seccomp disabled in order to allow the loading of these modules
sbox_run(SBOX_ROOT | /* SBOX_CAPS_NETWORK | SBOX_SECCOMP | */ SBOX_STDIN_FROM_FILE, 1, ip6tables_restore);
unlink(SBOX_STDIN_FILE);
// debug
if (arg_debug)
sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 2, ip6tables, "-vL");

View file

@ -50,8 +50,8 @@ int net_get_mtu(const char *ifname) {
if (arg_debug)
printf("MTU of %s is %d.\n", ifname, ifr.ifr_mtu);
close(s);
return mtu;
}
@ -84,10 +84,10 @@ int net_get_if_addr(const char *bridge, uint32_t *ip, uint32_t *mask, uint8_t ma
assert(bridge);
assert(ip);
assert(mask);
if (arg_debug)
printf("get interface %s configuration\n", bridge);
int rv = -1;
struct ifaddrs *ifaddr, *ifa;
@ -110,7 +110,7 @@ int net_get_if_addr(const char *bridge, uint32_t *ip, uint32_t *mask, uint8_t ma
net_get_mac(ifa->ifa_name, mac);
*mtu = net_get_mtu(bridge);
}
rv = 0;
break;
}
@ -126,9 +126,9 @@ void net_if_up(const char *ifname) {
fprintf(stderr, "Error: invalid network device name %s\n", ifname);
exit(1);
}
sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 3,
sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 3,
PATH_FNET, "ifup", ifname);
}
}
// configure interface ipv6 address
@ -138,8 +138,8 @@ void net_if_ip6(const char *ifname, const char *addr6) {
fprintf(stderr, "Error: invalid IPv6 address %s\n", addr6);
exit(1);
}
sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 5,
sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 5,
PATH_FNET, "config", "ipv6", ifname, addr6);
}
@ -187,19 +187,19 @@ uint32_t network_get_defaultgw(void) {
FILE *fp = fopen("/proc/self/net/route", "r");
if (!fp)
errExit("fopen");
char buf[BUFSIZE];
uint32_t retval = 0;
while (fgets(buf, BUFSIZE, fp)) {
if (strncmp(buf, "Iface", 5) == 0)
continue;
char *ptr = buf;
while (*ptr != ' ' && *ptr != '\t')
ptr++;
while (*ptr == ' ' || *ptr == '\t')
ptr++;
unsigned dest;
unsigned gw;
int rv = sscanf(ptr, "%x %x", &dest, &gw);
@ -219,9 +219,9 @@ int net_config_mac(const char *ifname, const unsigned char mac[6]) {
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]) == -1)
errExit("asprintf");
sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 5,
sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 5,
PATH_FNET, "config", "mac", ifname, macstr);
free(macstr);
return 0;
}
@ -237,7 +237,7 @@ int net_get_mac(const char *ifname, unsigned char mac[6]) {
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
if (ioctl(sock, SIOCGIFHWADDR, &ifr) == -1)
errExit("ioctl");
memcpy(mac, ifr.ifr_hwaddr.sa_data, 6);
@ -248,7 +248,7 @@ int net_get_mac(const char *ifname, unsigned char mac[6]) {
void net_config_interface(const char *dev, uint32_t ip, uint32_t mask, int mtu) {
assert(dev);
char *ipstr;
if (asprintf(&ipstr, "%llu", (long long unsigned) ip) == -1)
errExit("asprintf");
@ -260,12 +260,11 @@ void net_config_interface(const char *dev, uint32_t ip, uint32_t mask, int mtu)
char *mtustr;
if (asprintf(&mtustr, "%d", mtu) == -1)
errExit("asprintf");
sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 7,
sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 7,
PATH_FNET, "config", "interface", dev, ipstr, maskstr, mtustr);
free(ipstr);
free(maskstr);
free(mtustr);
}

View file

@ -40,10 +40,10 @@ main() {
else if --ip
br = last bridge configured
br->ipsandbox = ip address extracted from argv[i]
else if --defaultgw
else if --defaultgw
cfg.defaultgw = ip address extracted from argv[i]
}
net_check_cfg(); // check the validity of network configuration so far
if (any bridge configured) {
@ -51,29 +51,29 @@ main() {
for each bridge
net_configure_sandbox_ip(br)
}
clone (new network namespace if any bridge configured or --net=none)
if (any bridge configured) {
for each bridge
net_configure_veth_pair
}
}
notify child init is done
if (any bridge configured) {
for each bridge
net_bridge_wait_ip
unlock /var/lock/firejail.lock file
}
wait on child
exit
}
******************************************************
* macvlan notes
* macvlan notes
******************************************************
Configure a macvlan interface

View file

@ -50,7 +50,7 @@ void net_configure_bridge(Bridge *br, char *dev_name) {
if (asprintf(&newname, "%s-%u", br->devsandbox, getpid()) == -1)
errExit("asprintf");
br->devsandbox = newname;
}
}
else {
fprintf(stderr, "Error: cannot find network device %s\n", br->dev);
exit(1);
@ -72,7 +72,7 @@ void net_configure_bridge(Bridge *br, char *dev_name) {
printf("macvlan parent device %s at %d.%d.%d.%d/%d\n",
br->dev, PRINT_IP(br->ip), mask2bits(br->mask));
}
uint32_t range = ~br->mask + 1; // the number of potential addresses
// this software is not supported for /31 networks
if (range < 4) {
@ -127,7 +127,7 @@ void net_configure_veth_pair(Bridge *br, const char *ifname, pid_t child) {
}
else
dev = br->veth_name;
char *cstr;
if (asprintf(&cstr, "%d", child) == -1)
errExit("asprintf");
@ -249,7 +249,7 @@ void net_dns_print(pid_t pid) {
}
free(comm);
}
char *fname;
EUID_ROOT();
if (asprintf(&fname, "/proc/%d/root/etc/resolv.conf", pid) == -1)
@ -261,7 +261,7 @@ void net_dns_print(pid_t pid) {
fprintf(stderr, "Error: cannot access /etc/resolv.conf\n");
exit(1);
}
char buf[MAXBUF];
while (fgets(buf, MAXBUF, fp))
printf("%s", buf);
@ -284,21 +284,21 @@ void network_main(pid_t child) {
else
sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 6, PATH_FNET, "create", "macvlan", cfg.bridge0.devsandbox, cfg.bridge0.dev, cstr);
}
if (cfg.bridge1.configured) {
if (cfg.bridge1.macvlan == 0)
net_configure_veth_pair(&cfg.bridge1, "eth1", child);
else
sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 6, PATH_FNET, "create", "macvlan", cfg.bridge1.devsandbox, cfg.bridge1.dev, cstr);
}
if (cfg.bridge2.configured) {
if (cfg.bridge2.macvlan == 0)
net_configure_veth_pair(&cfg.bridge2, "eth2", child);
else
sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 6, PATH_FNET, "create", "macvlan", cfg.bridge2.devsandbox, cfg.bridge2.dev, cstr);
}
if (cfg.bridge3.configured) {
if (cfg.bridge3.macvlan == 0)
net_configure_veth_pair(&cfg.bridge3, "eth3", child);

View file

@ -39,12 +39,12 @@ int is_container(const char *str) {
// returns 1 if we are running under LXC
int check_namespace_virt(void) {
EUID_ASSERT();
// check container environment variable
char *str = getenv("container");
if (str && is_container(str))
return 1;
// check PID 1 container environment variable
EUID_ROOT();
FILE *fp = fopen("/proc/1/environ", "r");
@ -62,7 +62,7 @@ int check_namespace_virt(void) {
break;
}
buf[i] = '\0';
// check env var name
if (strncmp(buf, "container=", 10) == 0) {
// found it
@ -74,10 +74,10 @@ int check_namespace_virt(void) {
}
// printf("i %d c %d, buf #%s#\n", i, c, buf);
}
fclose(fp);
}
EUID_USER();
return 0;
}
@ -104,7 +104,7 @@ int check_kernel_procs(void) {
// look at the first 10 processes
// if a kernel process is found, return 1
for (i = 1; i <= 10; i++) {
for (i = 1; i <= 10; i++) {
struct stat s;
char *fname;
if (asprintf(&fname, "/proc/%d/comm", i) == -1)
@ -113,7 +113,7 @@ int check_kernel_procs(void) {
free(fname);
continue;
}
// open file
/* coverity[toctou] */
FILE *fp = fopen(fname, "r");
@ -122,7 +122,7 @@ int check_kernel_procs(void) {
free(fname);
continue;
}
// read file
char buf[100];
if (fgets(buf, 10, fp) == NULL) {
@ -135,7 +135,7 @@ int check_kernel_procs(void) {
char *ptr;
if ((ptr = strchr(buf, '\n')) != NULL)
*ptr = '\0';
// check process name against the kernel list
int j = 0;
while (kern_proc[j] != NULL) {
@ -148,7 +148,7 @@ int check_kernel_procs(void) {
}
j++;
}
fclose(fp);
free(fname);
}

View file

@ -24,7 +24,7 @@
void check_output(int argc, char **argv) {
EUID_ASSERT();
int i;
int outindex = 0;
@ -49,7 +49,7 @@ void check_output(int argc, char **argv) {
fprintf(stderr, "Error: invalid output file. Links, directories and files with \"..\" are not allowed.\n");
exit(1);
}
struct stat s;
if (stat(outfile, &s) == 0) {
// check permissions
@ -57,7 +57,7 @@ void check_output(int argc, char **argv) {
fprintf(stderr, "Error: the output file needs to be owned by the current user.\n");
exit(1);
}
// check hard links
if (s.st_nlink != 1) {
fprintf(stderr, "Error: no hard links allowed.\n");
@ -71,11 +71,11 @@ void check_output(int argc, char **argv) {
len += strlen(argv[i]) + 1; // + ' '
}
len += 100 + strlen(LIBDIR) + strlen(outfile); // tee command
char *cmd = malloc(len + 1); // + '\0'
if (!cmd)
errExit("malloc");
char *ptr = cmd;
for (i = 0; i < argc; i++) {
if (strncmp(argv[i], "--output=", 9) == 0)
@ -91,7 +91,7 @@ void check_output(int argc, char **argv) {
a[2] = cmd;
a[3] = NULL;
execvp(a[0], a);
execvp(a[0], a);
perror("execvp");
exit(1);

View file

@ -35,27 +35,27 @@ void preproc_build_firejail_dir(void) {
if (stat(RUN_FIREJAIL_DIR, &s)) {
create_empty_dir_as_root(RUN_FIREJAIL_DIR, 0755);
}
if (stat(RUN_FIREJAIL_NETWORK_DIR, &s)) {
create_empty_dir_as_root(RUN_FIREJAIL_NETWORK_DIR, 0755);
}
if (stat(RUN_FIREJAIL_BANDWIDTH_DIR, &s)) {
create_empty_dir_as_root(RUN_FIREJAIL_BANDWIDTH_DIR, 0755);
}
if (stat(RUN_FIREJAIL_NAME_DIR, &s)) {
create_empty_dir_as_root(RUN_FIREJAIL_NAME_DIR, 0755);
}
if (stat(RUN_FIREJAIL_X11_DIR, &s)) {
create_empty_dir_as_root(RUN_FIREJAIL_X11_DIR, 0755);
}
if (stat(RUN_FIREJAIL_APPIMAGE_DIR, &s)) {
create_empty_dir_as_root(RUN_FIREJAIL_APPIMAGE_DIR, 0755);
}
if (stat(RUN_MNT_DIR, &s)) {
create_empty_dir_as_root(RUN_MNT_DIR, 0755);
}
@ -74,7 +74,7 @@ void preproc_mount_mnt_dir(void) {
errExit("mounting /run/firejail/mnt");
tmpfs_mounted = 1;
fs_logger2("tmpfs", RUN_MNT_DIR);
//copy defaultl seccomp files
copy_file(PATH_SECCOMP_I386, RUN_SECCOMP_I386, getuid(), getgid(), 0644); // root needed
copy_file(PATH_SECCOMP_AMD64, RUN_SECCOMP_AMD64, getuid(), getgid(), 0644); // root needed
@ -82,7 +82,7 @@ void preproc_mount_mnt_dir(void) {
copy_file(PATH_SECCOMP_DEFAULT_DEBUG, RUN_SECCOMP_CFG, getuid(), getgid(), 0644); // root needed
else
copy_file(PATH_SECCOMP_DEFAULT, RUN_SECCOMP_CFG, getuid(), getgid(), 0644); // root needed
// as root, create an empty RUN_SECCOMP_PROTOCOL file
create_empty_file_as_root(RUN_SECCOMP_PROTOCOL, 0644);
if (set_perms(RUN_SECCOMP_PROTOCOL, getuid(), getgid(), 0644))

View file

@ -34,7 +34,7 @@ void protocol_filter_save(void) {
void protocol_filter_load(const char *fname) {
assert(fname);
// read protocol filter configuration from PROTOCOL_CFG
FILE *fp = fopen(fname, "r");
if (!fp)
@ -48,7 +48,7 @@ void protocol_filter_load(const char *fname) {
return;
}
fclose(fp);
char *ptr = strchr(buf, '\n');
if (ptr)
*ptr = '\0';
@ -61,7 +61,7 @@ void protocol_filter_load(const char *fname) {
// --protocol.print
void protocol_print_filter(pid_t pid) {
EUID_ASSERT();
(void) pid;
#ifdef SYS_socket
// if the pid is that of a firejail process, use the pid of the first child process
@ -109,7 +109,7 @@ void protocol_print_filter(pid_t pid) {
#else
fwarning("--protocol not supported on this platform\n");
return;
#endif
#endif
}

View file

@ -27,17 +27,17 @@
static void disable_file(const char *path, const char *file) {
assert(file);
assert(path);
struct stat s;
char *fname;
if (asprintf(&fname, "%s/%s", path, file) == -1)
errExit("asprintf");
if (stat(fname, &s) == -1)
goto doexit;
if (arg_debug)
printf("Disable%s\n", fname);
if (S_ISDIR(s.st_mode)) {
if (mount(RUN_RO_DIR, fname, "none", MS_BIND, "mode=400,gid=0") < 0)
errExit("disable file");
@ -71,7 +71,7 @@ void pulseaudio_disable(void) {
errExit("asprintf");
disable_file(path, "pulse/native");
free(path);
// blacklist any pulse* file in /tmp directory
@ -99,11 +99,11 @@ void pulseaudio_disable(void) {
// disable shm in pulseaudio
void pulseaudio_init(void) {
struct stat s;
// do we have pulseaudio in the system?
if (stat("/etc/pulse/client.conf", &s) == -1)
return;
// create the new user pulseaudio directory
int rv = mkdir(RUN_PULSE_DIR, 0700);
(void) rv; // in --chroot mode the directory can already be there
@ -134,7 +134,7 @@ void pulseaudio_init(void) {
if (child == 0) {
// drop privileges
drop_privs(0);
int rv = mkdir(dir1, 0755);
if (rv == 0) {
if (set_perms(dir1, getuid(), getgid(), 0755))
@ -156,7 +156,7 @@ void pulseaudio_init(void) {
}
}
free(dir1);
if (asprintf(&dir1, "%s/.config/pulse", cfg.homedir) == -1)
errExit("asprintf");
if (stat(dir1, &s) == -1) {
@ -166,7 +166,7 @@ void pulseaudio_init(void) {
if (child == 0) {
// drop privileges
drop_privs(0);
int rv = mkdir(dir1, 0700);
if (rv == 0) {
if (set_perms(dir1, getuid(), getgid(), 0700))
@ -188,8 +188,8 @@ void pulseaudio_init(void) {
}
}
free(dir1);
// if we have ~/.config/pulse mount the new directory, else set environment variable
char *homeusercfg;
if (asprintf(&homeusercfg, "%s/.config/pulse", cfg.homedir) == -1)
@ -204,7 +204,7 @@ void pulseaudio_init(void) {
if (setenv("PULSE_CLIENTCONFIG", pulsecfg, 1) < 0)
errExit("setenv");
}
free(pulsecfg);
free(homeusercfg);
}

View file

@ -56,23 +56,23 @@ static USER_LIST *ulist_find(const char *user) {
return ptr;
ptr = ptr->next;
}
return NULL;
}
static void sanitize_home(void) {
assert(getuid() != 0); // this code works only for regular users
if (arg_debug)
printf("Cleaning /home directory\n");
struct stat s;
if (stat(cfg.homedir, &s) == -1) {
// cannot find home directory, just return
fwarning("cannot find home directory\n");
return;
}
if (mkdir(RUN_WHITELIST_HOME_DIR, 0755) == -1)
errExit("mkdir");
@ -93,7 +93,7 @@ static void sanitize_home(void) {
errExit("mkdir");
}
fs_logger2("mkdir", cfg.homedir);
// set mode and ownership
if (set_perms(cfg.homedir, s.st_uid, s.st_gid, s.st_mode))
errExit("set_perms");
@ -108,7 +108,7 @@ static void sanitize_home(void) {
fs_logger2("tmpfs", RUN_WHITELIST_HOME_DIR);
if (!arg_private)
fs_logger2("whitelist", cfg.homedir);
}
static void sanitize_passwd(void) {
@ -133,7 +133,7 @@ static void sanitize_passwd(void) {
fpout = fopen(RUN_PASSWD_FILE, "w");
if (!fpout)
goto errout;
// read the file line by line
char buf[MAXBUF];
uid_t myuid = getuid();
@ -141,12 +141,12 @@ static void sanitize_passwd(void) {
// comments and empty lines
if (*buf == '\0' || *buf == '#')
continue;
// sample line:
// www-data:x:33:33:www-data:/var/www:/bin/sh
// drop lines with uid > 1000 and not the current user
char *ptr = buf;
// advance to uid
while (*ptr != ':' && *ptr != '\0')
ptr++;
@ -190,9 +190,9 @@ static void sanitize_passwd(void) {
if (mount(RUN_PASSWD_FILE, "/etc/passwd", "none", MS_BIND, "mode=400,gid=0") < 0)
errExit("mount");
fs_logger("create /etc/passwd");
return;
return;
errout:
fwarning("failed to clean up /etc/passwd\n");
if (fpin)
@ -206,7 +206,7 @@ static int copy_line(FILE *fpout, char *buf, char *ptr) {
// fpout: GROUP_FILE
// buf: pulse:x:115:netblue,bingo
// ptr: 115:neblue,bingo
while (*ptr != ':' && *ptr != '\0')
ptr++;
if (*ptr == '\0')
@ -217,7 +217,7 @@ static int copy_line(FILE *fpout, char *buf, char *ptr) {
fprintf(fpout, "%s", buf);
return 0;
}
// print what we have so far
char tmp = *ptr;
*ptr = '\0';
@ -266,7 +266,7 @@ static void sanitize_group(void) {
fpout = fopen(RUN_GROUP_FILE, "w");
if (!fpout)
goto errout;
// read the file line by line
char buf[MAXBUF];
gid_t mygid = getgid();
@ -274,12 +274,12 @@ static void sanitize_group(void) {
// comments and empty lines
if (*buf == '\0' || *buf == '#')
continue;
// sample line:
// pulse:x:115:netblue,bingo
// drop lines with uid > 1000 and not the current user group
char *ptr = buf;
// advance to uid
while (*ptr != ':' && *ptr != '\0')
ptr++;
@ -318,9 +318,9 @@ static void sanitize_group(void) {
if (mount(RUN_GROUP_FILE, "/etc/group", "none", MS_BIND, "mode=400,gid=0") < 0)
errExit("mount");
fs_logger("create /etc/group");
return;
return;
errout:
fwarning("failed to clean up /etc/group\n");
if (fpin)
@ -332,7 +332,7 @@ errout:
void restrict_users(void) {
if (arg_allusers)
return;
// only in user mode
if (getuid()) {
if (strncmp(cfg.homedir, "/home/", 6) == 0) {

View file

@ -44,7 +44,7 @@ int restricted_shell(const char *user) {
// remove empty spaces at the beginning of the line
char *ptr = buf;
while (*ptr == ' ' || *ptr == '\t') {
while (*ptr == ' ' || *ptr == '\t') {
ptr++;
}
if (*ptr == '\n' || *ptr == '#')
@ -53,7 +53,7 @@ int restricted_shell(const char *user) {
//
// parse line
//
// extract users
char *usr = ptr;
char *args = strchr(usr, ':');
@ -61,13 +61,13 @@ int restricted_shell(const char *user) {
fprintf(stderr, "Error: users.conf line %d\n", lineno);
exit(1);
}
*args = '\0';
args++;
ptr = strchr(args, '\n');
if (ptr)
*ptr = '\0';
// extract firejail command line arguments
char *ptr2 = args;
int found = 0;
@ -81,7 +81,7 @@ int restricted_shell(const char *user) {
// if nothing follows, continue
if (!found)
continue;
// user name globbing
if (fnmatch(usr, user, 0) == 0) {
// process program arguments
@ -102,8 +102,8 @@ int restricted_shell(const char *user) {
fclose(fp);
}
EUID_USER();}
#endif
#endif
if (*ptr != '\0') {
// go to the end of the word
while (*ptr != ' ' && *ptr != '\t' && *ptr != '\0')
@ -128,6 +128,5 @@ int restricted_shell(const char *user) {
}
fclose(fp);
return 0;
return 0;
}

View file

@ -47,7 +47,7 @@ void set_rlimits(void) {
if (arg_debug)
printf("Config rlimit: number of processes %llu\n", cfg.rlimit_nproc);
}
if (arg_rlimit_fsize) {
rl.rlim_cur = (rlim_t) cfg.rlimit_fsize;
rl.rlim_max = (rlim_t) cfg.rlimit_fsize;
@ -59,7 +59,7 @@ void set_rlimits(void) {
if (arg_debug)
printf("Config rlimit: maximum file size %llu\n", cfg.rlimit_fsize);
}
if (arg_rlimit_sigpending) {
rl.rlim_cur = (rlim_t) cfg.rlimit_sigpending;
rl.rlim_max = (rlim_t) cfg.rlimit_sigpending;

View file

@ -24,7 +24,7 @@
void run_symlink(int argc, char **argv) {
EUID_ASSERT();
char *program = strrchr(argv[0], '/');
if (program)
program += 1;
@ -40,7 +40,7 @@ void run_symlink(int argc, char **argv) {
fprintf(stderr, "Error: PATH environment variable not set\n");
exit(1);
}
char *path = strdup(p);
if (!path)
errExit("strdup");
@ -105,8 +105,8 @@ void run_symlink(int argc, char **argv) {
a[i + 2] = argv[i + 1];
}
a[i + 2] = NULL;
assert(getenv("LD_PRELOAD") == NULL);
execvp(a[0], a);
assert(getenv("LD_PRELOAD") == NULL);
execvp(a[0], a);
perror("execvp");
exit(1);

View file

@ -39,28 +39,28 @@ static struct sock_filter filter[] = {
#endif
// syscall list
#ifdef SYS_mount
#ifdef SYS_mount
BLACKLIST(SYS_mount), // mount/unmount filesystems
#endif
#ifdef SYS_umount2
#ifdef SYS_umount2
BLACKLIST(SYS_umount2),
#endif
#ifdef SYS_ptrace
#ifdef SYS_ptrace
BLACKLIST(SYS_ptrace), // trace processes
#endif
#ifdef SYS_kexec_file_load
#ifdef SYS_kexec_file_load
BLACKLIST(SYS_kexec_file_load),
#endif
#ifdef SYS_kexec_load
#ifdef SYS_kexec_load
BLACKLIST(SYS_kexec_load), // loading a different kernel
#endif
#ifdef SYS_name_to_handle_at
#ifdef SYS_name_to_handle_at
BLACKLIST(SYS_name_to_handle_at),
#endif
#ifdef SYS_open_by_handle_at
#ifdef SYS_open_by_handle_at
BLACKLIST(SYS_open_by_handle_at), // open by handle
#endif
#ifdef SYS_init_module
#ifdef SYS_init_module
BLACKLIST(SYS_init_module), // kernel module handling
#endif
#ifdef SYS_finit_module // introduced in 2013
@ -69,31 +69,31 @@ static struct sock_filter filter[] = {
#ifdef SYS_create_module
BLACKLIST(SYS_create_module),
#endif
#ifdef SYS_delete_module
#ifdef SYS_delete_module
BLACKLIST(SYS_delete_module),
#endif
#ifdef SYS_iopl
#ifdef SYS_iopl
BLACKLIST(SYS_iopl), // io permissions
#endif
#ifdef SYS_ioperm
#ifdef SYS_ioperm
BLACKLIST(SYS_ioperm),
#endif
#ifdef SYS_iopl
#ifdef SYS_iopl
BLACKLIST(SYS_iopl), // io permissions
#endif
#ifdef SYS_ioprio_set
#ifdef SYS_ioprio_set
BLACKLIST(SYS_ioprio_set),
#endif
#ifdef SYS_ni_syscall // new io permissions call on arm devices
BLACKLIST(SYS_ni_syscall),
#endif
#ifdef SYS_swapon
#ifdef SYS_swapon
BLACKLIST(SYS_swapon), // swap on/off
#endif
#ifdef SYS_swapoff
#ifdef SYS_swapoff
BLACKLIST(SYS_swapoff),
#endif
#ifdef SYS_syslog
#ifdef SYS_syslog
BLACKLIST(SYS_syslog), // kernel printk control
#endif
RETURN_ALLOW
@ -113,7 +113,7 @@ typedef struct sbox_config {
int sbox_run(unsigned filter, int num, ...) {
EUID_ROOT();
int i;
va_list valist;
va_start(valist, num);
@ -124,7 +124,7 @@ int sbox_run(unsigned filter, int num, ...) {
arg[i] = va_arg(valist, char*);
arg[i] = NULL;
va_end(valist);
if (arg_debug) {
printf("sbox run: ");
for (i = 0; i <= num; i++)
@ -138,7 +138,7 @@ int sbox_run(unsigned filter, int num, ...) {
if (child == 0) {
// clean the new process
clearenv();
if (filter & SBOX_STDIN_FROM_FILE) {
int fd;
if((fd = open(SBOX_STDIN_FILE, O_RDONLY)) == -1) {
@ -154,7 +154,7 @@ int sbox_run(unsigned filter, int num, ...) {
else // the user could run the sandbox without /dev/null
close(STDIN_FILENO);
}
// close all other file descriptors
int max = 20; // getdtablesize() is overkill for a firejail process
for (i = 3; i < max; i++)
@ -163,10 +163,10 @@ int sbox_run(unsigned filter, int num, ...) {
if (arg_debug) {
printf("sbox file descriptors:\n");
int rv = system("ls -l /proc/self/fd");
(void) rv;
(void) rv;
}
umask(027);
umask(027);
// apply filters
if (filter & SBOX_CAPS_NONE) {
@ -178,7 +178,7 @@ int sbox_run(unsigned filter, int num, ...) {
set |= ((uint64_t) 1) << CAP_NET_RAW;
caps_set(set);
#endif
}
}
if (filter & SBOX_SECCOMP) {
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
@ -200,11 +200,11 @@ int sbox_run(unsigned filter, int num, ...) {
drop_privs(1);
clearenv();
// --quiet is passed as an environment variable
if (arg_quiet)
setenv("FIREJAIL_QUIET", "yes", 1);
if (arg[0]) // get rid of scan-build warning
execvp(arg[0], arg);
else
@ -221,6 +221,6 @@ int sbox_run(unsigned filter, int num, ...) {
fprintf(stderr, "Error: failed to run %s\n", arg[0]);
exit(1);
}
return status;
}

View file

@ -30,13 +30,13 @@ char *seccomp_check_list(const char *str) {
fprintf(stderr, "Error: empty syscall lists are not allowed\n");
exit(1);
}
int len = strlen(str) + 1;
char *rv = malloc(len);
if (!rv)
errExit("malloc");
memset(rv, 0, len);
const char *ptr1 = str;
char *ptr2 = rv;
while (*ptr1 != '\0') {
@ -47,14 +47,14 @@ char *seccomp_check_list(const char *str) {
exit(1);
}
}
return rv;
}
int seccomp_load(const char *fname) {
assert(fname);
// open filter file
int fd = open(fname, O_RDONLY);
if (fd == -1)
@ -82,7 +82,7 @@ int seccomp_load(const char *fname) {
goto errexit;
rd += rv;
}
// close file
close(fd);
@ -97,9 +97,9 @@ int seccomp_load(const char *fname) {
err_printed = 1;
return 1;
}
return 0;
errexit:
fprintf(stderr, "Error: cannot read %s\n", fname);
exit(1);
@ -142,7 +142,7 @@ int seccomp_filter_drop(int enforce_seccomp) {
#endif
if (arg_debug)
printf("Build default+drop seccomp filter\n");
// build the seccomp filter as a regular user
int rv;
if (arg_allow_debuggers)
@ -154,7 +154,7 @@ int seccomp_filter_drop(int enforce_seccomp) {
if (rv)
exit(rv);
}
// drop list without defaults - secondary filters are not installed
else if (cfg.seccomp_list == NULL && cfg.seccomp_list_drop) {
if (arg_debug)
@ -175,7 +175,7 @@ int seccomp_filter_drop(int enforce_seccomp) {
else {
assert(0);
}
// load the filter
if (seccomp_load(RUN_SECCOMP_CFG) == 0) {
if (arg_debug)
@ -185,7 +185,7 @@ int seccomp_filter_drop(int enforce_seccomp) {
fprintf(stderr, "Error: a seccomp-enabled Linux kernel is required, exiting...\n");
exit(1);
}
if (arg_debug && access(PATH_FSECCOMP, X_OK) == 0)
sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 3,
PATH_FSECCOMP, "print", RUN_SECCOMP_CFG);
@ -197,14 +197,14 @@ int seccomp_filter_drop(int enforce_seccomp) {
int seccomp_filter_keep(void) {
if (arg_debug)
printf("Build drop seccomp filter\n");
// build the seccomp filter as a regular user
sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 4,
PATH_FSECCOMP, "keep", RUN_SECCOMP_CFG, cfg.seccomp_list_keep);
if (arg_debug)
printf("seccomp filter configured\n");
return seccomp_load(RUN_SECCOMP_CFG);
}
@ -255,4 +255,3 @@ void seccomp_print_filter(pid_t pid) {
}
#endif // HAVE_SECCOMP

View file

@ -25,7 +25,7 @@
void shut(pid_t pid) {
EUID_ASSERT();
pid_t parent = pid;
// if the pid is that of a firejail process, use the pid of a child process inside the sandbox
EUID_ROOT();
@ -57,11 +57,11 @@ void shut(pid_t pid) {
exit(1);
}
}
EUID_ROOT();
printf("Sending SIGTERM to %u\n", pid);
kill(pid, SIGTERM);
// wait for not more than 10 seconds
sleep(2);
int monsec = 8;
@ -76,7 +76,7 @@ void shut(pid_t pid) {
killdone = 1;
break;
}
char c;
size_t count = fread(&c, 1, 1, fp);
fclose(fp);
@ -102,6 +102,6 @@ void shut(pid_t pid) {
kill(parent, SIGKILL);
}
}
clear_run_files(parent);
}

View file

@ -118,7 +118,7 @@ int mkpath_as_root(const char* path) {
void fwarning(char* fmt, ...) {
if (arg_quiet)
return;
va_list args;
va_start(args,fmt);
fprintf(stderr, "Warning: ");
@ -786,7 +786,7 @@ static int remove_callback(const char *fpath, const struct stat *sb, int typefla
(void) sb;
(void) typeflag;
(void) ftwbuf;
int rv = remove(fpath);
if (rv)
perror(fpath);
@ -816,7 +816,7 @@ void create_empty_dir_as_root(const char *dir, mode_t mode) {
assert(dir);
mode &= 07777;
struct stat s;
if (stat(dir, &s)) {
if (arg_debug)
printf("Creating empty %s directory\n", dir);
@ -862,7 +862,7 @@ int set_perms(const char *fname, uid_t uid, gid_t gid, mode_t mode) {
void mkdir_attr(const char *fname, mode_t mode, uid_t uid, gid_t gid) {
assert(fname);
mode &= 07777;
#if 0
#if 0
printf("fname %s, uid %d, gid %d, mode %x - ", fname, uid, gid, (unsigned) mode);
if (S_ISLNK(mode))
printf("l");
@ -886,7 +886,7 @@ void mkdir_attr(const char *fname, mode_t mode, uid_t uid, gid_t gid) {
printf( (mode & S_IWOTH) ? "w" : "-");
printf( (mode & S_IXOTH) ? "x" : "-");
printf("\n");
#endif
#endif
if (mkdir(fname, mode) == -1 ||
chmod(fname, mode) == -1 ||
chown(fname, uid, gid)) {
@ -899,7 +899,7 @@ void mkdir_attr(const char *fname, mode_t mode, uid_t uid, gid_t gid) {
char *read_text_file_or_exit(const char *fname) {
assert(fname);
// open file
int fd = open(fname, O_RDONLY);
if (fd == -1) {
@ -912,7 +912,7 @@ char *read_text_file_or_exit(const char *fname) {
goto errexit;
if (lseek(fd, 0 , SEEK_SET) == -1)
goto errexit;
// allocate memory
char *data = malloc(size + 1); // + '\0'
if (data == NULL)
@ -928,11 +928,11 @@ char *read_text_file_or_exit(const char *fname) {
}
rd += rv;
}
// close file
close(fd);
return data;
errexit:
close(fd);
fprintf(stderr, "Error: cannot read %s\n", fname);

View file

@ -639,7 +639,7 @@ void x11_start_xpra(int argc, char **argv) {
// build the start command
char *server_argv[256] = { // rest initialyzed to NULL
"xpra", "start", display_str, "--no-daemon",
"xpra", "start", display_str, "--no-daemon",
};
unsigned pos = 0;
while (server_argv[pos] != NULL) pos++;
@ -696,7 +696,7 @@ void x11_start_xpra(int argc, char **argv) {
// no overrun
assert(pos < (sizeof(server_argv)/sizeof(*server_argv)));
assert(server_argv[pos-1] == NULL); // last element is null
if (arg_debug) {
size_t i = 0;
printf("\n*** Starting xpra server: ");
@ -820,7 +820,7 @@ void x11_start_xpra(int argc, char **argv) {
printf("Xpra server pid %d, xpra client pid %d, jail %d\n", server, client, jail);
sleep(1); // adding a delay in order to let the server start
// wait for jail or server to end
while (1) {
pid_t pid = wait(NULL);

View file

@ -12,7 +12,7 @@ C_FILE_LIST = $(sort $(wildcard *.c))
OBJS = $(C_FILE_LIST:.c=.o)
BINOBJS = $(foreach file, $(OBJS), $file)
CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' $(HAVE_GCOV) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security
LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now
LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now
HAVE_GCOV=@HAVE_GCOV@
EXTRA_LDFLAGS +=@EXTRA_LDFLAGS@
@ -27,4 +27,3 @@ clean:; rm -f *.o firemon *.gcov *.gcda *.gcno
distclean: clean
rm -fr Makefile

View file

@ -24,7 +24,7 @@ static void print_arp(const char *fname) {
FILE *fp = fopen(fname, "r");
if (!fp)
return;
printf(" ARP Table:\n");
char buf[MAXBUF];
while (fgets(buf, MAXBUF, fp)) {
@ -54,7 +54,7 @@ static void print_arp(const char *fname) {
int rv = sscanf(start, "%s %s %s %s %s %s\n", ip, type, flags, mac, mask, device);
if (rv != 6)
continue;
// destination ip
unsigned a, b, c, d;
if (sscanf(ip, "%u.%u.%u.%u", &a, &b, &c, &d) != 4 || a > 255 || b > 255 || c > 255 || d > 255)
@ -67,14 +67,14 @@ static void print_arp(const char *fname) {
printf(" %d.%d.%d.%d dev %s lladdr %s REACHABLE\n",
PRINT_IP(destip), device, mac);
}
fclose(fp);
}
void arp(pid_t pid, int print_procs) {
pid_read(pid);
// print processes
int i;
for (i = 0; i < max_pids; i++) {
@ -93,5 +93,3 @@ void arp(pid_t pid, int print_procs) {
}
printf("\n");
}

View file

@ -32,7 +32,7 @@ static void print_caps(int pid) {
free(file);
return;
}
char buf[MAXBUF];
while (fgets(buf, MAXBUF, fp)) {
if (strncmp(buf, "CapBnd:", 7) == 0) {
@ -44,10 +44,10 @@ static void print_caps(int pid) {
fclose(fp);
free(file);
}
void caps(pid_t pid, int print_procs) {
pid_read(pid); // include all processes
// print processes
int i;
for (i = 0; i < max_pids; i++) {
@ -61,4 +61,3 @@ void caps(pid_t pid, int print_procs) {
}
printf("\n");
}

View file

@ -33,7 +33,7 @@ static void print_cgroup(int pid) {
free(file);
return;
}
char buf[MAXBUF];
if (fgets(buf, MAXBUF, fp)) {
printf(" %s", buf);
@ -43,10 +43,10 @@ static void print_cgroup(int pid) {
fclose(fp);
free(file);
}
void cgroup(pid_t pid, int print_procs) {
pid_read(pid);
// print processes
int i;
for (i = 0; i < max_pids; i++) {
@ -60,4 +60,3 @@ void cgroup(pid_t pid, int print_procs) {
}
printf("\n");
}

View file

@ -33,7 +33,7 @@ static void print_cpu(int pid) {
free(file);
return;
}
char buf[MAXBUF];
while (fgets(buf, MAXBUF, fp)) {
if (strncmp(buf, "Cpus_allowed_list:", 18) == 0) {
@ -45,10 +45,10 @@ static void print_cpu(int pid) {
fclose(fp);
free(file);
}
void cpu(pid_t pid, int print_procs) {
pid_read(pid);
// print processes
int i;
for (i = 0; i < max_pids; i++) {
@ -62,4 +62,3 @@ void cpu(pid_t pid, int print_procs) {
}
printf("\n");
}

View file

@ -24,7 +24,7 @@
#include <sys/prctl.h>
#include <grp.h>
#include <sys/stat.h>
static int arg_route = 0;
static int arg_arp = 0;
static int arg_tree = 0;
@ -49,7 +49,7 @@ static void my_handler(int s){
if (terminal_set)
tcsetattr(0, TCSANOW, &tlocal);
exit(0);
exit(0);
}
// find the first child process for the specified pid
@ -60,7 +60,7 @@ int find_child(int id) {
if (pids[i].level == 2 && pids[i].parent == id)
return i;
}
return -1;
}
@ -118,7 +118,7 @@ int main(int argc, char **argv) {
printf("firemon version %s\n\n", VERSION);
return 0;
}
// options without a pid argument
else if (strcmp(argv[i], "--top") == 0)
arg_top = 1;
@ -131,7 +131,7 @@ int main(int argc, char **argv) {
if (getuid() != 0 && stat("/proc/sys/kernel/grsecurity", &s) == 0) {
fprintf(stderr, "Error: this feature is not available on Grsecurity systems\n");
exit(1);
}
}
arg_netstats = 1;
}
@ -166,17 +166,17 @@ int main(int argc, char **argv) {
return 1;
}
}
// etc
else if (strcmp(argv[i], "--nowrap") == 0)
arg_nowrap = 1;
// invalid option
else if (*argv[i] == '-') {
fprintf(stderr, "Error: invalid option\n");
fprintf(stderr, "Error: invalid option\n");
return 1;
}
// PID argument
else {
// this should be a pid number
@ -199,9 +199,9 @@ int main(int argc, char **argv) {
fprintf(stderr, "Error: /proc is mounted hidepid, you would need to be root to run this command\n");
exit(1);
}
if (arg_top) {
top();
top();
return 0;
}
if (arg_list) {
@ -210,9 +210,9 @@ int main(int argc, char **argv) {
}
if (arg_netstats) {
netstats();
return 0;
return 0;
}
// cumulative options
int print_procs = 1;
if (arg_tree) {
@ -251,9 +251,9 @@ int main(int argc, char **argv) {
arp((pid_t) pid, print_procs);
print_procs = 0;
}
if (print_procs)
procevent((pid_t) pid);
return 0;
}

View file

@ -64,13 +64,13 @@ static void net_ifprint(void) {
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, ifa->ifa_name, IFNAMSIZ);
int rv = ioctl (fd, SIOCGIFHWADDR, &ifr);
if (rv == 0)
printf(" %s UP, %02x:%02x:%02x:%02x:%02x:%02x\n",
ifa->ifa_name, PRINT_MAC((unsigned char *) &ifr.ifr_hwaddr.sa_data));
else
printf(" %s UP\n", ifa->ifa_name);
printf(" tx/rx: %u/%u packets, %u/%u bytes\n",
stats->tx_packets, stats->rx_packets,
stats->tx_bytes, stats->rx_bytes);
@ -78,7 +78,7 @@ static void net_ifprint(void) {
}
else
printf(" %s DOWN\n", ifa->ifa_name);
}
}
}
@ -139,7 +139,7 @@ static void print_sandbox(pid_t pid) {
pid_t child = fork();
if (child == -1)
return;
if (child == 0) {
int rv = join_namespace(pid, "net");
if (rv)
@ -150,14 +150,14 @@ static void print_sandbox(pid_t pid) {
#endif
_exit(0);
}
// wait for the child to finish
waitpid(child, NULL, 0);
}
void interface(pid_t pid, int print_procs) {
pid_read(pid); // a pid of 0 will include all processes
// print processes
int i;
for (i = 0; i < max_pids; i++) {
@ -172,4 +172,3 @@ void interface(pid_t pid, int print_procs) {
}
printf("\n");
}

View file

@ -21,7 +21,7 @@
void list(void) {
pid_read(0); // include all processes
// print processes
int i;
for (i = 0; i < max_pids; i++) {
@ -29,4 +29,3 @@ void list(void) {
pid_print_list(i, arg_nowrap);
}
}

View file

@ -35,7 +35,7 @@ static char *get_header(void) {
if (asprintf(&rv, "%-5.5s %-9.9s %-10.10s %-10.10s %s",
"PID", "User", "RX(KB/s)", "TX(KB/s)", "Command") == -1)
errExit("asprintf");
return rv;
}
@ -59,7 +59,7 @@ void get_stats(int parent) {
free(fname);
goto errexit;
}
char buf[MAXBUF];
long long unsigned rx = 0;
long long unsigned tx = 0;
@ -68,19 +68,19 @@ void get_stats(int parent) {
continue;
if (strncmp(buf, " face", 5) == 0)
continue;
char *ptr = buf;
while (*ptr != '\0' && *ptr != ':') {
ptr++;
}
if (*ptr == '\0') {
fclose(fp);
free(fname);
goto errexit;
}
ptr++;
long long unsigned rxval;
long long unsigned txval;
unsigned a, b, c, d, e, f, g;
@ -101,7 +101,7 @@ void get_stats(int parent) {
fclose(fp);
return;
errexit:
errexit:
pids[parent].rx = 0;
pids[parent].tx = 0;
pids[parent].rx_delta = 0;
@ -121,7 +121,7 @@ static void print_proc(int index, int itv, int col) {
}
else
ptrcmd = cmd;
// check network namespace
char *name;
if (asprintf(&name, "/run/firejail/network/%d-netmap", index) == -1)
@ -145,35 +145,35 @@ static void print_proc(int index, int itv, int col) {
ptruser = user;
else
ptruser = "";
float rx_kbps = ((float) pids[index].rx_delta / 1000) / itv;
char ptrrx[15];
sprintf(ptrrx, "%.03f", rx_kbps);
float tx_kbps = ((float) pids[index].tx_delta / 1000) / itv;
char ptrtx[15];
sprintf(ptrtx, "%.03f", tx_kbps);
char buf[1024 + 1];
snprintf(buf, 1024, "%-5.5s %-9.9s %-10.10s %-10.10s %s",
pidstr, ptruser, ptrrx, ptrtx, ptrcmd);
if (col < 1024)
buf[col] = '\0';
printf("%s\n", buf);
if (cmd)
free(cmd);
if (user)
free(user);
}
void netstats(void) {
pid_read(0); // include all processes
printf("Displaying network statistics only for sandboxes using a new network namespace.\n");
// print processes
while (1) {
// set pid table
@ -186,10 +186,10 @@ void netstats(void) {
if (pids[i].level == 1)
get_stats(i);
}
// wait 5 seconds
firemon_sleep(itv);
// grab screen size
struct winsize sz;
int row = 24;
@ -198,7 +198,7 @@ void netstats(void) {
col = sz.ws_col;
row = sz.ws_row;
}
// start printing
firemon_clrscr();
char *header = get_header();
@ -221,4 +221,3 @@ void netstats(void) {
#endif
}
}

View file

@ -40,12 +40,12 @@ static int pid_is_firejail(pid_t pid) {
printf("%s: %d, pid %d\n", __FUNCTION__, __LINE__, pid);
#endif
uid_t rv = 0;
// open /proc/self/comm
char *file;
if (asprintf(&file, "/proc/%u/comm", pid) == -1)
errExit("asprintf");
FILE *fp = fopen(file, "r");
if (!fp) {
free(file);
@ -58,7 +58,7 @@ static int pid_is_firejail(pid_t pid) {
if (strncmp(buf, "firejail", 8) == 0)
rv = 1;
}
#ifdef DEBUG_PRCTL
printf("%s: %d, comm %s, rv %d\n", __FUNCTION__, __LINE__, buf, rv);
#endif
@ -76,7 +76,7 @@ static int pid_is_firejail(pid_t pid) {
goto doexit;
}
free(fname);
// read file
#define BUFLEN 4096
unsigned char buffer[BUFLEN];
@ -90,16 +90,16 @@ static int pid_is_firejail(pid_t pid) {
}
buffer[len] = '\0';
close(fd);
// list of firejail arguments that don't trigger sandbox creation
// the initial -- is not included
// the initial -- is not included
char *exclude_args[] = {
"ls", "list", "tree", "x11", "help", "version", "top", "netstats", "debug-syscalls",
"debug-errnos", "debug-protocols", "protocol.print", "debug.caps",
"debug-errnos", "debug-protocols", "protocol.print", "debug.caps",
"shutdown", "bandwidth", "caps.print", "cpu.print", "debug-caps",
"fs.print", "get", "overlay-clean", NULL
};
int i;
char *start;
int first = 1;
@ -114,30 +114,30 @@ static int pid_is_firejail(pid_t pid) {
if (strncmp(start, "--", 2) != 0)
break;
start += 2;
// clan starting with =
char *ptr = strchr(start, '=');
if (ptr)
*ptr = '\0';
// look into exclude list
int j = 0;
while (exclude_args[j] != NULL) {
if (strcmp(start, exclude_args[j]) == 0) {
rv = 0;
#ifdef DEBUG_PRCTL
printf("start=#%s#, ptr=#%s#, flip rv %d\n", start, ptr, rv);
printf("start=#%s#, ptr=#%s#, flip rv %d\n", start, ptr, rv);
#endif
break;
}
j++;
}
start = (char *) buffer + i + 1;
}
}
doexit:
doexit:
fclose(fp);
free(file);
#ifdef DEBUG_PRCTL
@ -187,7 +187,7 @@ static int procevent_netlink_setup(void) {
if (writev(sock, iov, 3) == -1)
goto errexit;
return sock;
errexit:
fprintf(stderr, "Error: netlink socket problem\n");
@ -209,29 +209,29 @@ static int procevent_monitor(const int sock, pid_t mypid) {
__gcov_flush();
#endif
#define BUFFSIZE 4096
#define BUFFSIZE 4096
char __attribute__ ((aligned(NLMSG_ALIGNTO)))buf[BUFFSIZE];
fd_set readfds;
int max;
FD_ZERO(&readfds);
FD_SET(sock, &readfds);
max = sock;
max++;
int rv = select(max, &readfds, NULL, NULL, &tv);
if (rv == -1) {
fprintf(stderr, "recv: %s\n", strerror(errno));
return -1;
}
// timeout
if (rv == 0) {
tv.tv_sec = 30;
tv.tv_usec = 0;
continue;
}
if ((len = recv(sock, buf, sizeof(buf), 0)) == 0) {
return 0;
@ -304,7 +304,7 @@ static int procevent_monitor(const int sock, pid_t mypid) {
}
sprintf(lineptr, " exec");
break;
case PROC_EVENT_EXIT:
if (proc_ev->event_data.exit.process_pid !=
proc_ev->event_data.exit.process_tgid)
@ -317,7 +317,7 @@ static int procevent_monitor(const int sock, pid_t mypid) {
remove_pid = 1;
sprintf(lineptr, " exit");
break;
case PROC_EVENT_UID:
pid = proc_ev->event_data.id.process_tgid;
#ifdef DEBUG_PRCTL
@ -363,11 +363,11 @@ static int procevent_monitor(const int sock, pid_t mypid) {
continue;
}
}
lineptr += strlen(lineptr);
sprintf(lineptr, " %u", pid);
lineptr += strlen(lineptr);
char *user = pids[pid].user;
if (!user)
user = pid_get_user_name(pids[pid].uid);
@ -376,7 +376,7 @@ static int procevent_monitor(const int sock, pid_t mypid) {
sprintf(lineptr, " (%s)", user);
lineptr += strlen(lineptr);
}
int sandbox_closed = 0; // exit sandbox flag
char *cmd = pids[pid].cmd;
@ -409,11 +409,11 @@ static int procevent_monitor(const int sock, pid_t mypid) {
lineptr += strlen(lineptr);
}
(void) lineptr;
// print the event
printf("%s", line);
printf("%s", line);
fflush(0);
// unflag pid for exit events
if (remove_pid) {
if (pids[pid].user)
@ -433,15 +433,15 @@ static int procevent_monitor(const int sock, pid_t mypid) {
else
printf("\tchild %u\n", child);
}
// on uid events the uid is changing
if (proc_ev->what == PROC_EVENT_UID) {
if (pids[pid].user)
free(pids[pid].user);
pids[pid].user = 0;
pids[pid].uid = pid_get_uid(pid);
pids[pid].uid = pid_get_uid(pid);
}
if (sandbox_closed)
exit(0);
}

View file

@ -36,7 +36,7 @@ static IfList *list_find(uint32_t ip, uint32_t mask) {
return ptr;
ptr = ptr->next;
}
return NULL;
}
@ -47,15 +47,15 @@ static void extract_if(const char *fname) {
free(ifs);
ifs = tmp;
}
assert(ifs == NULL);
assert(ifs == NULL);
FILE *fp = fopen(fname, "r");
if (!fp)
return;
char buf[MAXBUF];
int state = 0; // 0 -wait for Local
//
//
while (fgets(buf, MAXBUF, fp)) {
// remove blanks, \n
char *ptr = buf;
@ -67,7 +67,7 @@ static void extract_if(const char *fname) {
ptr = strchr(ptr, '\n');
if (ptr)
*ptr = '\0';
if (state == 0) {
if (strncmp(buf, "Local:", 6) == 0) {
state = 1;
@ -105,7 +105,7 @@ static void extract_if(const char *fname) {
}
}
}
fclose(fp);
@ -115,7 +115,7 @@ static void print_route(const char *fname) {
FILE *fp = fopen(fname, "r");
if (!fp)
return;
printf(" Route table:\n");
char buf[MAXBUF];
while (fgets(buf, MAXBUF, fp)) {
@ -147,7 +147,7 @@ static void print_route(const char *fname) {
int rv = sscanf(start, "%s %s %s %s %s %s %s %s\n", ifname, destination, gateway, flags, refcnt, use, metric, mask);
if (rv != 8)
continue;
// destination ip
uint32_t destip;
sscanf(destination, "%x", &destip);
@ -158,7 +158,7 @@ static void print_route(const char *fname) {
uint32_t gw;
sscanf(gateway, "%x", &gw);
gw = ntohl(gw);
// printf("#%s# #%s# #%s# #%s# #%s# #%s# #%s# #%s#\n", ifname, destination, gateway, flags, refcnt, use, metric, mask);
if (gw != 0)
printf(" %u.%u.%u.%u/%u via %u.%u.%u.%u, dev %s, metric %s\n",
@ -176,14 +176,14 @@ static void print_route(const char *fname) {
}
}
}
fclose(fp);
}
void route(pid_t pid, int print_procs) {
pid_read(pid);
// print processes
int i;
for (i = 0; i < max_pids; i++) {
@ -207,5 +207,3 @@ void route(pid_t pid, int print_procs) {
}
printf("\n");
}

View file

@ -31,7 +31,7 @@ static void print_seccomp(int pid) {
free(file);
return;
}
char buf[MAXBUF];
while (fgets(buf, MAXBUF, fp)) {
if (strncmp(buf, "Seccomp:", 8) == 0) {
@ -43,10 +43,10 @@ static void print_seccomp(int pid) {
fclose(fp);
free(file);
}
void seccomp(pid_t pid, int print_procs) {
pid_read(pid); // include all processes
// print processes
int i;
for (i = 0; i < max_pids; i++) {
@ -60,4 +60,3 @@ void seccomp(pid_t pid, int print_procs) {
}
printf("\n");
}

View file

@ -23,7 +23,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
static unsigned pgs_rss = 0;
static unsigned pgs_shared = 0;
static unsigned clocktick = 0;
@ -40,7 +40,7 @@ static char *get_user_name(uid_t uid) {
}
else if (uid == cached_uid)
return strdup(cached_user_name);
else
else
return pid_get_user_name(uid);
}
@ -49,7 +49,7 @@ static char *get_header(void) {
if (asprintf(&rv, "%-5.5s %-9.9s %-8.8s %-8.8s %-5.5s %-4.4s %-9.9s %s",
"PID", "User", "RES(KiB)", "SHR(KiB)", "CPU%", "Prcs", "Uptime", "Command") == -1)
errExit("asprintf");
return rv;
}
@ -66,7 +66,7 @@ static char *print_top(unsigned index, unsigned parent, unsigned *utime, unsigne
struct stat s;
if (stat(procdir, &s) == -1)
return NULL;
if (pids[index].level == 1) {
pgs_rss = 0;
pgs_shared = 0;
@ -74,7 +74,7 @@ static char *print_top(unsigned index, unsigned parent, unsigned *utime, unsigne
*stime = 0;
*cnt = 0;
}
(*cnt)++;
pid_getmem(index, &pgs_rss, &pgs_shared);
unsigned utmp;
@ -82,8 +82,8 @@ static char *print_top(unsigned index, unsigned parent, unsigned *utime, unsigne
pid_get_cpu_time(index, &utmp, &stmp);
*utime += utmp;
*stime += stmp;
int i;
for (i = index + 1; i < max_pids; i++) {
if (pids[i].parent == (pid_t)index)
@ -108,7 +108,7 @@ static char *print_top(unsigned index, unsigned parent, unsigned *utime, unsigne
ptrcmd = cmd + 9;
else
ptrcmd = cmd;
// user
char *user = get_user_name(pids[index].uid);
char *ptruser;
@ -116,7 +116,7 @@ static char *print_top(unsigned index, unsigned parent, unsigned *utime, unsigne
ptruser = user;
else
ptruser = "";
// memory
if (pgsz == 0)
pgsz = getpagesize();
@ -124,7 +124,7 @@ static char *print_top(unsigned index, unsigned parent, unsigned *utime, unsigne
snprintf(rss, 10, "%u", pgs_rss * pgsz / 1024);
char shared[10];
snprintf(shared, 10, "%u", pgs_shared * pgsz / 1024);
// uptime
unsigned long long uptime = pid_get_start_time(index);
if (clocktick == 0)
@ -140,7 +140,7 @@ static char *print_top(unsigned index, unsigned parent, unsigned *utime, unsigne
unsigned hour = uptime;
char uptime_str[50];
snprintf(uptime_str, 50, "%02u:%02u:%02u", hour, min, sec);
// cpu
itv *= clocktick;
float ud = (float) (*utime - pids[index].utime) / itv * 100;
@ -153,18 +153,18 @@ static char *print_top(unsigned index, unsigned parent, unsigned *utime, unsigne
// process count
char prcs_str[10];
snprintf(prcs_str, 10, "%d", *cnt);
if (asprintf(&rv, "%-5.5s %-9.9s %-8.8s %-8.8s %-5.5s %-4.4s %-9.9s %s",
pidstr, ptruser, rss, shared, cpu_str, prcs_str, uptime_str, ptrcmd) == -1)
errExit("asprintf");
if (cmd)
free(cmd);
if (user)
free(user);
}
return rv;
}
@ -174,7 +174,7 @@ typedef struct node_t {
char *line;
float cpu;
} Node;
static Node *head = NULL;
static void head_clear(void) {
@ -186,7 +186,7 @@ static void head_clear(void) {
free(ptr);
ptr = next;
}
head = NULL;
}
@ -198,14 +198,14 @@ static void head_add(float cpu, char *line) {
node->line = line;
node->cpu = cpu;
node->next = NULL;
// insert in first list position
if (head == NULL || head->cpu < cpu) {
node->next = head;
head = node;
return;
}
// insert in the right place
Node *ptr = head;
while (1) {
@ -215,14 +215,14 @@ static void head_add(float cpu, char *line) {
ptr->next = node;
return;
}
// current position
if (current->cpu < cpu) {
ptr->next = node;
node->next = current;
return;
}
ptr = current;
}
}
@ -233,10 +233,10 @@ void head_print(int col, int row) {
while (ptr) {
if (current >= row)
break;
if (strlen(ptr->line) > (size_t)col)
ptr->line[col] = '\0';
if (ptr->next == NULL || current == (row - 1)) {
printf("%s", ptr->line);
fflush(0);
@ -253,7 +253,7 @@ void top(void) {
while (1) {
// clear linked list
head_clear();
// set pid table
int i;
int itv = 1; // 1 second interval
@ -266,10 +266,10 @@ void top(void) {
if (pids[i].level == 1)
pid_store_cpu(i, 0, &utime, &stime);
}
// wait 1 second
firemon_sleep(itv);
// grab screen size
struct winsize sz;
int row = 24;
@ -288,7 +288,7 @@ void top(void) {
if (row > 0)
row--;
free(header);
// find system uptime
FILE *fp = fopen("/proc/uptime", "r");
if (fp) {
@ -315,4 +315,3 @@ void top(void) {
#endif
}
}

View file

@ -21,7 +21,7 @@
void tree(pid_t pid) {
pid_read(pid);
// print processes
int i;
for (i = 0; i < max_pids; i++) {
@ -30,4 +30,3 @@ void tree(pid_t pid) {
}
printf("\n");
}

View file

@ -21,17 +21,17 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
void x11(pid_t pid, int print_procs) {
pid_read(pid);
// print processes
int i;
for (i = 0; i < max_pids; i++) {
if (pids[i].level == 1) {
if (print_procs || pid == 0)
pid_print_list(i, arg_nowrap);
char *x11file;
// todo: use macro from src/firejail/firejail.h for /run/firejail/x11 directory
if (asprintf(&x11file, "/run/firejail/x11/%d", i) == -1)
@ -53,4 +53,3 @@ void x11(pid_t pid, int print_procs) {
}
printf("\n");
}

View file

@ -5,5 +5,3 @@ READ ME
* Add comma separated process names to ~/.loader.conf
* export LD_PRELOAD=<path>./loader.so (ideally to .bashrc)
* Run any application within shell

View file

@ -1,13 +1,13 @@
/*
* Copyright (C) 2017 Madura A. (madura.x86@gmail.com)
*
*
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
@ -35,7 +35,7 @@ void remove_trailing_spaces(char *str)
{
str++;
}
while (*str != '\0')
{
*str = '\0';
@ -70,7 +70,7 @@ void make_args()
{
if (cmdline[cI] == '\0')
{
args[argI]= argstart;
args[argI]= argstart;
argstart = &cmdline[cI+1];
argI++;
if (*argstart == '\0')
@ -89,11 +89,11 @@ void loader_main()
snprintf(confFile, 255, "%s/.loader.conf", getenv("HOME"));
struct stat confFileStat;
stat(confFile, &confFileStat);
int confFd = open(confFile, O_RDONLY);
if (confFd == -1)
{
close(confFd);
@ -111,7 +111,7 @@ void loader_main()
close(confFd);
return;
}
close(confFd);
size_t fI = 0;
int matchId = 0;
@ -123,17 +123,17 @@ void loader_main()
{
names[matchId] = &conf[fI+1];
conf[fI] = '\0';
matchId++;
}
}
remove_trailing_spaces(names[matchId-1]);
read_cmdline();
make_args();
#ifdef DEBUG
int xarg=0;
while (args[xarg] != NULL)
@ -144,18 +144,18 @@ void loader_main()
#endif
int x;
for (x = 0;x<matchId;x++)
{
DBG("%s\n",names[x]);
if (strstr(args[0], names[x]) != NULL)
{
DBG("highjack!\n");
free(conf);
execvp(loader, args );
}
}
}

View file

@ -3,5 +3,3 @@ all:
debug:
gcc -ggdb -shared -DDEBUG -fPIC loader.c -o loader.so

View file

@ -42,4 +42,3 @@ clean:; rm -f *.o fnet *.gcov *.gcda *.gcno
distclean: clean
rm -fr Makefile

View file

@ -48,12 +48,12 @@ void arp_scan(const char *dev, uint32_t ifip, uint32_t ifmask) {
// printf("Scanning interface %s (%d.%d.%d.%d/%d)\n",
// dev, PRINT_IP(ifip & ifmask), mask2bits(ifmask));
if (strlen(dev) > IFNAMSIZ) {
fprintf(stderr, "Error: invalid network device name %s\n", dev);
exit(1);
}
// find interface mac address
int sock;
if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) < 0)
@ -70,7 +70,7 @@ void arp_scan(const char *dev, uint32_t ifip, uint32_t ifmask) {
// open layer2 socket
if ((sock = socket(PF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) < 0)
errExit("socket");
// try all possible ip addresses in ascending order
uint32_t range = ~ifmask + 1; // the number of potential addresses
// this software is not supported for /31 networks
@ -90,7 +90,7 @@ void arp_scan(const char *dev, uint32_t ifip, uint32_t ifmask) {
struct timeval ts;
ts.tv_sec = 2; // 2 seconds receive timeout
ts.tv_usec = 0;
while (1) {
fd_set rfds;
FD_ZERO(&rfds);
@ -101,21 +101,21 @@ void arp_scan(const char *dev, uint32_t ifip, uint32_t ifmask) {
int maxfd = sock;
uint8_t frame[ETH_FRAME_LEN]; // includes eht header, vlan, and crc
memset(frame, 0, ETH_FRAME_LEN);
memset(frame, 0, ETH_FRAME_LEN);
int nready;
if (dest < last)
nready = select(maxfd + 1, &rfds, &wfds, (fd_set *) 0, NULL);
else
else
nready = select(maxfd + 1, &rfds, (fd_set *) 0, (fd_set *) 0, &ts);
if (nready < 0)
errExit("select");
if (nready == 0) { // timeout
break;
}
if (FD_ISSET(sock, &wfds) && dest < last) {
// configure layer2 socket address information
struct sockaddr_ll addr;
@ -125,7 +125,7 @@ void arp_scan(const char *dev, uint32_t ifip, uint32_t ifmask) {
addr.sll_family = AF_PACKET;
memcpy (addr.sll_addr, mac, 6);
addr.sll_halen = htons(6);
// build the arp packet header
ArpHdr hdr;
memset(&hdr, 0, sizeof(hdr));
@ -138,7 +138,7 @@ void arp_scan(const char *dev, uint32_t ifip, uint32_t ifmask) {
memcpy(hdr.sender_ip, (uint8_t *)&src, 4);
uint32_t dst = htonl(dest);
memcpy(hdr.target_ip, (uint8_t *)&dst, 4);
// build ethernet frame
uint8_t frame[ETH_FRAME_LEN]; // includes eht header, vlan, and crc
memset(frame, 0, sizeof(frame));
@ -147,16 +147,16 @@ void arp_scan(const char *dev, uint32_t ifip, uint32_t ifmask) {
frame[12] = ETH_P_ARP / 256;
frame[13] = ETH_P_ARP % 256;
memcpy (frame + 14, &hdr, sizeof(hdr));
// send packet
int len;
if ((len = sendto (sock, frame, 14 + sizeof(ArpHdr), 0, (struct sockaddr *) &addr, sizeof (addr))) <= 0)
errExit("send");
//printf("send %d bytes to %d.%d.%d.%d\n", len, PRINT_IP(dest));
//printf("send %d bytes to %d.%d.%d.%d\n", len, PRINT_IP(dest));
fflush(0);
dest++;
}
if (FD_ISSET(sock, &rfds)) {
// read the incoming packet
int len = recvfrom(sock, frame, ETH_FRAME_LEN, 0, NULL, NULL);
@ -185,24 +185,21 @@ void arp_scan(const char *dev, uint32_t ifip, uint32_t ifmask) {
continue;
memcpy(&ip, hdr.sender_ip, 4);
ip = ntohl(ip);
if (ip == last_ip) // filter duplicates
continue;
last_ip = ip;
// printing
if (header_printed == 0) {
printf(" Network scan:\n");
header_printed = 1;
}
printf(" %02x:%02x:%02x:%02x:%02x:%02x\t%d.%d.%d.%d\n",
PRINT_MAC(hdr.sender_mac), PRINT_IP(ip));
PRINT_MAC(hdr.sender_mac), PRINT_IP(ip));
}
}
}
close(sock);
}

View file

@ -40,7 +40,7 @@ static void check_if_name(const char *ifname) {
void net_bridge_add_interface(const char *bridge, const char *dev) {
check_if_name(bridge);
check_if_name(dev);
// somehow adding the interface to the bridge resets MTU on bridge device!!!
// workaround: restore MTU on the bridge device
// todo: put a real fix in
@ -82,7 +82,7 @@ void net_bridge_add_interface(const char *bridge, const char *dev) {
// bring interface up
void net_if_up(const char *ifname) {
check_if_name(ifname);
int sock = socket(AF_INET,SOCK_DGRAM,0);
if (sock < 0)
errExit("socket");
@ -139,8 +139,8 @@ int net_get_mtu(const char *ifname) {
if (ioctl(s, SIOCGIFMTU, (caddr_t)&ifr) == 0)
mtu = ifr.ifr_mtu;
close(s);
return mtu;
}
@ -197,7 +197,7 @@ void net_ifprint(int scan) {
sprintf(ipstr, "%d.%d.%d.%d", PRINT_IP(ip));
char maskstr[30];
sprintf(maskstr, "%d.%d.%d.%d", PRINT_IP(mask));
// mac address
unsigned char mac[6];
net_get_mac(ifa->ifa_name, mac);
@ -207,7 +207,7 @@ void net_ifprint(int scan) {
else
sprintf(macstr, "%02x:%02x:%02x:%02x:%02x:%02x", PRINT_MAC(mac));
// print
// print
printf("%-17.17s%-19.19s%-17.17s%-17.17s%-6.6s\n",
ifa->ifa_name, macstr, ipstr, maskstr, status);
@ -240,7 +240,7 @@ int net_get_mac(const char *ifname, unsigned char mac[6]) {
memset(&ifr, 0, sizeof(ifr));
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
if (ioctl(sock, SIOCGIFHWADDR, &ifr) == -1)
errExit("ioctl");
memcpy(mac, ifr.ifr_hwaddr.sa_data, 6);
@ -262,7 +262,7 @@ void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask, int mtu) {
ifr.ifr_addr.sa_family = AF_INET;
((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr = htonl(ip);
if (ioctl( sock, SIOCSIFADDR, &ifr ) < 0)
if (ioctl( sock, SIOCSIFADDR, &ifr ) < 0)
errExit("ioctl");
if (ip != 0) {
@ -270,7 +270,7 @@ void net_if_ip(const char *ifname, uint32_t ip, uint32_t mask, int mtu) {
if (ioctl( sock, SIOCSIFNETMASK, &ifr ) < 0)
errExit("ioctl");
}
// configure mtu
if (mtu > 0) {
ifr.ifr_mtu = mtu;
@ -295,7 +295,7 @@ int net_if_mac(const char *ifname, const unsigned char mac[6]) {
strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
memcpy(ifr.ifr_hwaddr.sa_data, mac, 6);
if (ioctl(sock, SIOCSIFHWADDR, &ifr) == -1)
errExit("ioctl");
close(sock);
@ -315,7 +315,7 @@ void net_if_ip6(const char *ifname, const char *addr6) {
fprintf(stderr, "Error fnet: invalid IPv6 address %s\n", addr6);
exit(1);
}
// extract prefix
unsigned long prefix;
char *ptr;
@ -367,6 +367,6 @@ void net_if_ip6(const char *ifname, const char *addr6) {
perror("ioctl SIOCSIFADDR");
exit(1);
}
close(sock);
}

View file

@ -41,7 +41,7 @@ int i;
for (i = 0; i < argc; i++)
printf("*%s* ", argv[i]);
printf("\n");
}
}
#endif
if (argc < 2) {
usage();
@ -51,7 +51,7 @@ printf("\n");
char *quiet = getenv("FIREJAIL_QUIET");
if (quiet && strcmp(quiet, "yes") == 0)
arg_quiet = 1;
if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") ==0) {
usage();
return 0;

View file

@ -1,16 +1,16 @@
/* code based on iproute2 ip/iplink.c, modified to be included in firejail project
*
* Original source code:
*
*
* Information:
* http://www.linuxfoundation.org/collaborate/workgroups/networking/iproute2
*
*
* Download:
* http://www.kernel.org/pub/linux/utils/net/iproute2/
*
*
* Repository:
* git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git
*
*
* License: GPL v2
*
* Original copyright header
@ -112,7 +112,7 @@ int net_create_veth(const char *dev, const char *nsdev, unsigned pid) {
exit(2);
rtnl_close(&rth);
return 0;
}
@ -134,13 +134,13 @@ int net_create_macvlan(const char *dev, const char *parent, unsigned pid) {
req.n.nlmsg_flags = NLM_F_REQUEST|NLM_F_CREATE|NLM_F_EXCL;
req.n.nlmsg_type = RTM_NEWLINK;
req.i.ifi_family = 0;
// find parent ifindex
int parent_ifindex = if_nametoindex(parent);
if (parent_ifindex <= 0) {
fprintf(stderr, "Error: cannot find network device %s\n", parent);
exit(1);
}
}
// add parent
addattr_l(&req.n, sizeof(req), IFLA_LINK, &parent_ifindex, 4);
@ -148,7 +148,7 @@ int net_create_macvlan(const char *dev, const char *parent, unsigned pid) {
// add new interface name
len = strlen(dev) + 1;
addattr_l(&req.n, sizeof(req), IFLA_IFNAME, dev, len);
// place the interface in child namespace
addattr_l (&req.n, sizeof(req), IFLA_NET_NS_PID, &pid, 4);
@ -176,7 +176,7 @@ int net_create_macvlan(const char *dev, const char *parent, unsigned pid) {
exit(2);
rtnl_close(&rth);
return 0;
}
@ -197,7 +197,7 @@ int net_move_interface(const char *dev, unsigned pid) {
req.n.nlmsg_flags = NLM_F_REQUEST;
req.n.nlmsg_type = RTM_NEWLINK;
req.i.ifi_family = 0;
// find ifindex
int ifindex = if_nametoindex(dev);
if (ifindex <= 0) {
@ -205,7 +205,7 @@ int net_move_interface(const char *dev, unsigned pid) {
exit(1);
}
req.i.ifi_index = ifindex;
// place the interface in child namespace
addattr_l (&req.n, sizeof(req), IFLA_NET_NS_PID, &pid, 4);
@ -214,7 +214,7 @@ int net_move_interface(const char *dev, unsigned pid) {
exit(2);
rtnl_close(&rth);
return 0;
}
@ -233,4 +233,4 @@ int main(int argc, char **argv) {
return 0;
}
*/
*/

View file

@ -42,4 +42,3 @@ clean:; rm -f *.o fseccomp *.gcov *.gcda *.gcno
distclean: clean
rm -fr Makefile

View file

@ -167,7 +167,7 @@ static ErrnoEntry errnolist[] = {
{"ENOTSUP", ENOTSUP},
#ifdef ENOATTR
{"ENOATTR", ENOATTR},
#endif
#endif
};
int errno_find_name(const char *name) {

View file

@ -46,7 +46,7 @@ int i;
for (i = 0; i < argc; i++)
printf("*%s* ", argv[i]);
printf("\n");
}
}
#endif
if (argc < 2) {
usage();
@ -56,7 +56,7 @@ printf("\n");
char *quiet = getenv("FIREJAIL_QUIET");
if (quiet && strcmp(quiet, "yes") == 0)
arg_quiet = 1;
if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") ==0) {
usage();
return 0;
@ -71,7 +71,7 @@ printf("\n");
protocol_build_filter(argv[3], argv[4]);
else if (argc == 4 && strcmp(argv[1], "secondary") == 0 && strcmp(argv[2], "64") == 0)
seccomp_secondary_64(argv[3]);
else if (argc == 4 && strcmp(argv[1], "secondary") == 0 && strcmp(argv[2], "32") == 0)
else if (argc == 4 && strcmp(argv[1], "secondary") == 0 && strcmp(argv[2], "32") == 0)
seccomp_secondary_32(argv[3]);
else if (argc == 3 && strcmp(argv[1], "default") == 0)
seccomp_default(argv[2], 0);
@ -95,4 +95,4 @@ printf("\n");
}
return 0;
}
}

View file

@ -87,7 +87,7 @@ static struct sock_filter *find_protocol_domain(const char *p) {
}
return NULL;
}
}
#endif
void protocol_print(void) {
@ -119,7 +119,7 @@ void protocol_build_filter(const char *prlist, const char *fname) {
struct sock_filter filter[32]; // big enough
memset(&filter[0], 0, sizeof(filter));
uint8_t *ptr = (uint8_t *) &filter[0];
// header
struct sock_filter filter_start[] = {
VALIDATE_ARCHITECTURE,
@ -153,7 +153,7 @@ printf("whitelist_len %u, struct sock_filter len %u\n", whitelist_len, (unsigned
char *token = strtok(tmplist, ",");
if (!token)
errExit("strtok");
while (token) {
struct sock_filter *domain = find_protocol_domain(token);
if (domain == NULL) {
@ -179,7 +179,7 @@ printf("entries %u\n", (unsigned) ((uint64_t) ptr - (uint64_t) (filter)) / (uns
#endif
}
}
free(tmplist);
// add end of filter
@ -201,14 +201,14 @@ printf("entries %u\n", (unsigned) ((uint64_t) ptr - (uint64_t) (filter)) / (uns
}
printf("\n");
}
#endif
#endif
// save filter to file
int dst = open(fname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
if (dst < 0) {
fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname);
exit(1);
}
int size = (int) ((uintptr_t) ptr - (uintptr_t) (filter));
int written = 0;
while (written < size) {
@ -220,5 +220,5 @@ printf("entries %u\n", (unsigned) ((uint64_t) ptr - (uint64_t) (filter)) / (uns
written += rv;
}
close(dst);
#endif // SYS_socket
#endif // SYS_socket
}

View file

@ -257,7 +257,7 @@ void seccomp_default(const char *fname, int allow_debuggers) {
filter_init(fd);
add_default_list(fd, allow_debuggers);
filter_end_blacklist(fd);
// close file
close(fd);
}
@ -281,7 +281,7 @@ void seccomp_drop(const char *fname, char *list, int allow_debuggers) {
exit(1);
}
filter_end_blacklist(fd);
// close file
close(fd);
}
@ -305,7 +305,7 @@ void seccomp_default_drop(const char *fname, char *list, int allow_debuggers) {
exit(1);
}
filter_end_blacklist(fd);
// close file
close(fd);
}
@ -326,15 +326,14 @@ void seccomp_keep(const char *fname, char *list) {
filter_add_whitelist(fd, SYS_setgroups, 0);
filter_add_whitelist(fd, SYS_dup, 0);
filter_add_whitelist(fd, SYS_prctl, 0);
if (syscall_check_list(list, filter_add_whitelist, fd, 0)) {
fprintf(stderr, "Error fseccomp: cannot build seccomp filter\n");
exit(1);
}
filter_end_whitelist(fd);
// close file
close(fd);
}

View file

@ -24,7 +24,7 @@
static void write_to_file(int fd, void *data, int size) {
assert(data);
assert(size);
int written = 0;
while (written < size) {
int rv = write(fd, (unsigned char *) data + written, size - written);
@ -69,7 +69,7 @@ void filter_init(int fd) {
void filter_add_whitelist(int fd, int syscall, int arg) {
(void) arg;
struct sock_filter filter[] = {
WHITELIST(syscall)
};
@ -78,7 +78,7 @@ void filter_add_whitelist(int fd, int syscall, int arg) {
void filter_add_blacklist(int fd, int syscall, int arg) {
(void) arg;
struct sock_filter filter[] = {
BLACKLIST(syscall)
};
@ -105,4 +105,3 @@ void filter_end_whitelist(int fd) {
};
write_to_file(fd, filter, sizeof(filter));
}

View file

@ -26,7 +26,7 @@ static int filter_cnt = 0;
static void load_seccomp(const char *fname) {
assert(fname);
// open filter file
int fd = open(fname, O_RDONLY);
if (fd == -1)
@ -40,7 +40,7 @@ static void load_seccomp(const char *fname) {
goto errexit;
unsigned short entries = (unsigned short) size / (unsigned short) sizeof(struct sock_filter);
filter_cnt = entries;
// read filter
filter = malloc(size);
if (filter == NULL)
@ -53,7 +53,7 @@ static void load_seccomp(const char *fname) {
goto errexit;
rd += rv;
}
// close file
close(fd);
return;
@ -67,7 +67,7 @@ errexit:
void filter_print(const char *fname) {
assert(fname);
load_seccomp(fname);
// start filter
struct sock_filter start[] = {
VALIDATE_ARCHITECTURE,
@ -86,7 +86,7 @@ void filter_print(const char *fname) {
printf("Invalid seccomp filter %s\n", fname);
return;
}
// loop trough blacklists
int i = 4;
while (i < filter_cnt) {

View file

@ -28,7 +28,7 @@ void seccomp_secondary_64(const char *fname) {
EXAMINE_SYSCALL,
BLACKLIST(165), // mount
BLACKLIST(166), // umount2
// todo: implement --allow-debuggers
// todo: implement --allow-debuggers
BLACKLIST(101), // ptrace
BLACKLIST(246), // kexec_load
BLACKLIST(304), // open_by_handle_at
@ -77,7 +77,7 @@ void seccomp_secondary_64(const char *fname) {
BLACKLIST(169), // reboot
BLACKLIST(180), // nfsservctl
BLACKLIST(177), // get_kernel_syms
RETURN_ALLOW
};
@ -87,7 +87,7 @@ void seccomp_secondary_64(const char *fname) {
fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname);
exit(1);
}
int size = (int) sizeof(filter);
int written = 0;
while (written < size) {
@ -109,7 +109,7 @@ void seccomp_secondary_32(const char *fname) {
EXAMINE_SYSCALL,
BLACKLIST(21), // mount
BLACKLIST(52), // umount2
// todo: implement --allow-debuggers
// todo: implement --allow-debuggers
BLACKLIST(26), // ptrace
BLACKLIST(283), // kexec_load
BLACKLIST(341), // name_to_handle_at
@ -157,7 +157,7 @@ void seccomp_secondary_32(const char *fname) {
BLACKLIST(88), // reboot
BLACKLIST(169), // nfsservctl
BLACKLIST(130), // get_kernel_syms
RETURN_ALLOW
};
@ -167,7 +167,7 @@ void seccomp_secondary_32(const char *fname) {
fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname);
exit(1);
}
int size = (int) sizeof(filter);
int written = 0;
while (written < size) {
@ -180,4 +180,3 @@ void seccomp_secondary_32(const char *fname) {
}
close(dst);
}

View file

@ -43,7 +43,7 @@ int syscall_find_name(const char *name) {
if (strcmp(name, syslist[i].name) == 0)
return syslist[i].nr;
}
return -1;
}
@ -54,7 +54,7 @@ char *syscall_find_nr(int nr) {
if (nr == syslist[i].nr)
return syslist[i].name;
}
return "unknown";
}
@ -75,7 +75,7 @@ static void syscall_process_name(const char *name, int *syscall_nr, int *error_n
if (strlen(name) == 0)
goto error;
*error_nr = -1;
// syntax check
char *str = strdup(name);
if (!str)
@ -101,7 +101,7 @@ static void syscall_process_name(const char *name, int *syscall_nr, int *error_n
free(str);
return;
error:
fprintf(stderr, "Error fseccomp: invalid syscall list entry %s\n", name);
exit(1);
@ -142,7 +142,7 @@ int syscall_check_list(const char *slist, void (*callback)(int fd, int syscall,
}
ptr = strtok(NULL, ",");
}
free(str);
return 0;
}

View file

@ -19,13 +19,13 @@ if [ "$1" = "--clear" ]; then
usage
exit
fi
DEV=$2
echo "Removing bandwith limits"
/sbin/tc qdisc del dev $DEV root 2> /dev/null > /dev/null
/sbin/tc qdisc del dev $DEV ingress 2> /dev/null > /dev/null
exit
fi
if [ "$1" = "--set" ]; then
@ -38,22 +38,22 @@ if [ "$1" = "--set" ]; then
usage
exit
fi
DEV=$2
echo "Configuring interface $DEV "
IN=$3
IN=$((${IN} * 8))
echo "Download speed ${IN}kbps"
OUT=$4
OUT=$((${OUT} * 8))
echo "Upload speed ${OUT}kbps"
echo "cleaning limits"
/sbin/tc qdisc del dev $DEV root 2> /dev/null > /dev/null
/sbin/tc qdisc del dev $DEV ingress 2> /dev/null > /dev/null
echo "configuring tc ingress"
/sbin/tc qdisc add dev $DEV handle ffff: ingress #2> /dev/null > /dev/null
/sbin/tc filter add dev $DEV parent ffff: protocol ip prio 50 u32 match ip src \
@ -63,7 +63,7 @@ if [ "$1" = "--set" ]; then
/sbin/tc qdisc add dev $DEV root tbf rate ${OUT}kbit latency 25ms burst 10k #2> /dev/null > /dev/null
exit
fi
echo "Error: missing parameters"
usage
exit 1

View file

@ -24,4 +24,3 @@ clean:; rm -f *.o ftee *.gcov *.gcda *.gcno
distclean: clean
rm -fr Makefile

View file

@ -21,4 +21,4 @@
#define FTEE_H
#include "../include/common.h"
#endif
#endif

View file

@ -47,7 +47,7 @@ static void log_rotate(const char *fname) {
strcpy(name1, fname);
strcpy(name2, fname);
fflush(0);
// delete filename.5
sprintf(name1 + index, ".5");
if (stat(name1, &s) == 0) {
@ -55,7 +55,7 @@ static void log_rotate(const char *fname) {
if (rv == -1)
perror("unlink");
}
// move files 1 to 4 down one position
sprintf(name2 + index, ".4");
if (stat(name2, &s) == 0) {
@ -96,14 +96,14 @@ static void log_rotate(const char *fname) {
if (rv == -1)
perror("rename");
}
free(name1);
free(name2);
}
static void log_write(const unsigned char *str, int len, const char *fname) {
assert(fname);
if (out_fp == NULL) {
out_fp = fopen(fname, "w");
if (!out_fp) {
@ -112,7 +112,7 @@ static void log_write(const unsigned char *str, int len, const char *fname) {
}
out_cnt = 0;
}
// rotate files
out_cnt += len;
if (out_cnt >= out_max) {
@ -127,9 +127,9 @@ static void log_write(const unsigned char *str, int len, const char *fname) {
exit(1);
}
out_cnt = len;
}
fwrite(str, len, 1, out_fp);
}
fwrite(str, len, 1, out_fp);
fflush(0);
}
@ -139,7 +139,7 @@ static int is_dir(const char *fname) {
assert(fname);
if (*fname == '\0')
return 0;
// if fname doesn't end in '/', add one
int rv;
struct stat s;
@ -150,14 +150,14 @@ static int is_dir(const char *fname) {
if (asprintf(&tmp, "%s/", fname) == -1) {
fprintf(stderr, "Error: cannot allocate memory, %s:%d\n", __FILE__, __LINE__);
exit(1);
}
}
rv = stat(tmp, &s);
free(tmp);
}
if (rv == -1)
return 0;
if (S_ISDIR(s.st_mode))
return 1;
@ -199,13 +199,13 @@ int main(int argc, char **argv) {
// do not accept directories, links, and files with ".."
if (strstr(fname, "..") || is_link(fname) || is_dir(fname))
goto errexit;
struct stat s;
if (stat(fname, &s) == 0) {
// check permissions
if (s.st_uid != getuid() || s.st_gid != getgid())
goto errexit;
// check hard links
if (s.st_nlink != 1)
goto errexit;
@ -229,11 +229,11 @@ int main(int argc, char **argv) {
continue;
if (n <= 0)
break;
fwrite(buf, n, 1, stdout);
log_write(buf, n, fname);
}
log_close();
return 0;

View file

@ -64,7 +64,7 @@ static inline int atoip(const char *str, uint32_t *ip) {
if (sscanf(str, "%u.%u.%u.%u", &a, &b, &c, &d) != 4 || a > 255 || b > 255 || c > 255 || d > 255)
return 1;
*ip = a * 0x1000000 + b * 0x10000 + c * 0x100 + d;
return 0;
}
@ -91,7 +91,7 @@ static inline int atomac(char *str, unsigned char macAddr[6]) {
for (i = 0; i < 6; i++) {
if (mac[i] > 0xff)
return 1;
macAddr[i] = (unsigned char) mac[i];
}
@ -105,16 +105,16 @@ static inline int mac_not_zero(const unsigned char mac[6]) {
if (mac[i] != 0)
return 1;
}
return 0;
}
// rtdsc timestamp on x86-64/amd64 processors
static inline unsigned long long getticks(void) {
#if defined(__x86_64__)
unsigned a, d;
asm volatile("rdtsc" : "=a" (a), "=d" (d));
return ((unsigned long long)a) | (((unsigned long long)d) << 32);
unsigned a, d;
asm volatile("rdtsc" : "=a" (a), "=d" (d));
return ((unsigned long long)a) | (((unsigned long long)d) << 32);
#elif defined(__i386__)
unsigned long long ret;
__asm__ __volatile__("rdtsc" : "=A" (ret));

View file

@ -1,16 +1,16 @@
/* file extracted from iproute2 software package
*
* Original source code:
*
*
* Information:
* http://www.linuxfoundation.org/collaborate/workgroups/networking/iproute2
*
*
* Download:
* http://www.kernel.org/pub/linux/utils/net/iproute2/
*
*
* Repository:
* git://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git
*
*
* License: GPL v2
*/
@ -161,4 +161,3 @@ extern int rtnl_from_file(FILE *, rtnl_filter_t handler,
#endif
#endif /* __LIBNETLINK_H__ */

View file

@ -5144,4 +5144,3 @@
#endif
#endif
//#endif

View file

@ -10,7 +10,7 @@ C_FILE_LIST = $(sort $(wildcard *.c))
OBJS = $(C_FILE_LIST:.c=.o)
BINOBJS = $(foreach file, $(OBJS), $file)
CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' $(HAVE_GCOV) -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIC -Wformat -Wformat-security
LDFLAGS:=-pic -Wl,-z,relro -Wl,-z,now
LDFLAGS:=-pic -Wl,-z,relro -Wl,-z,now
all: $(OBJS)

Some files were not shown because too many files have changed in this diff Show more