diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/firejail/checkcfg.c | 8 | ||||
-rw-r--r-- | src/firejail/firejail.h | 3 | ||||
-rw-r--r-- | src/firejail/fs.c | 132 |
3 files changed, 78 insertions, 65 deletions
diff --git a/src/firejail/checkcfg.c b/src/firejail/checkcfg.c index fed934434..5bc859f8d 100644 --- a/src/firejail/checkcfg.c +++ b/src/firejail/checkcfg.c | |||
@@ -241,6 +241,14 @@ int checkcfg(int val) { | |||
241 | else | 241 | else |
242 | goto errout; | 242 | goto errout; |
243 | } | 243 | } |
244 | else if (strncmp(ptr, "chroot-desktop ", 15) == 0) { | ||
245 | if (strcmp(ptr + 15, "yes") == 0) | ||
246 | cfg_val[CFG_CHROOT_DESKTOP] = 1; | ||
247 | else if (strcmp(ptr + 15, "no") == 0) | ||
248 | cfg_val[CFG_CHROOT_DESKTOP] = 0; | ||
249 | else | ||
250 | goto errout; | ||
251 | } | ||
244 | else | 252 | else |
245 | goto errout; | 253 | goto errout; |
246 | 254 | ||
diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h index 8e30e929a..abbaa807c 100644 --- a/src/firejail/firejail.h +++ b/src/firejail/firejail.h | |||
@@ -593,7 +593,8 @@ void sandboxfs(int op, pid_t pid, const char *patqh); | |||
593 | #define CFG_XEPHYR_WINDOW_TITLE 10 | 593 | #define CFG_XEPHYR_WINDOW_TITLE 10 |
594 | #define CFG_REMOUNT_PROC_SYS 11 | 594 | #define CFG_REMOUNT_PROC_SYS 11 |
595 | #define CFG_OVERLAYFS 12 | 595 | #define CFG_OVERLAYFS 12 |
596 | #define CFG_MAX 13 // this should always be the last entry | 596 | #define CFG_CHROOT_DESKTOP 13 |
597 | #define CFG_MAX 14 // this should always be the last entry | ||
597 | extern char *xephyr_screen; | 598 | extern char *xephyr_screen; |
598 | extern char *xephyr_extra_params; | 599 | extern char *xephyr_extra_params; |
599 | extern char *netfilter_default; | 600 | extern char *netfilter_default; |
diff --git a/src/firejail/fs.c b/src/firejail/fs.c index c5ef27615..6c87df1e9 100644 --- a/src/firejail/fs.c +++ b/src/firejail/fs.c | |||
@@ -1211,56 +1211,58 @@ int fs_check_chroot_dir(const char *rootdir) { | |||
1211 | void fs_chroot(const char *rootdir) { | 1211 | void fs_chroot(const char *rootdir) { |
1212 | assert(rootdir); | 1212 | assert(rootdir); |
1213 | 1213 | ||
1214 | // mount-bind a /dev in rootdir | 1214 | if (checkcfg(CFG_CHROOT_DESKTOP)) { |
1215 | char *newdev; | 1215 | // mount-bind a /dev in rootdir |
1216 | if (asprintf(&newdev, "%s/dev", rootdir) == -1) | 1216 | char *newdev; |
1217 | errExit("asprintf"); | 1217 | if (asprintf(&newdev, "%s/dev", rootdir) == -1) |
1218 | if (arg_debug) | ||
1219 | printf("Mounting /dev on %s\n", newdev); | ||
1220 | if (mount("/dev", newdev, NULL, MS_BIND|MS_REC, NULL) < 0) | ||
1221 | errExit("mounting /dev"); | ||
1222 | free(newdev); | ||
1223 | |||
1224 | // x11 | ||
1225 | if (getenv("FIREJAIL_X11")) { | ||
1226 | char *newx11; | ||
1227 | if (asprintf(&newx11, "%s/tmp/.X11-unix", rootdir) == -1) | ||
1228 | errExit("asprintf"); | 1218 | errExit("asprintf"); |
1229 | if (arg_debug) | 1219 | if (arg_debug) |
1230 | printf("Mounting /tmp/.X11-unix on %s\n", newx11); | 1220 | printf("Mounting /dev on %s\n", newdev); |
1231 | if (mount("/tmp/.X11-unix", newx11, NULL, MS_BIND|MS_REC, NULL) < 0) | 1221 | if (mount("/dev", newdev, NULL, MS_BIND|MS_REC, NULL) < 0) |
1232 | errExit("mounting /tmp/.X11-unix"); | 1222 | errExit("mounting /dev"); |
1233 | free(newx11); | 1223 | free(newdev); |
1234 | } | 1224 | |
1235 | 1225 | // x11 | |
1236 | // some older distros don't have a /run directory | 1226 | if (getenv("FIREJAIL_X11")) { |
1237 | // create one by default | 1227 | char *newx11; |
1238 | // no exit on error, let the user deal with any problems | 1228 | if (asprintf(&newx11, "%s/tmp/.X11-unix", rootdir) == -1) |
1239 | char *rundir; | 1229 | errExit("asprintf"); |
1240 | if (asprintf(&rundir, "%s/run", rootdir) == -1) | 1230 | if (arg_debug) |
1241 | errExit("asprintf"); | 1231 | printf("Mounting /tmp/.X11-unix on %s\n", newx11); |
1242 | if (!is_dir(rundir)) { | 1232 | if (mount("/tmp/.X11-unix", newx11, NULL, MS_BIND|MS_REC, NULL) < 0) |
1243 | int rv = mkdir(rundir, 0755); | 1233 | errExit("mounting /tmp/.X11-unix"); |
1244 | (void) rv; | 1234 | free(newx11); |
1245 | rv = chown(rundir, 0, 0); | 1235 | } |
1246 | (void) rv; | 1236 | |
1237 | // some older distros don't have a /run directory | ||
1238 | // create one by default | ||
1239 | // no exit on error, let the user deal with any problems | ||
1240 | char *rundir; | ||
1241 | if (asprintf(&rundir, "%s/run", rootdir) == -1) | ||
1242 | errExit("asprintf"); | ||
1243 | if (!is_dir(rundir)) { | ||
1244 | int rv = mkdir(rundir, 0755); | ||
1245 | (void) rv; | ||
1246 | rv = chown(rundir, 0, 0); | ||
1247 | (void) rv; | ||
1248 | } | ||
1249 | |||
1250 | // copy /etc/resolv.conf in chroot directory | ||
1251 | // if resolv.conf in chroot is a symbolic link, this will fail | ||
1252 | // no exit on error, let the user deal with the problem | ||
1253 | char *fname; | ||
1254 | if (asprintf(&fname, "%s/etc/resolv.conf", rootdir) == -1) | ||
1255 | errExit("asprintf"); | ||
1256 | if (arg_debug) | ||
1257 | printf("Updating /etc/resolv.conf in %s\n", fname); | ||
1258 | if (is_link(fname)) { | ||
1259 | fprintf(stderr, "Error: invalid %s file\n", fname); | ||
1260 | exit(1); | ||
1261 | } | ||
1262 | if (copy_file("/etc/resolv.conf", fname) == -1) | ||
1263 | fprintf(stderr, "Warning: /etc/resolv.conf not initialized\n"); | ||
1247 | } | 1264 | } |
1248 | 1265 | ||
1249 | // copy /etc/resolv.conf in chroot directory | ||
1250 | // if resolv.conf in chroot is a symbolic link, this will fail | ||
1251 | // no exit on error, let the user deal with the problem | ||
1252 | char *fname; | ||
1253 | if (asprintf(&fname, "%s/etc/resolv.conf", rootdir) == -1) | ||
1254 | errExit("asprintf"); | ||
1255 | if (arg_debug) | ||
1256 | printf("Updating /etc/resolv.conf in %s\n", fname); | ||
1257 | if (is_link(fname)) { | ||
1258 | fprintf(stderr, "Error: invalid %s file\n", fname); | ||
1259 | exit(1); | ||
1260 | } | ||
1261 | if (copy_file("/etc/resolv.conf", fname) == -1) | ||
1262 | fprintf(stderr, "Warning: /etc/resolv.conf not initialized\n"); | ||
1263 | |||
1264 | // chroot into the new directory | 1266 | // chroot into the new directory |
1265 | if (arg_debug) | 1267 | if (arg_debug) |
1266 | printf("Chrooting into %s\n", rootdir); | 1268 | printf("Chrooting into %s\n", rootdir); |
@@ -1269,24 +1271,26 @@ void fs_chroot(const char *rootdir) { | |||
1269 | // mount a new tmpfs in /run/firejail/mnt - the old one was lost in chroot | 1271 | // mount a new tmpfs in /run/firejail/mnt - the old one was lost in chroot |
1270 | fs_build_remount_mnt_dir(); | 1272 | fs_build_remount_mnt_dir(); |
1271 | 1273 | ||
1272 | // update /var directory in order to support multiple sandboxes running on the same root directory | 1274 | if (checkcfg(CFG_CHROOT_DESKTOP)) { |
1273 | if (!arg_private_dev) | 1275 | // update /var directory in order to support multiple sandboxes running on the same root directory |
1274 | fs_dev_shm(); | 1276 | if (!arg_private_dev) |
1275 | fs_var_lock(); | 1277 | fs_dev_shm(); |
1276 | fs_var_tmp(); | 1278 | fs_var_lock(); |
1277 | fs_var_log(); | 1279 | fs_var_tmp(); |
1278 | fs_var_lib(); | 1280 | fs_var_log(); |
1279 | fs_var_cache(); | 1281 | fs_var_lib(); |
1280 | fs_var_utmp(); | 1282 | fs_var_cache(); |
1281 | 1283 | fs_var_utmp(); | |
1282 | // don't leak user information | 1284 | |
1283 | restrict_users(); | 1285 | // don't leak user information |
1284 | 1286 | restrict_users(); | |
1285 | // when starting as root, firejail config is not disabled; | 1287 | |
1286 | // this mode could be used to install and test new software by chaining | 1288 | // when starting as root, firejail config is not disabled; |
1287 | // firejail sandboxes (firejail --force) | 1289 | // this mode could be used to install and test new software by chaining |
1288 | if (getuid() != 0) | 1290 | // firejail sandboxes (firejail --force) |
1289 | disable_config(); | 1291 | if (getuid() != 0) |
1292 | disable_config(); | ||
1293 | } | ||
1290 | } | 1294 | } |
1291 | #endif | 1295 | #endif |
1292 | 1296 | ||