diff options
author | netblue30 <netblue30@yahoo.com> | 2017-01-10 10:07:20 -0500 |
---|---|---|
committer | netblue30 <netblue30@yahoo.com> | 2017-01-10 10:07:20 -0500 |
commit | 9aa81442afc6e00ca177bf0e3e7a025195102f7d (patch) | |
tree | cedef10be6c5efa2b3a87ec2568836891e696c61 /src/firejail/fs_home.c | |
parent | Merge pull request #1027 from reinerh/cve-references2 (diff) | |
download | firejail-9aa81442afc6e00ca177bf0e3e7a025195102f7d.tar.gz firejail-9aa81442afc6e00ca177bf0e3e7a025195102f7d.tar.zst firejail-9aa81442afc6e00ca177bf0e3e7a025195102f7d.zip |
security fix
Diffstat (limited to 'src/firejail/fs_home.c')
-rw-r--r-- | src/firejail/fs_home.c | 148 |
1 files changed, 36 insertions, 112 deletions
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c index 4de082b06..e4b19d5cc 100644 --- a/src/firejail/fs_home.c +++ b/src/firejail/fs_home.c | |||
@@ -42,19 +42,17 @@ static void skel(const char *homedir, uid_t u, gid_t g) { | |||
42 | // don't copy it if we already have the file | 42 | // don't copy it if we already have the file |
43 | if (stat(fname, &s) == 0) | 43 | if (stat(fname, &s) == 0) |
44 | return; | 44 | return; |
45 | if (is_link(fname)) { // stat on dangling symlinks fails, try again using lstat | ||
46 | fprintf(stderr, "Error: invalid %s file\n", fname); | ||
47 | exit(1); | ||
48 | } | ||
45 | if (stat("/etc/skel/.zshrc", &s) == 0) { | 49 | if (stat("/etc/skel/.zshrc", &s) == 0) { |
46 | if (copy_file("/etc/skel/.zshrc", fname, u, g, 0644) == 0) { | 50 | copy_file_as_user("/etc/skel/.zshrc", fname, u, g, 0644); |
47 | fs_logger("clone /etc/skel/.zshrc"); | 51 | fs_logger("clone /etc/skel/.zshrc"); |
48 | } | ||
49 | } | 52 | } |
50 | else { // | 53 | else { |
51 | FILE *fp = fopen(fname, "w"); | 54 | touch_file_as_user(fname, u, g, 0644); |
52 | if (fp) { | 55 | fs_logger2("touch", fname); |
53 | fprintf(fp, "\n"); | ||
54 | SET_PERMS_STREAM(fp, u, g, S_IRUSR | S_IWUSR); | ||
55 | fclose(fp); | ||
56 | fs_logger2("touch", fname); | ||
57 | } | ||
58 | } | 56 | } |
59 | free(fname); | 57 | free(fname); |
60 | } | 58 | } |
@@ -64,23 +62,21 @@ static void skel(const char *homedir, uid_t u, gid_t g) { | |||
64 | if (asprintf(&fname, "%s/.cshrc", homedir) == -1) | 62 | if (asprintf(&fname, "%s/.cshrc", homedir) == -1) |
65 | errExit("asprintf"); | 63 | errExit("asprintf"); |
66 | struct stat s; | 64 | struct stat s; |
65 | |||
67 | // don't copy it if we already have the file | 66 | // don't copy it if we already have the file |
68 | if (stat(fname, &s) == 0) | 67 | if (stat(fname, &s) == 0) |
69 | return; | 68 | return; |
69 | if (is_link(fname)) { // stat on dangling symlinks fails, try again using lstat | ||
70 | fprintf(stderr, "Error: invalid %s file\n", fname); | ||
71 | exit(1); | ||
72 | } | ||
70 | if (stat("/etc/skel/.cshrc", &s) == 0) { | 73 | if (stat("/etc/skel/.cshrc", &s) == 0) { |
71 | if (copy_file("/etc/skel/.cshrc", fname, u, g, 0644) == 0) { | 74 | copy_file_as_user("/etc/skel/.cshrc", fname, u, g, 0644); |
72 | fs_logger("clone /etc/skel/.cshrc"); | 75 | fs_logger("clone /etc/skel/.cshrc"); |
73 | } | ||
74 | } | 76 | } |
75 | else { // | 77 | else { |
76 | /* coverity[toctou] */ | 78 | touch_file_as_user(fname, u, g, 0644); |
77 | FILE *fp = fopen(fname, "w"); | 79 | fs_logger2("touch", fname); |
78 | if (fp) { | ||
79 | fprintf(fp, "\n"); | ||
80 | SET_PERMS_STREAM(fp, u, g, S_IRUSR | S_IWUSR); | ||
81 | fclose(fp); | ||
82 | fs_logger2("touch", fname); | ||
83 | } | ||
84 | } | 80 | } |
85 | free(fname); | 81 | free(fname); |
86 | } | 82 | } |
@@ -93,10 +89,13 @@ static void skel(const char *homedir, uid_t u, gid_t g) { | |||
93 | // don't copy it if we already have the file | 89 | // don't copy it if we already have the file |
94 | if (stat(fname, &s) == 0) | 90 | if (stat(fname, &s) == 0) |
95 | return; | 91 | return; |
92 | if (is_link(fname)) { // stat on dangling symlinks fails, try again using lstat | ||
93 | fprintf(stderr, "Error: invalid %s file\n", fname); | ||
94 | exit(1); | ||
95 | } | ||
96 | if (stat("/etc/skel/.bashrc", &s) == 0) { | 96 | if (stat("/etc/skel/.bashrc", &s) == 0) { |
97 | if (copy_file("/etc/skel/.bashrc", fname, u, g, 0644) == 0) { | 97 | copy_file_as_user("/etc/skel/.bashrc", fname, u, g, 0644); |
98 | fs_logger("clone /etc/skel/.bashrc"); | 98 | fs_logger("clone /etc/skel/.bashrc"); |
99 | } | ||
100 | } | 99 | } |
101 | free(fname); | 100 | free(fname); |
102 | } | 101 | } |
@@ -106,7 +105,7 @@ static int store_xauthority(void) { | |||
106 | // put a copy of .Xauthority in XAUTHORITY_FILE | 105 | // put a copy of .Xauthority in XAUTHORITY_FILE |
107 | char *src; | 106 | char *src; |
108 | char *dest = RUN_XAUTHORITY_FILE; | 107 | char *dest = RUN_XAUTHORITY_FILE; |
109 | // create an empty file | 108 | // create an empty file as root, and change ownership to user |
110 | FILE *fp = fopen(dest, "w"); | 109 | FILE *fp = fopen(dest, "w"); |
111 | if (fp) { | 110 | if (fp) { |
112 | fprintf(fp, "\n"); | 111 | fprintf(fp, "\n"); |
@@ -124,27 +123,8 @@ static int store_xauthority(void) { | |||
124 | return 0; | 123 | return 0; |
125 | } | 124 | } |
126 | 125 | ||
127 | pid_t child = fork(); | 126 | copy_file_as_user(src, dest, getuid(), getgid(), 0600); |
128 | if (child < 0) | 127 | fs_logger2("clone", dest); |
129 | errExit("fork"); | ||
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); | ||
145 | } | ||
146 | // wait for the child to finish | ||
147 | waitpid(child, NULL, 0); | ||
148 | return 1; // file copied | 128 | return 1; // file copied |
149 | } | 129 | } |
150 | 130 | ||
@@ -152,9 +132,10 @@ static int store_xauthority(void) { | |||
152 | } | 132 | } |
153 | 133 | ||
154 | static int store_asoundrc(void) { | 134 | static int store_asoundrc(void) { |
135 | // put a copy of .Xauthority in XAUTHORITY_FILE | ||
155 | char *src; | 136 | char *src; |
156 | char *dest = RUN_ASOUNDRC_FILE; | 137 | char *dest = RUN_ASOUNDRC_FILE; |
157 | // create an empty file | 138 | // create an empty file as root, and change ownership to user |
158 | FILE *fp = fopen(dest, "w"); | 139 | FILE *fp = fopen(dest, "w"); |
159 | if (fp) { | 140 | if (fp) { |
160 | fprintf(fp, "\n"); | 141 | fprintf(fp, "\n"); |
@@ -182,27 +163,8 @@ static int store_asoundrc(void) { | |||
182 | free(rp); | 163 | free(rp); |
183 | } | 164 | } |
184 | 165 | ||
185 | pid_t child = fork(); | 166 | copy_file_as_user(src, dest, getuid(), getgid(), 0644); |
186 | if (child < 0) | 167 | fs_logger2("clone", dest); |
187 | errExit("fork"); | ||
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); | ||
203 | } | ||
204 | // wait for the child to finish | ||
205 | waitpid(child, NULL, 0); | ||
206 | return 1; // file copied | 168 | return 1; // file copied |
207 | } | 169 | } |
208 | 170 | ||
@@ -222,27 +184,8 @@ static void copy_xauthority(void) { | |||
222 | exit(1); | 184 | exit(1); |
223 | } | 185 | } |
224 | 186 | ||
225 | pid_t child = fork(); | 187 | copy_file_as_user(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR); |
226 | if (child < 0) | 188 | fs_logger2("clone", dest); |
227 | errExit("fork"); | ||
228 | if (child == 0) { | ||
229 | // drop privileges | ||
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); | ||
243 | } | ||
244 | // wait for the child to finish | ||
245 | waitpid(child, NULL, 0); | ||
246 | 189 | ||
247 | // delete the temporary file | 190 | // delete the temporary file |
248 | unlink(src); | 191 | unlink(src); |
@@ -261,27 +204,8 @@ static void copy_asoundrc(void) { | |||
261 | exit(1); | 204 | exit(1); |
262 | } | 205 | } |
263 | 206 | ||
264 | pid_t child = fork(); | 207 | copy_file_as_user(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR); |
265 | if (child < 0) | 208 | fs_logger2("clone", dest); |
266 | errExit("fork"); | ||
267 | if (child == 0) { | ||
268 | // drop privileges | ||
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); | ||
282 | } | ||
283 | // wait for the child to finish | ||
284 | waitpid(child, NULL, 0); | ||
285 | 209 | ||
286 | // delete the temporary file | 210 | // delete the temporary file |
287 | unlink(src); | 211 | unlink(src); |