aboutsummaryrefslogtreecommitdiffstats
path: root/src/faudit
diff options
context:
space:
mode:
Diffstat (limited to 'src/faudit')
-rw-r--r--src/faudit/Makefile.in25
-rw-r--r--src/faudit/caps.c78
-rw-r--r--src/faudit/faudit.h51
-rw-r--r--src/faudit/files.c73
-rw-r--r--src/faudit/main.c62
-rw-r--r--src/faudit/pid.c89
-rw-r--r--src/faudit/seccomp.c102
-rw-r--r--src/faudit/syscall.c91
8 files changed, 571 insertions, 0 deletions
diff --git a/src/faudit/Makefile.in b/src/faudit/Makefile.in
new file mode 100644
index 000000000..995a0bf49
--- /dev/null
+++ b/src/faudit/Makefile.in
@@ -0,0 +1,25 @@
1all: faudit
2
3PREFIX=@prefix@
4VERSION=@PACKAGE_VERSION@
5NAME=@PACKAGE_NAME@
6HAVE_FATAL_WARNINGS=@HAVE_FATAL_WARNINGS@
7
8H_FILE_LIST = $(sort $(wildcard *.[h]))
9C_FILE_LIST = $(sort $(wildcard *.c))
10OBJS = $(C_FILE_LIST:.c=.o)
11BINOBJS = $(foreach file, $(OBJS), $file)
12CFLAGS += -ggdb $(HAVE_FATAL_WARNINGS) -O2 -DVERSION='"$(VERSION)"' -DPREFIX='"$(PREFIX)"' -fstack-protector-all -D_FORTIFY_SOURCE=2 -fPIE -pie -Wformat -Wformat-security
13LDFLAGS += -pie -Wl,-z,relro -Wl,-z,now -lpthread
14
15%.o : %.c $(H_FILE_LIST)
16 $(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
17
18faudit: $(OBJS)
19 $(CC) $(LDFLAGS) -o $@ $(OBJS)
20
21clean:; rm -f *.o faudit
22
23distclean: clean
24 rm -fr Makefile
25
diff --git a/src/faudit/caps.c b/src/faudit/caps.c
new file mode 100644
index 000000000..f98d45ec8
--- /dev/null
+++ b/src/faudit/caps.c
@@ -0,0 +1,78 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20
21#include "faudit.h"
22#include <linux/capability.h>
23
24#define MAXBUF 4098
25static int extract_caps(uint64_t *val) {
26 FILE *fp = fopen("/proc/self/status", "r");
27 if (!fp)
28 return 1;
29
30 char buf[MAXBUF];
31 while (fgets(buf, MAXBUF, fp)) {
32 if (strncmp(buf, "CapBnd:\t", 8) == 0) {
33 char *ptr = buf + 8;
34 unsigned long long tmp;
35 sscanf(ptr, "%llx", &tmp);
36 *val = tmp;
37 fclose(fp);
38 return 0;
39 }
40 }
41
42 fclose(fp);
43 return 1;
44}
45
46// return 1 if the capability is in tbe map
47static int check_capability(uint64_t map, int cap) {
48 int i;
49 uint64_t mask = 1ULL;
50
51 for (i = 0; i < 64; i++, mask <<= 1) {
52 if ((i == cap) && (mask & map))
53 return 1;
54 }
55
56 return 0;
57}
58
59void caps_test(void) {
60 uint64_t caps_val;
61
62 if (extract_caps(&caps_val)) {
63 printf("SKIP: cannot extract capabilities on this platform\n");
64 return;
65 }
66
67 if (caps_val) {
68 printf("BAD: the capability map is %llx, it should be all zero\n", (unsigned long long) caps_val);
69
70 if (check_capability(caps_val, CAP_SYS_ADMIN))
71 printf("UGLY: CAP_SYS_ADMIN is enabled\n");
72 if (check_capability(caps_val, CAP_SYS_BOOT))
73 printf("UGLY: CAP_SYS_BOOT is enabled\n");
74 }
75 else
76 printf("GOOD: all capabilities are disabled\n");
77}
78
diff --git a/src/faudit/faudit.h b/src/faudit/faudit.h
new file mode 100644
index 000000000..fdb4556c3
--- /dev/null
+++ b/src/faudit/faudit.h
@@ -0,0 +1,51 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20
21#ifndef FAUDIT_H
22#define FAUDIT_H
23#include <stdio.h>
24#include <stdlib.h>
25#include <stdint.h>
26#include <string.h>
27#include <unistd.h>
28#include <sys/types.h>
29#include <sys/stat.h>
30#include <sys/mount.h>
31#include <assert.h>
32
33#define errExit(msg) do { char msgout[500]; sprintf(msgout, "Error %s:%s(%d)", msg, __FUNCTION__, __LINE__); perror(msgout); exit(1);} while (0)
34
35// main.c
36extern char *prog;
37
38// pid.c
39void pid_test(void);
40
41// caps.c
42void caps_test(void);
43
44// seccomp.c
45void seccomp_test(void);
46
47// syscall.c
48void syscall_helper(int argc, char **argv);
49void syscall_run(const char *name);
50
51#endif \ No newline at end of file
diff --git a/src/faudit/files.c b/src/faudit/files.c
new file mode 100644
index 000000000..0463af66d
--- /dev/null
+++ b/src/faudit/files.c
@@ -0,0 +1,73 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "faudit.h"
21#include <fcntl.h>
22#include <pwd.h>
23
24static char *username = NULL;
25static char *homedir = NULL;
26
27static void check_home_file(const char *name) {
28 assert(homedir);
29
30 char *fname;
31 if (asprintf(&fname, "%s/%s", homedir, name) == -1)
32 errExit("asprintf");
33
34 if (access(fname, R_OK) == 0)
35 printf("UGLY: I can access files in %s directory\n", fname);
36 else
37 printf("GOOD: I cannot access files in %s directory\n", fname);
38
39 free(fname);
40}
41
42void files_test(void) {
43 struct passwd *pw = getpwuid(getuid());
44 if (!pw) {
45 fprintf(stderr, "Error: cannot retrive user account information\n");
46 return;
47 }
48
49 username = strdup(pw->pw_name);
50 if (!username)
51 errExit("strdup");
52 homedir = strdup(pw->pw_dir);
53 if (!homedir)
54 errExit("strdup");
55
56 // check access to .ssh directory
57 check_home_file(".ssh");
58
59 // check access to .gnupg directory
60 check_home_file(".gnupg");
61
62 // check access to Firefox browser directory
63 check_home_file(".mozilla");
64
65 // check access to Chromium browser directory
66 check_home_file(".config/chromium");
67
68 // check access to Debian Icedove directory
69 check_home_file(".icedove");
70
71 // check access to Thunderbird directory
72 check_home_file(".thunderbird");
73}
diff --git a/src/faudit/main.c b/src/faudit/main.c
new file mode 100644
index 000000000..2ed3aa2e1
--- /dev/null
+++ b/src/faudit/main.c
@@ -0,0 +1,62 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "faudit.h"
21char *prog;
22
23int main(int argc, char **argv) {
24 if (argc != 1) {
25 int i;
26
27 for (i = 1; i < argc; i++) {
28 if (strcmp(argv[i], "syscall")) {
29 syscall_helper(argc, argv);
30 return 0;
31 }
32 }
33 return 1;
34 }
35
36 printf("\n---------------- Firejail Audit: the Good, the Bad and the Ugly ----------------\n");
37
38 // extract program name
39 prog = realpath(argv[0], NULL);
40 if (prog == NULL) {
41 fprintf(stderr, "Error: cannot extract the path of the audit program\n");
42 return 1;
43 }
44 printf("INFO: starting %s\n", prog);
45
46
47 // check pid namespace
48 pid_test();
49
50 // check capabilities
51 caps_test();
52
53 // check seccomp
54 seccomp_test();
55
56 // check some well-known problematic files
57 files_test();
58
59 free(prog);
60 printf("--------------------------------------------------------------------------------\n");
61 return 0;
62}
diff --git a/src/faudit/pid.c b/src/faudit/pid.c
new file mode 100644
index 000000000..53b59a838
--- /dev/null
+++ b/src/faudit/pid.c
@@ -0,0 +1,89 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "faudit.h"
21
22void pid_test(void) {
23 char *kern_proc[] = {
24 "kthreadd",
25 "ksoftirqd",
26 "kworker",
27 "rcu_sched",
28 "rcu_bh",
29 NULL // NULL terminated list
30 };
31 int i;
32
33 // look at the first 10 processes
34 for (i = 1; i <= 10; i++) {
35 struct stat s;
36 char *fname;
37 if (asprintf(&fname, "/proc/%d/comm", i) == -1)
38 errExit("asprintf");
39 if (stat(fname, &s) == -1) {
40 free(fname);
41 continue;
42 }
43
44 // open file
45 /* coverity[toctou] */
46 FILE *fp = fopen(fname, "r");
47 if (!fp) {
48 fprintf(stderr, "Warning: cannot open %s\n", fname);
49 free(fname);
50 continue;
51 }
52
53 // read file
54 char buf[100];
55 if (fgets(buf, 10, fp) == NULL) {
56 fprintf(stderr, "Warning: cannot read %s\n", fname);
57 fclose(fp);
58 free(fname);
59 continue;
60 }
61 // clean /n
62 char *ptr;
63 if ((ptr = strchr(buf, '\n')) != NULL)
64 *ptr = '\0';
65
66 // check process name against the kernel list
67 int j = 0;
68 while (kern_proc[j] != NULL) {
69 if (strncmp(buf, kern_proc[j], strlen(kern_proc[j])) == 0) {
70 fclose(fp);
71 free(fname);
72 printf("BAD: Process PID %d, not running in a PID namespace\n", getpid());
73 return;
74 }
75 j++;
76 }
77
78 fclose(fp);
79 free(fname);
80 }
81
82
83 printf("GOOD: process PID %d, running in a PID namespace\n", getpid());
84
85 // try to guess the type of container/sandbox
86 char *str = getenv("container");
87 if (str)
88 printf("INFO: container/sandbox %s\n", str);
89}
diff --git a/src/faudit/seccomp.c b/src/faudit/seccomp.c
new file mode 100644
index 000000000..d88d6a958
--- /dev/null
+++ b/src/faudit/seccomp.c
@@ -0,0 +1,102 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "faudit.h"
21
22#define MAXBUF 4098
23static int extract_seccomp(int *val) {
24 FILE *fp = fopen("/proc/self/status", "r");
25 if (!fp)
26 return 1;
27
28 char buf[MAXBUF];
29 while (fgets(buf, MAXBUF, fp)) {
30 if (strncmp(buf, "Seccomp:\t", 8) == 0) {
31 char *ptr = buf + 8;
32 int tmp;
33 sscanf(ptr, "%d", &tmp);
34 *val = tmp;
35 fclose(fp);
36 return 0;
37 }
38 }
39
40 fclose(fp);
41 return 1;
42}
43
44void seccomp_test(void) {
45 int seccomp_status;
46 int rv = extract_seccomp(&seccomp_status);
47
48 if (rv) {
49 printf("SKIP: cannot extract seccomp configuration on this platform\n");
50 return;
51 }
52
53 if (seccomp_status == 0)
54 printf("BAD: seccomp disabled\n");
55 else if (seccomp_status == 1)
56 printf("GOOD: seccomp strict mode - only read, write, _exit, and sigreturn are allowd\n");
57 else if (seccomp_status == 2) {
58 printf("GOOD: seccomp BPF enababled\n");
59
60 printf("checking syscalls: "); fflush(0);
61 printf("mount... "); fflush(0);
62 syscall_run("mount");
63
64 printf("umount2... "); fflush(0);
65 syscall_run("umount2");
66
67 printf("ptrace... "); fflush(0);
68 syscall_run("ptrace");
69
70 printf("swapon... "); fflush(0);
71 syscall_run("swapon");
72
73 printf("swapoff... "); fflush(0);
74 syscall_run("swapoff");
75
76 printf("init_module... "); fflush(0);
77 syscall_run("init_module");
78
79 printf("finit_module... "); fflush(0);
80 syscall_run("finit_module");
81
82 printf("delete_module... "); fflush(0);
83 syscall_run("delete_module");
84
85 printf("chroot... "); fflush(0);
86 syscall_run("chroot");
87
88 printf("pivot_root... "); fflush(0);
89 syscall_run("pivot_root");
90
91 printf("iopl... "); fflush(0);
92 syscall_run("iopl");
93
94 printf("ioperm... "); fflush(0);
95 syscall_run("ioperm");
96
97 printf("\n");
98 }
99 else
100 fprintf(stderr, "Error: unrecognized seccomp mode\n");
101
102} \ No newline at end of file
diff --git a/src/faudit/syscall.c b/src/faudit/syscall.c
new file mode 100644
index 000000000..11fb3730b
--- /dev/null
+++ b/src/faudit/syscall.c
@@ -0,0 +1,91 @@
1/*
2 * Copyright (C) 2014-2016 Firejail Authors
3 *
4 * This file is part of firejail project
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19*/
20#include "faudit.h"
21
22void syscall_helper(int argc, char **argv) {
23 if (strcmp(argv[2], "mount") == 0) {
24 mount(NULL, NULL, NULL, 0, NULL);
25 printf("\nUGLY: mount syscall permitted\n");
26 }
27 else if (strcmp(argv[2], "umount2") == 0) {
28 umount2(NULL, 0);
29 printf("\nUGLY: umount2 syscall permitted\n");
30 }
31 else if (strcmp(argv[2], "ptrace") == 0) {
32 ptrace(0, 0, NULL, NULL);
33 printf("\nUGLY: ptrace syscall permitted\n");
34 }
35 else if (strcmp(argv[2], "swapon") == 0) {
36 swapon(NULL, 0);
37 printf("\nUGLY: swapon syscall permitted\n");
38 }
39 else if (strcmp(argv[2], "swapoff") == 0) {
40 swapoff(NULL);
41 printf("\nUGLY: swapoff syscall permitted\n");
42 }
43 else if (strcmp(argv[2], "init_module") == 0) {
44 init_module(NULL, 0, NULL);
45 printf("\nUGLY: init_moule syscall permitted\n");
46 }
47 else if (strcmp(argv[2], "finit_module") == 0) {
48 swapoff(0, NULL, 0);
49 printf("\nUGLY: finit_moule syscall permitted\n");
50 }
51 else if (strcmp(argv[2], "delete_module") == 0) {
52 delete_module(NULL, 0);
53 printf("\nUGLY: delete_moule syscall permitted\n");
54 }
55 else if (strcmp(argv[2], "chroot") == 0) {
56 int rv = chroot(NULL);
57 (void) rv;
58 printf("\nUGLY: chroot syscall permitted\n");
59 }
60 else if (strcmp(argv[2], "pivot_root") == 0) {
61 pivot_root(NULL, NULL);
62 printf("\nUGLY: pivot_root syscall permitted\n");
63 }
64 else if (strcmp(argv[2], "iopl") == 0) {
65 iopl(0L);
66 printf("\nUGLY: iopl syscall permitted\n");
67 }
68 else if (strcmp(argv[2], "ioperm") == 0) {
69 ioperm(0, 0, 0);
70 printf("\nUGLY: ioperm syscall permitted\n");
71 }
72 exit(0);
73}
74
75void syscall_run(const char *name) {
76 assert(prog);
77
78 pid_t child = fork();
79 if (child < 0)
80 errExit("fork");
81 if (child == 0) {
82 char *cmd;
83 if (asprintf(&cmd, "%s syscall %s", prog, name) == -1)
84 errExit("asprintf");
85 execl(prog, prog, "syscall", name, NULL);
86 exit(0);
87 }
88
89 // wait for the child to finish
90 waitpid(child, NULL, 0);
91} \ No newline at end of file