mirror of
https://github.com/netblue30/firejail.git
synced 2026-05-15 14:16:14 -06:00
Remove trailing whitespace from src/
This commit is contained in:
parent
6db7fe46fb
commit
96c920e166
115 changed files with 1061 additions and 1134 deletions
|
|
@ -34,6 +34,3 @@ _firecfg()
|
|||
fi
|
||||
} &&
|
||||
complete -F _firecfg firecfg
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -109,6 +109,3 @@ _firejail()
|
|||
|
||||
} &&
|
||||
complete -F _firejail firejail
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,3 @@ _firemon()
|
|||
fi
|
||||
} &&
|
||||
complete -F _firemon firemon
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -22,4 +22,3 @@ clean:; rm -f *.o faudit
|
|||
|
||||
distclean: clean
|
||||
rm -fr Makefile
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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.");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -42,4 +42,3 @@ clean:; rm -f *.o fcopy *.gcov *.gcda *.gcno
|
|||
|
||||
distclean: clean
|
||||
rm -fr Makefile
|
||||
|
||||
|
|
|
|||
|
|
@ -37,4 +37,3 @@ clean:; rm -f *.o firecfg firecfg.1 firecfg.1.gz *.gcov *.gcda *.gcno
|
|||
|
||||
distclean: clean
|
||||
rm -fr Makefile
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -42,4 +42,3 @@ clean:; rm -f *.o firejail firejail.1 firejail.1.gz *.gcov *.gcda *.gcno
|
|||
|
||||
distclean: clean
|
||||
rm -fr Makefile
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -156,5 +156,3 @@ getout:
|
|||
close(fd);
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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++;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,5 +3,3 @@ all:
|
|||
|
||||
debug:
|
||||
gcc -ggdb -shared -DDEBUG -fPIC loader.c -o loader.so
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -42,4 +42,3 @@ clean:; rm -f *.o fnet *.gcov *.gcda *.gcno
|
|||
|
||||
distclean: clean
|
||||
rm -fr Makefile
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
*/
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -42,4 +42,3 @@ clean:; rm -f *.o fseccomp *.gcov *.gcda *.gcno
|
|||
|
||||
distclean: clean
|
||||
rm -fr Makefile
|
||||
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ static ErrnoEntry errnolist[] = {
|
|||
{"ENOTSUP", ENOTSUP},
|
||||
#ifdef ENOATTR
|
||||
{"ENOATTR", ENOATTR},
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
int errno_find_name(const char *name) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -24,4 +24,3 @@ clean:; rm -f *.o ftee *.gcov *.gcda *.gcno
|
|||
|
||||
distclean: clean
|
||||
rm -fr Makefile
|
||||
|
||||
|
|
|
|||
|
|
@ -21,4 +21,4 @@
|
|||
#define FTEE_H
|
||||
#include "../include/common.h"
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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__ */
|
||||
|
||||
|
|
|
|||
|
|
@ -5144,4 +5144,3 @@
|
|||
#endif
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -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
Loading…
Add table
Add a link
Reference in a new issue