aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLibravatar smitsohu <smitsohu@gmail.com>2021-06-26 16:34:49 +0200
committerLibravatar GitHub <noreply@github.com>2021-06-26 16:34:49 +0200
commit99e533580bd0a4cc5e90a2a1a8212356c85e2d38 (patch)
treeb4d1a27c0dae41f09096c942b96b8835c781730f /src
parentfirejail.h: fix typo of "either" in license header (diff)
parentfs_home.c: improve EUID switching, fix selinux relabeling (diff)
downloadfirejail-99e533580bd0a4cc5e90a2a1a8212356c85e2d38.tar.gz
firejail-99e533580bd0a4cc5e90a2a1a8212356c85e2d38.tar.zst
firejail-99e533580bd0a4cc5e90a2a1a8212356c85e2d38.zip
Merge pull request #4374 from smitsohu/euid
fs_home.c: run more code with euid of the user
Diffstat (limited to 'src')
-rw-r--r--src/firejail/firejail.h2
-rw-r--r--src/firejail/fs_home.c99
-rw-r--r--src/firejail/fs_whitelist.c5
-rw-r--r--src/firejail/sandbox.c2
-rw-r--r--src/firejail/util.c7
-rw-r--r--src/firejail/x11.c6
6 files changed, 77 insertions, 44 deletions
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index d175f1e83..af2777347 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -508,7 +508,7 @@ void logargs(int argc, char **argv) ;
508void logerr(const char *msg); 508void logerr(const char *msg);
509void set_nice(int inc); 509void set_nice(int inc);
510int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode); 510int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode);
511void copy_file_as_user(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode); 511void copy_file_as_user(const char *srcname, const char *destname, mode_t mode);
512void copy_file_from_user_to_root(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode); 512void copy_file_from_user_to_root(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode);
513void touch_file_as_user(const char *fname, mode_t mode); 513void touch_file_as_user(const char *fname, mode_t mode);
514int is_dir(const char *fname); 514int is_dir(const char *fname);
diff --git a/src/firejail/fs_home.c b/src/firejail/fs_home.c
index eab952eb8..1c4f9e07e 100644
--- a/src/firejail/fs_home.c
+++ b/src/firejail/fs_home.c
@@ -34,12 +34,13 @@
34#define O_PATH 010000000 34#define O_PATH 010000000
35#endif 35#endif
36 36
37static void skel(const char *homedir, uid_t u, gid_t g) { 37static void skel(const char *homedir) {
38 char *fname; 38 EUID_ASSERT();
39 39
40 // zsh 40 // zsh
41 if (!arg_shell_none && (strcmp(cfg.shell,"/usr/bin/zsh") == 0 || strcmp(cfg.shell,"/bin/zsh") == 0)) { 41 if (!arg_shell_none && (strcmp(cfg.shell,"/usr/bin/zsh") == 0 || strcmp(cfg.shell,"/bin/zsh") == 0)) {
42 // copy skel files 42 // copy skel files
43 char *fname;
43 if (asprintf(&fname, "%s/.zshrc", homedir) == -1) 44 if (asprintf(&fname, "%s/.zshrc", homedir) == -1)
44 errExit("asprintf"); 45 errExit("asprintf");
45 // don't copy it if we already have the file 46 // don't copy it if we already have the file
@@ -50,7 +51,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
50 exit(1); 51 exit(1);
51 } 52 }
52 if (access("/etc/skel/.zshrc", R_OK) == 0) { 53 if (access("/etc/skel/.zshrc", R_OK) == 0) {
53 copy_file_as_user("/etc/skel/.zshrc", fname, u, g, 0644); // regular user 54 copy_file_as_user("/etc/skel/.zshrc", fname, 0644); // regular user
54 fs_logger("clone /etc/skel/.zshrc"); 55 fs_logger("clone /etc/skel/.zshrc");
55 fs_logger2("clone", fname); 56 fs_logger2("clone", fname);
56 } 57 }
@@ -64,6 +65,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
64 // csh 65 // csh
65 else if (!arg_shell_none && strcmp(cfg.shell,"/bin/csh") == 0) { 66 else if (!arg_shell_none && strcmp(cfg.shell,"/bin/csh") == 0) {
66 // copy skel files 67 // copy skel files
68 char *fname;
67 if (asprintf(&fname, "%s/.cshrc", homedir) == -1) 69 if (asprintf(&fname, "%s/.cshrc", homedir) == -1)
68 errExit("asprintf"); 70 errExit("asprintf");
69 // don't copy it if we already have the file 71 // don't copy it if we already have the file
@@ -74,7 +76,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
74 exit(1); 76 exit(1);
75 } 77 }
76 if (access("/etc/skel/.cshrc", R_OK) == 0) { 78 if (access("/etc/skel/.cshrc", R_OK) == 0) {
77 copy_file_as_user("/etc/skel/.cshrc", fname, u, g, 0644); // regular user 79 copy_file_as_user("/etc/skel/.cshrc", fname, 0644); // regular user
78 fs_logger("clone /etc/skel/.cshrc"); 80 fs_logger("clone /etc/skel/.cshrc");
79 fs_logger2("clone", fname); 81 fs_logger2("clone", fname);
80 } 82 }
@@ -88,6 +90,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
88 // bash etc. 90 // bash etc.
89 else { 91 else {
90 // copy skel files 92 // copy skel files
93 char *fname;
91 if (asprintf(&fname, "%s/.bashrc", homedir) == -1) 94 if (asprintf(&fname, "%s/.bashrc", homedir) == -1)
92 errExit("asprintf"); 95 errExit("asprintf");
93 // don't copy it if we already have the file 96 // don't copy it if we already have the file
@@ -98,7 +101,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
98 exit(1); 101 exit(1);
99 } 102 }
100 if (access("/etc/skel/.bashrc", R_OK) == 0) { 103 if (access("/etc/skel/.bashrc", R_OK) == 0) {
101 copy_file_as_user("/etc/skel/.bashrc", fname, u, g, 0644); // regular user 104 copy_file_as_user("/etc/skel/.bashrc", fname, 0644); // regular user
102 fs_logger("clone /etc/skel/.bashrc"); 105 fs_logger("clone /etc/skel/.bashrc");
103 fs_logger2("clone", fname); 106 fs_logger2("clone", fname);
104 } 107 }
@@ -108,6 +111,7 @@ static void skel(const char *homedir, uid_t u, gid_t g) {
108} 111}
109 112
110static int store_xauthority(void) { 113static int store_xauthority(void) {
114 EUID_ASSERT();
111 if (arg_x11_block) 115 if (arg_x11_block)
112 return 0; 116 return 0;
113 117
@@ -118,7 +122,7 @@ static int store_xauthority(void) {
118 errExit("asprintf"); 122 errExit("asprintf");
119 123
120 struct stat s; 124 struct stat s;
121 if (lstat_as_user(src, &s) == 0) { 125 if (lstat(src, &s) == 0) {
122 if (S_ISLNK(s.st_mode)) { 126 if (S_ISLNK(s.st_mode)) {
123 fwarning("invalid .Xauthority file\n"); 127 fwarning("invalid .Xauthority file\n");
124 free(src); 128 free(src);
@@ -126,6 +130,7 @@ static int store_xauthority(void) {
126 } 130 }
127 131
128 // create an empty file as root, and change ownership to user 132 // create an empty file as root, and change ownership to user
133 EUID_ROOT();
129 FILE *fp = fopen(dest, "we"); 134 FILE *fp = fopen(dest, "we");
130 if (fp) { 135 if (fp) {
131 fprintf(fp, "\n"); 136 fprintf(fp, "\n");
@@ -134,10 +139,11 @@ static int store_xauthority(void) {
134 } 139 }
135 else 140 else
136 errExit("fopen"); 141 errExit("fopen");
142 EUID_USER();
137 143
138 copy_file_as_user(src, dest, getuid(), getgid(), 0600); // regular user 144 copy_file_as_user(src, dest, 0600); // regular user
139 fs_logger2("clone", dest);
140 selinux_relabel_path(dest, src); 145 selinux_relabel_path(dest, src);
146 fs_logger2("clone", dest);
141 free(src); 147 free(src);
142 return 1; // file copied 148 return 1; // file copied
143 } 149 }
@@ -147,6 +153,7 @@ static int store_xauthority(void) {
147} 153}
148 154
149static int store_asoundrc(void) { 155static int store_asoundrc(void) {
156 EUID_ASSERT();
150 if (arg_nosound) 157 if (arg_nosound)
151 return 0; 158 return 0;
152 159
@@ -157,11 +164,11 @@ static int store_asoundrc(void) {
157 errExit("asprintf"); 164 errExit("asprintf");
158 165
159 struct stat s; 166 struct stat s;
160 if (lstat_as_user(src, &s) == 0) { 167 if (lstat(src, &s) == 0) {
161 if (S_ISLNK(s.st_mode)) { 168 if (S_ISLNK(s.st_mode)) {
162 // make sure the real path of the file is inside the home directory 169 // make sure the real path of the file is inside the home directory
163 /* coverity[toctou] */ 170 /* coverity[toctou] */
164 char *rp = realpath_as_user(src); 171 char *rp = realpath(src, NULL);
165 if (!rp) { 172 if (!rp) {
166 fprintf(stderr, "Error: Cannot access %s\n", src); 173 fprintf(stderr, "Error: Cannot access %s\n", src);
167 exit(1); 174 exit(1);
@@ -174,6 +181,7 @@ static int store_asoundrc(void) {
174 } 181 }
175 182
176 // create an empty file as root, and change ownership to user 183 // create an empty file as root, and change ownership to user
184 EUID_ROOT();
177 FILE *fp = fopen(dest, "we"); 185 FILE *fp = fopen(dest, "we");
178 if (fp) { 186 if (fp) {
179 fprintf(fp, "\n"); 187 fprintf(fp, "\n");
@@ -182,10 +190,11 @@ static int store_asoundrc(void) {
182 } 190 }
183 else 191 else
184 errExit("fopen"); 192 errExit("fopen");
193 EUID_USER();
185 194
186 copy_file_as_user(src, dest, getuid(), getgid(), 0644); // regular user 195 copy_file_as_user(src, dest, 0644); // regular user
187 selinux_relabel_path(dest, src);
188 fs_logger2("clone", dest); 196 fs_logger2("clone", dest);
197 selinux_relabel_path(dest, src);
189 free(src); 198 free(src);
190 return 1; // file copied 199 return 1; // file copied
191 } 200 }
@@ -195,6 +204,7 @@ static int store_asoundrc(void) {
195} 204}
196 205
197static void copy_xauthority(void) { 206static void copy_xauthority(void) {
207 EUID_ASSERT();
198 // copy XAUTHORITY_FILE in the new home directory 208 // copy XAUTHORITY_FILE in the new home directory
199 char *src = RUN_XAUTHORITY_FILE ; 209 char *src = RUN_XAUTHORITY_FILE ;
200 char *dest; 210 char *dest;
@@ -207,16 +217,18 @@ static void copy_xauthority(void) {
207 exit(1); 217 exit(1);
208 } 218 }
209 219
210 copy_file_as_user(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR); // regular user 220 copy_file_as_user(src, dest, S_IRUSR | S_IWUSR); // regular user
211 selinux_relabel_path(dest, src);
212 fs_logger2("clone", dest); 221 fs_logger2("clone", dest);
222 selinux_relabel_path(dest, dest);
213 free(dest); 223 free(dest);
214 224
215 // delete the temporary file 225 EUID_ROOT();
216 unlink(src); 226 unlink(src); // delete the temporary file
227 EUID_USER();
217} 228}
218 229
219static void copy_asoundrc(void) { 230static void copy_asoundrc(void) {
231 EUID_ASSERT();
220 // copy ASOUNDRC_FILE in the new home directory 232 // copy ASOUNDRC_FILE in the new home directory
221 char *src = RUN_ASOUNDRC_FILE ; 233 char *src = RUN_ASOUNDRC_FILE ;
222 char *dest; 234 char *dest;
@@ -229,13 +241,14 @@ static void copy_asoundrc(void) {
229 exit(1); 241 exit(1);
230 } 242 }
231 243
232 copy_file_as_user(src, dest, getuid(), getgid(), S_IRUSR | S_IWUSR); // regular user 244 copy_file_as_user(src, dest, S_IRUSR | S_IWUSR); // regular user
233 selinux_relabel_path(dest, src);
234 fs_logger2("clone", dest); 245 fs_logger2("clone", dest);
246 selinux_relabel_path(dest, dest);
235 free(dest); 247 free(dest);
236 248
237 // delete the temporary file 249 EUID_ROOT();
238 unlink(src); 250 unlink(src); // delete the temporary file
251 EUID_USER();
239} 252}
240 253
241// private mode (--private=homedir): 254// private mode (--private=homedir):
@@ -248,18 +261,18 @@ void fs_private_homedir(void) {
248 char *private_homedir = cfg.home_private; 261 char *private_homedir = cfg.home_private;
249 assert(homedir); 262 assert(homedir);
250 assert(private_homedir); 263 assert(private_homedir);
264 EUID_ASSERT();
265
266 uid_t u = getuid();
267 // gid_t g = getgid();
251 268
252 int xflag = store_xauthority(); 269 int xflag = store_xauthority();
253 int aflag = store_asoundrc(); 270 int aflag = store_asoundrc();
254 271
255 uid_t u = getuid();
256 gid_t g = getgid();
257
258 // mount bind private_homedir on top of homedir 272 // mount bind private_homedir on top of homedir
259 if (arg_debug) 273 if (arg_debug)
260 printf("Mount-bind %s on top of %s\n", private_homedir, homedir); 274 printf("Mount-bind %s on top of %s\n", private_homedir, homedir);
261 // get file descriptors for homedir and private_homedir, fails if there is any symlink 275 // get file descriptors for homedir and private_homedir, fails if there is any symlink
262 EUID_USER();
263 int src = safer_openat(-1, private_homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC); 276 int src = safer_openat(-1, private_homedir, O_PATH|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC);
264 if (src == -1) 277 if (src == -1)
265 errExit("opening private directory"); 278 errExit("opening private directory");
@@ -287,6 +300,7 @@ void fs_private_homedir(void) {
287 EUID_ROOT(); 300 EUID_ROOT();
288 if (bind_mount_by_fd(src, dst)) 301 if (bind_mount_by_fd(src, dst))
289 errExit("mount bind"); 302 errExit("mount bind");
303 EUID_USER();
290 304
291 // check /proc/self/mountinfo to confirm the mount is ok 305 // check /proc/self/mountinfo to confirm the mount is ok
292 MountData *mptr = get_last_mount(); 306 MountData *mptr = get_last_mount();
@@ -305,6 +319,7 @@ void fs_private_homedir(void) {
305// if (chmod(homedir, s.st_mode) == -1) 319// if (chmod(homedir, s.st_mode) == -1)
306// errExit("mount-bind chmod"); 320// errExit("mount-bind chmod");
307 321
322 EUID_ROOT();
308 if (u != 0) { 323 if (u != 0) {
309 // mask /root 324 // mask /root
310 if (arg_debug) 325 if (arg_debug)
@@ -323,8 +338,9 @@ void fs_private_homedir(void) {
323 selinux_relabel_path("/home", "/home"); 338 selinux_relabel_path("/home", "/home");
324 fs_logger("tmpfs /home"); 339 fs_logger("tmpfs /home");
325 } 340 }
341 EUID_USER();
326 342
327 skel(homedir, u, g); 343 skel(homedir);
328 if (xflag) 344 if (xflag)
329 copy_xauthority(); 345 copy_xauthority();
330 if (aflag) 346 if (aflag)
@@ -339,12 +355,15 @@ void fs_private_homedir(void) {
339void fs_private(void) { 355void fs_private(void) {
340 char *homedir = cfg.homedir; 356 char *homedir = cfg.homedir;
341 assert(homedir); 357 assert(homedir);
358 EUID_ASSERT();
359
342 uid_t u = getuid(); 360 uid_t u = getuid();
343 gid_t g = getgid(); 361 gid_t g = getgid();
344 362
345 int xflag = store_xauthority(); 363 int xflag = store_xauthority();
346 int aflag = store_asoundrc(); 364 int aflag = store_asoundrc();
347 365
366 EUID_ROOT();
348 // mask /root 367 // mask /root
349 if (arg_debug) 368 if (arg_debug)
350 printf("Mounting a new /root directory\n"); 369 printf("Mounting a new /root directory\n");
@@ -387,8 +406,9 @@ void fs_private(void) {
387 406
388 selinux_relabel_path(homedir, homedir); 407 selinux_relabel_path(homedir, homedir);
389 } 408 }
409 EUID_USER();
390 410
391 skel(homedir, u, g); 411 skel(homedir);
392 if (xflag) 412 if (xflag)
393 copy_xauthority(); 413 copy_xauthority();
394 if (aflag) 414 if (aflag)
@@ -530,26 +550,29 @@ static void duplicate(char *name) {
530// set skel files, 550// set skel files,
531// restore .Xauthority 551// restore .Xauthority
532void fs_private_home_list(void) { 552void fs_private_home_list(void) {
533 timetrace_start();
534
535 char *homedir = cfg.homedir; 553 char *homedir = cfg.homedir;
536 char *private_list = cfg.home_private_keep; 554 char *private_list = cfg.home_private_keep;
537 assert(homedir); 555 assert(homedir);
538 assert(private_list); 556 assert(private_list);
557 EUID_ASSERT();
539 558
540 int xflag = store_xauthority(); 559 timetrace_start();
541 int aflag = store_asoundrc();
542 560
543 uid_t uid = getuid(); 561 uid_t uid = getuid();
544 gid_t gid = getgid(); 562 gid_t gid = getgid();
545 563
564 int xflag = store_xauthority();
565 int aflag = store_asoundrc();
566
546 // create /run/firejail/mnt/home directory 567 // create /run/firejail/mnt/home directory
568 EUID_ROOT();
547 mkdir_attr(RUN_HOME_DIR, 0755, uid, gid); 569 mkdir_attr(RUN_HOME_DIR, 0755, uid, gid);
548 selinux_relabel_path(RUN_HOME_DIR, homedir); 570 selinux_relabel_path(RUN_HOME_DIR, homedir);
571
549 fs_logger_print(); // save the current log 572 fs_logger_print(); // save the current log
573 EUID_USER();
550 574
551 // copy the list of files in the new home directory 575 // copy the list of files in the new home directory
552 EUID_USER();
553 if (arg_debug) 576 if (arg_debug)
554 printf("Copying files in the new home:\n"); 577 printf("Copying files in the new home:\n");
555 char *dlist = strdup(cfg.home_private_keep); 578 char *dlist = strdup(cfg.home_private_keep);
@@ -588,6 +611,7 @@ void fs_private_home_list(void) {
588 if (bind_mount_path_to_fd(RUN_HOME_DIR, fd)) 611 if (bind_mount_path_to_fd(RUN_HOME_DIR, fd))
589 errExit("mount bind"); 612 errExit("mount bind");
590 close(fd); 613 close(fd);
614 EUID_USER();
591 615
592 // check /proc/self/mountinfo to confirm the mount is ok 616 // check /proc/self/mountinfo to confirm the mount is ok
593 MountData *mptr = get_last_mount(); 617 MountData *mptr = get_last_mount();
@@ -595,11 +619,7 @@ void fs_private_home_list(void) {
595 errLogExit("invalid private-home mount"); 619 errLogExit("invalid private-home mount");
596 fs_logger2("tmpfs", homedir); 620 fs_logger2("tmpfs", homedir);
597 621
598 // mask RUN_HOME_DIR, it is writable and not noexec 622 EUID_ROOT();
599 if (mount("tmpfs", RUN_HOME_DIR, "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0)
600 errExit("mounting tmpfs");
601 fs_logger2("tmpfs", RUN_HOME_DIR);
602
603 if (uid != 0) { 623 if (uid != 0) {
604 // mask /root 624 // mask /root
605 if (arg_debug) 625 if (arg_debug)
@@ -619,7 +639,12 @@ void fs_private_home_list(void) {
619 fs_logger("tmpfs /home"); 639 fs_logger("tmpfs /home");
620 } 640 }
621 641
622 skel(homedir, uid, gid); 642 // mask RUN_HOME_DIR, it is writable and not noexec
643 if (mount("tmpfs", RUN_HOME_DIR, "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME, "mode=755,gid=0") < 0)
644 errExit("mounting tmpfs");
645 EUID_USER();
646
647 skel(homedir);
623 if (xflag) 648 if (xflag)
624 copy_xauthority(); 649 copy_xauthority();
625 if (aflag) 650 if (aflag)
diff --git a/src/firejail/fs_whitelist.c b/src/firejail/fs_whitelist.c
index 370035a4d..7588f69b7 100644
--- a/src/firejail/fs_whitelist.c
+++ b/src/firejail/fs_whitelist.c
@@ -374,9 +374,12 @@ static void tmpfs_topdirs(const TopDir *topdirs) {
374 } 374 }
375 375
376 // user home directory 376 // user home directory
377 if (tmpfs_home) 377 if (tmpfs_home) {
378 // checks owner if outside /home 378 // checks owner if outside /home
379 EUID_USER();
379 fs_private(); 380 fs_private();
381 EUID_ROOT();
382 }
380 383
381 // /run/user/$UID directory 384 // /run/user/$UID directory
382 if (tmpfs_runuser) { 385 if (tmpfs_runuser) {
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index e06ba3617..95be3335f 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -840,6 +840,7 @@ int sandbox(void* sandbox_arg) {
840 // private mode 840 // private mode
841 //**************************** 841 //****************************
842 if (arg_private) { 842 if (arg_private) {
843 EUID_USER();
843 if (cfg.home_private) { // --private= 844 if (cfg.home_private) { // --private=
844 if (cfg.chrootdir) 845 if (cfg.chrootdir)
845 fwarning("private=directory feature is disabled in chroot\n"); 846 fwarning("private=directory feature is disabled in chroot\n");
@@ -858,6 +859,7 @@ int sandbox(void* sandbox_arg) {
858 } 859 }
859 else // --private 860 else // --private
860 fs_private(); 861 fs_private();
862 EUID_ROOT();
861 } 863 }
862 864
863 if (arg_private_dev) 865 if (arg_private_dev)
diff --git a/src/firejail/util.c b/src/firejail/util.c
index 68b76b8e8..8fcaf3f7b 100644
--- a/src/firejail/util.c
+++ b/src/firejail/util.c
@@ -370,7 +370,7 @@ int copy_file(const char *srcname, const char *destname, uid_t uid, gid_t gid, m
370} 370}
371 371
372// return -1 if error, 0 if no error 372// return -1 if error, 0 if no error
373void copy_file_as_user(const char *srcname, const char *destname, uid_t uid, gid_t gid, mode_t mode) { 373void copy_file_as_user(const char *srcname, const char *destname, mode_t mode) {
374 pid_t child = fork(); 374 pid_t child = fork();
375 if (child < 0) 375 if (child < 0)
376 errExit("fork"); 376 errExit("fork");
@@ -378,8 +378,8 @@ void copy_file_as_user(const char *srcname, const char *destname, uid_t uid, gid
378 // drop privileges 378 // drop privileges
379 drop_privs(0); 379 drop_privs(0);
380 380
381 // copy, set permissions and ownership 381 // copy, set permissions
382 int rv = copy_file(srcname, destname, uid, gid, mode); // already a regular user 382 int rv = copy_file(srcname, destname, -1, -1, mode); // already a regular user
383 if (rv) 383 if (rv)
384 fwarning("cannot copy %s\n", srcname); 384 fwarning("cannot copy %s\n", srcname);
385#ifdef HAVE_GCOV 385#ifdef HAVE_GCOV
@@ -1231,6 +1231,7 @@ unsigned extract_timeout(const char *str) {
1231} 1231}
1232 1232
1233void disable_file_or_dir(const char *fname) { 1233void disable_file_or_dir(const char *fname) {
1234 assert(geteuid() == 0);
1234 assert(fname); 1235 assert(fname);
1235 1236
1236 EUID_USER(); 1237 EUID_USER();
diff --git a/src/firejail/x11.c b/src/firejail/x11.c
index 0619ff380..896aa2fd3 100644
--- a/src/firejail/x11.c
+++ b/src/firejail/x11.c
@@ -1290,9 +1290,11 @@ void x11_xorg(void) {
1290 if (envar) { 1290 if (envar) {
1291 char *rp = realpath(envar, NULL); 1291 char *rp = realpath(envar, NULL);
1292 if (rp) { 1292 if (rp) {
1293 if (strcmp(rp, dest) != 0) 1293 if (strcmp(rp, dest) != 0) {
1294 // disable_file_or_dir returns with EUID 0 1294 EUID_ROOT();
1295 disable_file_or_dir(rp); 1295 disable_file_or_dir(rp);
1296 EUID_USER();
1297 }
1296 free(rp); 1298 free(rp);
1297 } 1299 }
1298 } 1300 }