aboutsummaryrefslogtreecommitdiffstats
path: root/src/fbuilder/build_profile.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/fbuilder/build_profile.c')
-rw-r--r--src/fbuilder/build_profile.c182
1 files changed, 67 insertions, 115 deletions
diff --git a/src/fbuilder/build_profile.c b/src/fbuilder/build_profile.c
index fb53f70a6..941f43562 100644
--- a/src/fbuilder/build_profile.c
+++ b/src/fbuilder/build_profile.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2014-2021 Firejail Authors 2 * Copyright (C) 2014-2022 Firejail Authors
3 * 3 *
4 * This file is part of firejail project 4 * This file is part of firejail project
5 * 5 *
@@ -22,22 +22,6 @@
22#include <sys/wait.h> 22#include <sys/wait.h>
23 23
24#define TRACE_OUTPUT "/tmp/firejail-trace.XXXXXX" 24#define TRACE_OUTPUT "/tmp/firejail-trace.XXXXXX"
25#define STRACE_OUTPUT "/tmp/firejail-strace.XXXXXX"
26
27/* static char *cmdlist[] = { */
28/* "/usr/bin/firejail", */
29/* "--quiet", */
30/* "--output=" TRACE_OUTPUT, */
31/* "--noprofile", */
32/* "--caps.drop=all", */
33/* "--nonewprivs", */
34/* "--trace", */
35/* "--shell=none", */
36/* "/usr/bin/strace", // also used as a marker in build_profile() */
37/* "-c", */
38/* "-f", */
39/* "-o" STRACE_OUTPUT, */
40/* }; */
41 25
42void build_profile(int argc, char **argv, int index, FILE *fp) { 26void build_profile(int argc, char **argv, int index, FILE *fp) {
43 // next index is the application name 27 // next index is the application name
@@ -47,78 +31,42 @@ void build_profile(int argc, char **argv, int index, FILE *fp) {
47 } 31 }
48 32
49 char trace_output[] = "/tmp/firejail-trace.XXXXXX"; 33 char trace_output[] = "/tmp/firejail-trace.XXXXXX";
50 char strace_output[] = "/tmp/firejail-strace.XXXXXX";
51
52 int tfile = mkstemp(trace_output); 34 int tfile = mkstemp(trace_output);
53 int stfile = mkstemp(strace_output); 35 if(tfile == -1)
54 if(tfile == -1 || stfile == -1)
55 errExit("mkstemp"); 36 errExit("mkstemp");
56
57 // close the files, firejail/strace will overwrite them!
58 close(tfile); 37 close(tfile);
59 close(stfile);
60
61 38
62 char *output; 39 char *output;
63 char *stroutput;
64 if(asprintf(&output,"--trace=%s",trace_output) == -1) 40 if(asprintf(&output,"--trace=%s",trace_output) == -1)
65 errExit("asprintf"); 41 errExit("asprintf");
66 if(asprintf(&stroutput,"-o%s",strace_output) == -1)
67 errExit("asprintf");
68
69 char *cmdlist[] = {
70 BINDIR "/firejail",
71 "--quiet",
72 "--noprofile",
73 "--caps.drop=all",
74 "--nonewprivs",
75 output,
76 "--shell=none",
77 "/usr/bin/strace", // also used as a marker in build_profile()
78 "-c",
79 "-f",
80 stroutput,
81 };
82
83 // detect strace and check if Yama LSM allows us to use it
84 int have_strace = 0;
85 int have_yama_permission = 1;
86 if (access("/usr/bin/strace", X_OK) == 0) {
87 have_strace = 1;
88 FILE *ps = fopen("/proc/sys/kernel/yama/ptrace_scope", "r");
89 if (ps) {
90 unsigned val;
91 if (fscanf(ps, "%u", &val) == 1)
92 have_yama_permission = (val < 2);
93 fclose(ps);
94 }
95 }
96 42
97 // calculate command length 43 // calculate command length
98 unsigned len = (int) sizeof(cmdlist) / sizeof(char*) + argc - index + 1; 44 unsigned len = 64; // plenty of space for firejail command line
99 if (arg_debug) 45 len += argc - index; // program command line
100 printf("command len %d + %d + 1\n", (int) (sizeof(cmdlist) / sizeof(char*)), argc - index); 46 len += 1; // NULL
101 char *cmd[len];
102 cmd[0] = cmdlist[0]; // explicit assignment to clean scan-build error
103 47
104 // build command 48 // build command
105 // skip strace if not installed, or no permission to use it 49 char *cmd[len];
106 int skip_strace = !(have_strace && have_yama_permission); 50 unsigned curr_len = 0;
107 unsigned i = 0; 51 cmd[curr_len++] = BINDIR "/firejail";
108 for (i = 0; i < (int) sizeof(cmdlist) / sizeof(char*); i++) { 52 cmd[curr_len++] = "--quiet";
109 if (skip_strace && strcmp(cmdlist[i], "/usr/bin/strace") == 0) 53 cmd[curr_len++] = "--noprofile";
110 break; 54 cmd[curr_len++] = "--caps.drop=all";
111 cmd[i] = cmdlist[i]; 55 cmd[curr_len++] = "--seccomp=!chroot";
112 } 56 cmd[curr_len++] = "--shell=none";
113 57 cmd[curr_len++] = output;
114 int i2 = index; 58 if (arg_appimage)
115 for (; i < (len - 1); i++, i2++) 59 cmd[curr_len++] = "--appimage";
116 cmd[i] = argv[i2]; 60
117 assert(i < len); 61 int i;
118 cmd[i] = NULL; 62 for (i = index; i < argc; i++)
63 cmd[curr_len++] = argv[i];
64
65 assert(curr_len < len);
66 cmd[curr_len] = NULL;
119 67
120 if (arg_debug) { 68 if (arg_debug) {
121 for (i = 0; i < len; i++) 69 for (i = 0; cmd[i]; i++)
122 printf("%s%s\n", (i)?"\t":"", cmd[i]); 70 printf("%s%s\n", (i)?"\t":"", cmd[i]);
123 } 71 }
124 72
@@ -140,14 +88,14 @@ void build_profile(int argc, char **argv, int index, FILE *fp) {
140 88
141 if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { 89 if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
142 if (fp == stdout) 90 if (fp == stdout)
143 printf("--- Built profile beings after this line ---\n"); 91 printf("--- Built profile begins after this line ---\n");
144 fprintf(fp, "# Save this file as \"application.profile\" (change \"application\" with the\n"); 92 fprintf(fp, "# Save this file as \"application.profile\" (change \"application\" with the\n");
145 fprintf(fp, "# program name) in ~/.config/firejail directory. Firejail will find it\n"); 93 fprintf(fp, "# program name) in ~/.config/firejail directory. Firejail will find it\n");
146 fprintf(fp, "# automatically every time you sandbox your application.\n#\n"); 94 fprintf(fp, "# automatically every time you sandbox your application.\n#\n");
147 fprintf(fp, "# Run \"firejail application\" to test it. In the file there are\n"); 95 fprintf(fp, "# Run \"firejail application\" to test it. In the file there are\n");
148 fprintf(fp, "# some other commands you can try. Enable them by removing the \"#\".\n"); 96 fprintf(fp, "# some other commands you can try. Enable them by removing the \"#\".\n\n");
149 97
150 fprintf(fp, "\n# Firejail profile for %s\n", argv[index]); 98 fprintf(fp, "# Firejail profile for %s\n", argv[index]);
151 fprintf(fp, "# Persistent local customizations\n"); 99 fprintf(fp, "# Persistent local customizations\n");
152 fprintf(fp, "#include %s.local\n", argv[index]); 100 fprintf(fp, "#include %s.local\n", argv[index]);
153 fprintf(fp, "# Persistent global definitions\n"); 101 fprintf(fp, "# Persistent global definitions\n");
@@ -158,58 +106,62 @@ void build_profile(int argc, char **argv, int index, FILE *fp) {
158 fprintf(fp, "### Enable as many of them as you can! A very important one is\n"); 106 fprintf(fp, "### Enable as many of them as you can! A very important one is\n");
159 fprintf(fp, "### \"disable-exec.inc\". This will make among other things your home\n"); 107 fprintf(fp, "### \"disable-exec.inc\". This will make among other things your home\n");
160 fprintf(fp, "### and /tmp directories non-executable.\n"); 108 fprintf(fp, "### and /tmp directories non-executable.\n");
161 fprintf(fp, "include disable-common.inc\n"); 109 fprintf(fp, "include disable-common.inc\t# dangerous directories like ~/.ssh and ~/.gnupg\n");
162 fprintf(fp, "#include disable-devel.inc\n"); 110 fprintf(fp, "#include disable-devel.inc\t# development tools such as gcc and gdb\n");
163 fprintf(fp, "#include disable-exec.inc\n"); 111 fprintf(fp, "#include disable-exec.inc\t# non-executable directories such as /var, /tmp, and /home\n");
164 fprintf(fp, "#include disable-interpreters.inc\n"); 112 fprintf(fp, "#include disable-interpreters.inc\t# perl, python, lua etc.\n");
165 fprintf(fp, "include disable-passwdmgr.inc\n"); 113 fprintf(fp, "include disable-programs.inc\t# user configuration for programs such as firefox, vlc etc.\n");
166 fprintf(fp, "include disable-programs.inc\n"); 114 fprintf(fp, "#include disable-shell.inc\t# sh, bash, zsh etc.\n");
167 fprintf(fp, "#include disable-xdg.inc\n"); 115 fprintf(fp, "#include disable-xdg.inc\t# standard user directories: Documents, Pictures, Videos, Music\n");
168 fprintf(fp, "\n"); 116 fprintf(fp, "\n");
169 117
170 fprintf(fp, "### Home Directory Whitelisting ###\n"); 118 fprintf(fp, "### Home Directory Whitelisting ###\n");
171 fprintf(fp, "### If something goes wrong, this section is the first one to comment out.\n"); 119 fprintf(fp, "### If something goes wrong, this section is the first one to comment out.\n");
172 fprintf(fp, "### Instead, you'll have to relay on the basic blacklisting above.\n"); 120 fprintf(fp, "### Instead, you'll have to relay on the basic blacklisting above.\n");
173 build_home(trace_output, fp); 121 build_home(trace_output, fp);
122 fprintf(fp, "\n");
174 123
175 fprintf(fp, "\n### The Rest of the Filesystem ###\n"); 124 fprintf(fp, "### Filesystem Whitelisting ###\n");
176 build_share(trace_output, fp); 125 build_share(trace_output, fp);
126 //todo: include whitelist-runuser-common.inc
177 build_var(trace_output, fp); 127 build_var(trace_output, fp);
178 build_bin(trace_output, fp); 128 fprintf(fp, "\n");
179 build_dev(trace_output, fp);
180 fprintf(fp, "#nodvd\n");
181 fprintf(fp, "#noinput\n");
182 fprintf(fp, "#notv\n");
183 fprintf(fp, "#nou2f\n");
184 fprintf(fp, "#novideo\n");
185 build_etc(trace_output, fp);
186 build_tmp(trace_output, fp);
187 129
188 fprintf(fp, "\n### Security Filters ###\n"); 130 fprintf(fp, "#apparmor\t# if you have AppArmor running, try this one!\n");
189 fprintf(fp, "#apparmor\n");
190 fprintf(fp, "caps.drop all\n"); 131 fprintf(fp, "caps.drop all\n");
132 fprintf(fp, "ipc-namespace\n");
191 fprintf(fp, "netfilter\n"); 133 fprintf(fp, "netfilter\n");
192 fprintf(fp, "#nogroups\n"); 134 fprintf(fp, "#no3d\t# disable 3D acceleration\n");
193 fprintf(fp, "#noroot\n"); 135 fprintf(fp, "#nodvd\t# disable DVD and CD devices\n");
136 fprintf(fp, "#nogroups\t# disable supplementary user groups\n");
137 fprintf(fp, "#noinput\t# disable input devices\n");
194 fprintf(fp, "nonewprivs\n"); 138 fprintf(fp, "nonewprivs\n");
139 fprintf(fp, "noroot\n");
140 fprintf(fp, "#notv\t# disable DVB TV devices\n");
141 fprintf(fp, "#nou2f\t# disable U2F devices\n");
142 fprintf(fp, "#novideo\t# disable video capture devices\n");
195 build_protocol(trace_output, fp); 143 build_protocol(trace_output, fp);
144 fprintf(fp, "seccomp !chroot\t# allowing chroot, just in case this is an Electron app\n");
145 fprintf(fp, "shell none\n");
146 fprintf(fp, "tracelog\n");
147 fprintf(fp, "\n");
148
149 fprintf(fp, "#disable-mnt\t# no access to /mnt, /media, /run/mount and /run/media\n");
150 build_bin(trace_output, fp);
151 fprintf(fp, "#private-cache\t# run with an empty ~/.cache directory\n");
152 build_dev(trace_output, fp);
153 build_etc(trace_output, fp);
154 fprintf(fp, "#private-lib\n");
155 build_tmp(trace_output, fp);
156 fprintf(fp, "\n");
157
158 fprintf(fp, "#dbus-user none\n");
159 fprintf(fp, "#dbus-system none\n");
160 fprintf(fp, "\n");
161 fprintf(fp, "#memory-deny-write-execute\n");
196 162
197 fprintf(fp, "seccomp\n"); 163 if (!arg_debug)
198 if (!have_strace) {
199 fprintf(fp, "### If you install strace on your system, Firejail will also create a\n");
200 fprintf(fp, "### whitelisted seccomp filter.\n");
201 }
202 else if (!have_yama_permission)
203 fprintf(fp, "### Yama security module prevents creation of a whitelisted seccomp filter\n");
204 else
205 build_seccomp(strace_output, fp);
206 fprintf(fp, "#shell none\n");
207 fprintf(fp, "#tracelog\n");
208
209 if (!arg_debug) {
210 unlink(trace_output); 164 unlink(trace_output);
211 unlink(strace_output);
212 }
213 } 165 }
214 else { 166 else {
215 fprintf(stderr, "Error: cannot run the sandbox\n"); 167 fprintf(stderr, "Error: cannot run the sandbox\n");