diff options
author | 2017-01-04 18:13:45 -0500 | |
---|---|---|
committer | 2017-01-04 18:13:45 -0500 | |
commit | e74fdab5d2125ce8f058c1630ce7cce19cbdac16 (patch) | |
tree | 9a293ccb85ee28e732f27ed72b0023178d2bdddf /src | |
parent | Merge pull request #1021 from KOLANICH/fix_private-bin (diff) | |
download | firejail-e74fdab5d2125ce8f058c1630ce7cce19cbdac16.tar.gz firejail-e74fdab5d2125ce8f058c1630ce7cce19cbdac16.tar.zst firejail-e74fdab5d2125ce8f058c1630ce7cce19cbdac16.zip |
security fixes
Diffstat (limited to 'src')
-rw-r--r-- | src/fcopy/main.c | 2 | ||||
-rw-r--r-- | src/firejail/fs_home.c | 118 | ||||
-rw-r--r-- | src/firejail/pulseaudio.c | 45 | ||||
-rw-r--r-- | src/firejail/util.c | 4 |
4 files changed, 136 insertions, 33 deletions
diff --git a/src/fcopy/main.c b/src/fcopy/main.c index b1e2813db..a4f5ace11 100644 --- a/src/fcopy/main.c +++ b/src/fcopy/main.c | |||
@@ -41,7 +41,7 @@ static void copy_file(const char *srcname, const char *destname, mode_t mode, ui | |||
41 | // open source | 41 | // open source |
42 | int src = open(srcname, O_RDONLY); | 42 | int src = open(srcname, O_RDONLY); |
43 | if (src < 0) { | 43 | if (src < 0) { |
44 | fprintf(stderr, "Warning: cannot open %s, file not copied\n", srcname); | 44 | fprintf(stderr, "Warning fcopy: cannot open %s, file not copied\n", srcname); |
45 | return; | 45 | return; |
46 | } | 46 | } |
47 | 47 | ||
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c index f5e545bf3..4de082b06 100644 --- a/src/firejail/fs_home.c +++ b/src/firejail/fs_home.c | |||
@@ -106,6 +106,14 @@ static int store_xauthority(void) { | |||
106 | // put a copy of .Xauthority in XAUTHORITY_FILE | 106 | // put a copy of .Xauthority in XAUTHORITY_FILE |
107 | char *src; | 107 | char *src; |
108 | char *dest = RUN_XAUTHORITY_FILE; | 108 | char *dest = RUN_XAUTHORITY_FILE; |
109 | // create an empty file | ||
110 | FILE *fp = fopen(dest, "w"); | ||
111 | if (fp) { | ||
112 | fprintf(fp, "\n"); | ||
113 | SET_PERMS_STREAM(fp, getuid(), getgid(), 0600); | ||
114 | fclose(fp); | ||
115 | } | ||
116 | |||
109 | if (asprintf(&src, "%s/.Xauthority", cfg.homedir) == -1) | 117 | if (asprintf(&src, "%s/.Xauthority", cfg.homedir) == -1) |
110 | errExit("asprintf"); | 118 | errExit("asprintf"); |
111 | 119 | ||
@@ -115,12 +123,28 @@ static int store_xauthority(void) { | |||
115 | fprintf(stderr, "Warning: invalid .Xauthority file\n"); | 123 | fprintf(stderr, "Warning: invalid .Xauthority file\n"); |
116 | return 0; | 124 | return 0; |
117 | } | 125 | } |
118 | 126 | ||
119 | int rv = copy_file(src, dest, -1, -1, 0600); | 127 | pid_t child = fork(); |
120 | if (rv) { | 128 | if (child < 0) |
121 | fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n"); | 129 | errExit("fork"); |
122 | return 0; | 130 | if (child == 0) { |
131 | // drop privileges | ||
132 | drop_privs(0); | ||
133 | |||
134 | // copy, set permissions and ownership | ||
135 | int rv = copy_file(src, dest, getuid(), getgid(), 0600); | ||
136 | if (rv) | ||
137 | fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n"); | ||
138 | else { | ||
139 | fs_logger2("clone", dest); | ||
140 | } | ||
141 | #ifdef HAVE_GCOV | ||
142 | __gcov_flush(); | ||
143 | #endif | ||
144 | _exit(0); | ||
123 | } | 145 | } |
146 | // wait for the child to finish | ||
147 | waitpid(child, NULL, 0); | ||
124 | return 1; // file copied | 148 | return 1; // file copied |
125 | } | 149 | } |
126 | 150 | ||
@@ -130,6 +154,14 @@ static int store_xauthority(void) { | |||
130 | static int store_asoundrc(void) { | 154 | static int store_asoundrc(void) { |
131 | char *src; | 155 | char *src; |
132 | char *dest = RUN_ASOUNDRC_FILE; | 156 | char *dest = RUN_ASOUNDRC_FILE; |
157 | // create an empty file | ||
158 | FILE *fp = fopen(dest, "w"); | ||
159 | if (fp) { | ||
160 | fprintf(fp, "\n"); | ||
161 | SET_PERMS_STREAM(fp, getuid(), getgid(), 0644); | ||
162 | fclose(fp); | ||
163 | } | ||
164 | |||
133 | if (asprintf(&src, "%s/.asoundrc", cfg.homedir) == -1) | 165 | if (asprintf(&src, "%s/.asoundrc", cfg.homedir) == -1) |
134 | errExit("asprintf"); | 166 | errExit("asprintf"); |
135 | 167 | ||
@@ -150,11 +182,27 @@ static int store_asoundrc(void) { | |||
150 | free(rp); | 182 | free(rp); |
151 | } | 183 | } |
152 | 184 | ||
153 | int rv = copy_file(src, dest, -1, -1, -0644); | 185 | pid_t child = fork(); |
154 | if (rv) { | 186 | if (child < 0) |
155 | fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n"); | 187 | errExit("fork"); |
156 | return 0; | 188 | if (child == 0) { |
189 | // drop privileges | ||
190 | drop_privs(0); | ||
191 | |||
192 | // copy, set permissions and ownership | ||
193 | int rv = copy_file(src, dest, getuid(), getgid(), 0644); | ||
194 | if (rv) | ||
195 | fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n"); | ||
196 | else { | ||
197 | fs_logger2("clone", dest); | ||
198 | } | ||
199 | #ifdef HAVE_GCOV | ||
200 | __gcov_flush(); | ||
201 | #endif | ||
202 | _exit(0); | ||
157 | } | 203 | } |
204 | // wait for the child to finish | ||
205 | waitpid(child, NULL, 0); | ||
158 | return 1; // file copied | 206 | return 1; // file copied |
159 | } | 207 | } |
160 | 208 | ||
@@ -174,13 +222,27 @@ static void copy_xauthority(void) { | |||
174 | exit(1); | 222 | exit(1); |
175 | } | 223 | } |
176 | 224 | ||
177 | // copy, set permissions and ownership | 225 | pid_t child = fork(); |
178 | int rv = copy_file(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR); | 226 | if (child < 0) |
179 | if (rv) | 227 | errExit("fork"); |
180 | fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n"); | 228 | if (child == 0) { |
181 | else { | 229 | // drop privileges |
182 | fs_logger2("clone", dest); | 230 | drop_privs(0); |
231 | |||
232 | // copy, set permissions and ownership | ||
233 | int rv = copy_file(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR); | ||
234 | if (rv) | ||
235 | fprintf(stderr, "Warning: cannot transfer .Xauthority in private home directory\n"); | ||
236 | else { | ||
237 | fs_logger2("clone", dest); | ||
238 | } | ||
239 | #ifdef HAVE_GCOV | ||
240 | __gcov_flush(); | ||
241 | #endif | ||
242 | _exit(0); | ||
183 | } | 243 | } |
244 | // wait for the child to finish | ||
245 | waitpid(child, NULL, 0); | ||
184 | 246 | ||
185 | // delete the temporary file | 247 | // delete the temporary file |
186 | unlink(src); | 248 | unlink(src); |
@@ -199,13 +261,27 @@ static void copy_asoundrc(void) { | |||
199 | exit(1); | 261 | exit(1); |
200 | } | 262 | } |
201 | 263 | ||
202 | // copy, set permissions and ownership | 264 | pid_t child = fork(); |
203 | int rv = copy_file(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR); | 265 | if (child < 0) |
204 | if (rv) | 266 | errExit("fork"); |
205 | fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n"); | 267 | if (child == 0) { |
206 | else { | 268 | // drop privileges |
207 | fs_logger2("clone", dest); | 269 | drop_privs(0); |
270 | |||
271 | // copy, set permissions and ownership | ||
272 | int rv = copy_file(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR); | ||
273 | if (rv) | ||
274 | fprintf(stderr, "Warning: cannot transfer .asoundrc in private home directory\n"); | ||
275 | else { | ||
276 | fs_logger2("clone", dest); | ||
277 | } | ||
278 | #ifdef HAVE_GCOV | ||
279 | __gcov_flush(); | ||
280 | #endif | ||
281 | _exit(0); | ||
208 | } | 282 | } |
283 | // wait for the child to finish | ||
284 | waitpid(child, NULL, 0); | ||
209 | 285 | ||
210 | // delete the temporary file | 286 | // delete the temporary file |
211 | unlink(src); | 287 | unlink(src); |
diff --git a/src/firejail/pulseaudio.c b/src/firejail/pulseaudio.c index b3a22bad9..14a7f03dd 100644 --- a/src/firejail/pulseaudio.c +++ b/src/firejail/pulseaudio.c | |||
@@ -127,11 +127,25 @@ void pulseaudio_init(void) { | |||
127 | if (asprintf(&dir1, "%s/.config", cfg.homedir) == -1) | 127 | if (asprintf(&dir1, "%s/.config", cfg.homedir) == -1) |
128 | errExit("asprintf"); | 128 | errExit("asprintf"); |
129 | if (stat(dir1, &s) == -1) { | 129 | if (stat(dir1, &s) == -1) { |
130 | int rv = mkdir(dir1, 0755); | 130 | pid_t child = fork(); |
131 | if (rv == 0) { | 131 | if (child < 0) |
132 | if (set_perms(dir1, getuid(), getgid(), 0755)) | 132 | errExit("fork"); |
133 | {;} // do nothing | 133 | if (child == 0) { |
134 | // drop privileges | ||
135 | drop_privs(0); | ||
136 | |||
137 | int rv = mkdir(dir1, 0755); | ||
138 | if (rv == 0) { | ||
139 | if (set_perms(dir1, getuid(), getgid(), 0755)) | ||
140 | {;} // do nothing | ||
141 | } | ||
142 | #ifdef HAVE_GCOV | ||
143 | __gcov_flush(); | ||
144 | #endif | ||
145 | _exit(0); | ||
134 | } | 146 | } |
147 | // wait for the child to finish | ||
148 | waitpid(child, NULL, 0); | ||
135 | } | 149 | } |
136 | else { | 150 | else { |
137 | // make sure the directory is owned by the user | 151 | // make sure the directory is owned by the user |
@@ -145,12 +159,25 @@ void pulseaudio_init(void) { | |||
145 | if (asprintf(&dir1, "%s/.config/pulse", cfg.homedir) == -1) | 159 | if (asprintf(&dir1, "%s/.config/pulse", cfg.homedir) == -1) |
146 | errExit("asprintf"); | 160 | errExit("asprintf"); |
147 | if (stat(dir1, &s) == -1) { | 161 | if (stat(dir1, &s) == -1) { |
148 | /* coverity[toctou] */ | 162 | pid_t child = fork(); |
149 | int rv = mkdir(dir1, 0700); | 163 | if (child < 0) |
150 | if (rv == 0) { | 164 | errExit("fork"); |
151 | if (set_perms(dir1, getuid(), getgid(), 0700)) | 165 | if (child == 0) { |
152 | {;} // do nothing | 166 | // drop privileges |
167 | drop_privs(0); | ||
168 | |||
169 | int rv = mkdir(dir1, 0700); | ||
170 | if (rv == 0) { | ||
171 | if (set_perms(dir1, getuid(), getgid(), 0700)) | ||
172 | {;} // do nothing | ||
173 | } | ||
174 | #ifdef HAVE_GCOV | ||
175 | __gcov_flush(); | ||
176 | #endif | ||
177 | _exit(0); | ||
153 | } | 178 | } |
179 | // wait for the child to finish | ||
180 | waitpid(child, NULL, 0); | ||
154 | } | 181 | } |
155 | else { | 182 | else { |
156 | // make sure the directory is owned by the user | 183 | // make sure the directory is owned by the user |
diff --git a/src/firejail/util.c b/src/firejail/util.c index 75f2acdb9..5b94aa288 100644 --- a/src/firejail/util.c +++ b/src/firejail/util.c | |||
@@ -177,14 +177,14 @@ int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, m | |||
177 | // open source | 177 | // open source |
178 | int src = open(srcname, O_RDONLY); | 178 | int src = open(srcname, O_RDONLY); |
179 | if (src < 0) { | 179 | if (src < 0) { |
180 | fprintf(stderr, "Warning: cannot open %s, file not copied\n", srcname); | 180 | fprintf(stderr, "Warning: cannot open source file %s, file not copied\n", srcname); |
181 | return -1; | 181 | return -1; |
182 | } | 182 | } |
183 | 183 | ||
184 | // open destination | 184 | // open destination |
185 | int dst = open(destname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); | 185 | int dst = open(destname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); |
186 | if (dst < 0) { | 186 | if (dst < 0) { |
187 | fprintf(stderr, "Warning: cannot open %s, file not copied\n", destname); | 187 | fprintf(stderr, "Warning: cannot open destination file %s, file not copied\n", destname); |
188 | close(src); | 188 | close(src); |
189 | return -1; | 189 | return -1; |
190 | } | 190 | } |