CVE-2019-12589: Incorrect Permission Assignment for Critical Resource (CWE-732)
value: In Firejail before 0.9.60, seccomp filters are writable inside the jail, leading to a lack of intended seccomp restrictions for a process that is joined to the jail after a filter has been modified by an attacker.
CWE description: The product specifies permissions for a security-critical resource in a way that allows that resource to be read or modified by unintended actors.
CVSS v3 base score: 8.8
Published: 2019-06-03T03:29Z
Repository: https://github.com/netblue30/firejail
Language: C
Files changed: src/firejail/firejail.h, src/firejail/fs_lib.c, src/firejail/preproc.c, src/firejail/sandbox.c
Commit date: 2019-03-23 22:32:30 +0000
Commit message: mount runtime seccomp files read-only (#2602)

avoid creating locations in the file system that are both writable and
executable (in this case for processes with euid of the user).

for the same reason also remove user owned libfiles
when it is not needed any more
Diff: diff --git a/src/firejail/firejail.h b/src/firejail/firejail.h
index 5291361c..4cb10c87 100644
--- a/src/firejail/firejail.h
+++ b/src/firejail/firejail.h
@@ -55,17 +55,18 @@
 #define RUN_PULSE_DIR	"/run/firejail/mnt/pulse"
 #define RUN_LIB_DIR	"/run/firejail/mnt/lib"
 #define RUN_LIB_FILE	"/run/firejail/mnt/libfiles"
 #define RUN_DNS_ETC	"/run/firejail/mnt/dns-etc"
 
-#define RUN_SECCOMP_LIST	"/run/firejail/mnt/seccomp.list"	// list of seccomp files installed
-#define RUN_SECCOMP_PROTOCOL	"/run/firejail/mnt/seccomp.protocol"	// protocol filter
-#define RUN_SECCOMP_CFG	"/run/firejail/mnt/seccomp"			// configured filter
-#define RUN_SECCOMP_32	"/run/firejail/mnt/seccomp.32"		// 32bit arch filter installed on 64bit architectures
-#define RUN_SECCOMP_MDWX	"/run/firejail/mnt/seccomp.mdwx"		// filter for memory-deny-write-execute
-#define RUN_SECCOMP_BLOCK_SECONDARY	"/run/firejail/mnt/seccomp.block_secondary"	// secondary arch blocking filter
-#define RUN_SECCOMP_POSTEXEC	"/run/firejail/mnt/seccomp.postexec"		// filter for post-exec library
+#define RUN_SECCOMP_DIR	"/run/firejail/mnt/seccomp"
+#define RUN_SECCOMP_LIST	"/run/firejail/mnt/seccomp/seccomp.list"	// list of seccomp files installed
+#define RUN_SECCOMP_PROTOCOL	"/run/firejail/mnt/seccomp/seccomp.protocol"	// protocol filter
+#define RUN_SECCOMP_CFG	"/run/firejail/mnt/seccomp/seccomp"			// configured filter
+#define RUN_SECCOMP_32		"/run/firejail/mnt/seccomp/seccomp.32"		// 32bit arch filter installed on 64bit architectures
+#define RUN_SECCOMP_MDWX	"/run/firejail/mnt/seccomp/seccomp.mdwx"		// filter for memory-deny-write-execute
+#define RUN_SECCOMP_BLOCK_SECONDARY	"/run/firejail/mnt/seccomp/seccomp.block_secondary"	// secondary arch blocking filter
+#define RUN_SECCOMP_POSTEXEC	"/run/firejail/mnt/seccomp/seccomp.postexec"		// filter for post-exec library
 #define PATH_SECCOMP_DEFAULT (LIBDIR "/firejail/seccomp")			// default filter built during make
 #define PATH_SECCOMP_DEFAULT_DEBUG (LIBDIR "/firejail/seccomp.debug")	// default filter built during make
 #define PATH_SECCOMP_32 (LIBDIR "/firejail/seccomp.32")			// 32bit arch filter built during make
 #define PATH_SECCOMP_MDWX (LIBDIR "/firejail/seccomp.mdwx")		// filter for memory-deny-write-execute built during make
 #define PATH_SECCOMP_BLOCK_SECONDARY (LIBDIR "/firejail/seccomp.block_secondary")	// secondary arch blocking filter built during make
@@ -93,11 +94,10 @@
 #define RUN_XAUTHORITY_FILE	"/run/firejail/mnt/.Xauthority"
 #define RUN_XAUTHORITY_SEC_FILE	"/run/firejail/mnt/sec.Xauthority"
 #define RUN_ASOUNDRC_FILE	"/run/firejail/mnt/.asoundrc"
 #define RUN_HOSTNAME_FILE	"/run/firejail/mnt/hostname"
 #define RUN_HOSTS_FILE	"/run/firejail/mnt/hosts"
-#define RUN_RESOLVCONF_FILE	"/run/firejail/mnt/resolv.conf"
 #define RUN_MACHINEID	"/run/firejail/mnt/machine-id"
 #define RUN_LDPRELOAD_FILE	"/run/firejail/mnt/ld.so.preload"
 #define RUN_UTMP_FILE		"/run/firejail/mnt/utmp"
 #define RUN_PASSWD_FILE		"/run/firejail/mnt/passwd"
 #define RUN_GROUP_FILE		"/run/firejail/mnt/group"
diff --git a/src/firejail/fs_lib.c b/src/firejail/fs_lib.c
index 808ead24..70c6ac88 100644
--- a/src/firejail/fs_lib.c
+++ b/src/firejail/fs_lib.c
@@ -131,10 +131,11 @@ void fslib_copy_libs(const char *full_path) {
 		if (ptr)
 			*ptr = '\0';
 		fslib_duplicate(buf);
 	}
 	fclose(fp);
+	unlink(RUN_LIB_FILE);
 }
 
 
 void fslib_copy_dir(const char *full_path) {
 	assert(full_path);
diff --git a/src/firejail/preproc.c b/src/firejail/preproc.c
index 2effebba..a7af4b12 100644
--- a/src/firejail/preproc.c
+++ b/src/firejail/preproc.c
@@ -84,10 +84,12 @@ void preproc_mount_mnt_dir(void) {
 			errExit("mounting /run/firejail/mnt");
 		tmpfs_mounted = 1;
 		fs_logger2("tmpfs", RUN_MNT_DIR);
 
 #ifdef HAVE_SECCOMP
+		create_empty_dir_as_root(RUN_SECCOMP_DIR, 0755);
+
 		if (arg_seccomp_block_secondary)
 			copy_file(PATH_SECCOMP_BLOCK_SECONDARY, RUN_SECCOMP_BLOCK_SECONDARY, getuid(), getgid(), 0644); // root needed
 		else {
 			//copy default seccomp files
 			copy_file(PATH_SECCOMP_32, RUN_SECCOMP_32, getuid(), getgid(), 0644); // root needed
diff --git a/src/firejail/sandbox.c b/src/firejail/sandbox.c
index 2b5d3015..101a16d0 100644
--- a/src/firejail/sandbox.c
+++ b/src/firejail/sandbox.c
@@ -1051,13 +1051,10 @@ int sandbox(void* sandbox_arg) {
 	// set security filters
 	//****************************
 	// save state of nonewprivs
 	save_nonewprivs();
 
-	// set capabilities
-	set_caps();
-
 	// save cpu affinity mask to CPU_CFG file
 	save_cpu();
 
 	// save cgroup in CGROUP_CFG file
 	save_cgroup();
@@ -1099,12 +1096,17 @@ int sandbox(void* sandbox_arg) {
 	}
 	else {
 		int rv = unlink(RUN_SECCOMP_MDWX);
 		(void) rv;
 	}
+	// make seccomp filters read-only
+	fs_rdonly(RUN_SECCOMP_DIR);
 #endif
 
+	// set capabilities
+	set_caps();
+
 	//****************************************
 	// communicate progress of sandbox set up
 	// to --join
 	//****************************************
 

Vulnerable code: #define RUN_SECCOMP_LIST	"/run/firejail/mnt/seccomp.list"	// list of seccomp files installed
#define RUN_SECCOMP_PROTOCOL	"/run/firejail/mnt/seccomp.protocol"	// protocol filter
#define RUN_SECCOMP_CFG	"/run/firejail/mnt/seccomp"			// configured filter
#define RUN_SECCOMP_32	"/run/firejail/mnt/seccomp.32"		// 32bit arch filter installed on 64bit architectures
#define RUN_SECCOMP_MDWX	"/run/firejail/mnt/seccomp.mdwx"		// filter for memory-deny-write-execute
#define RUN_SECCOMP_BLOCK_SECONDARY	"/run/firejail/mnt/seccomp.block_secondary"	// secondary arch blocking filter
#define RUN_SECCOMP_POSTEXEC	"/run/firejail/mnt/seccomp.postexec"		// filter for post-exec library
#define RUN_RESOLVCONF_FILE	"/run/firejail/mnt/resolv.conf"
	// set capabilities
	set_caps();

Fixed code: #define RUN_SECCOMP_DIR	"/run/firejail/mnt/seccomp"
#define RUN_SECCOMP_LIST	"/run/firejail/mnt/seccomp/seccomp.list"	// list of seccomp files installed
#define RUN_SECCOMP_PROTOCOL	"/run/firejail/mnt/seccomp/seccomp.protocol"	// protocol filter
#define RUN_SECCOMP_CFG	"/run/firejail/mnt/seccomp/seccomp"			// configured filter
#define RUN_SECCOMP_32		"/run/firejail/mnt/seccomp/seccomp.32"		// 32bit arch filter installed on 64bit architectures
#define RUN_SECCOMP_MDWX	"/run/firejail/mnt/seccomp/seccomp.mdwx"		// filter for memory-deny-write-execute
#define RUN_SECCOMP_BLOCK_SECONDARY	"/run/firejail/mnt/seccomp/seccomp.block_secondary"	// secondary arch blocking filter
#define RUN_SECCOMP_POSTEXEC	"/run/firejail/mnt/seccomp/seccomp.postexec"		// filter for post-exec library
	unlink(RUN_LIB_FILE);
		create_empty_dir_as_root(RUN_SECCOMP_DIR, 0755);

	// make seccomp filters read-only
	fs_rdonly(RUN_SECCOMP_DIR);
	// set capabilities
	set_caps();