Example #1
0
static void filter_add_blacklist(int syscall) {
	assert(sfilter);
	assert(sfilter_alloc_size);
	assert(sfilter_index);
//	if (arg_debug)
//		printf("Blacklisting syscall %d %s\n", syscall, syscall_find_nr(syscall));
	
	if ((sfilter_index + 2) > sfilter_alloc_size)
		filter_realloc();
	
	struct sock_filter filter[] = {
		BLACKLIST(syscall)
	};
#if 0
{
	int i;
	unsigned char *ptr = (unsigned char *) &filter[0];
	for (i = 0; i < sizeof(filter); i++, ptr++)
		printf("%x, ", (*ptr) & 0xff);
	printf("\n");
}
#endif
	memcpy(&sfilter[sfilter_index], filter, sizeof(filter));
	sfilter_index += sizeof(filter) / sizeof(struct sock_filter);	
}
Example #2
0
void filter_add_blacklist(int fd, int syscall, int arg) {
	(void) arg;
	
	struct sock_filter filter[] = {
		BLACKLIST(syscall)
	};
	write_to_file(fd, filter, sizeof(filter));
}
Example #3
0
static struct sock_filter filter[] = {
	VALIDATE_ARCHITECTURE,
	EXAMINE_SYSCALL,

#if defined(__x86_64__)
#define X32_SYSCALL_BIT 0x40000000
	// handle X32 ABI
	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, X32_SYSCALL_BIT, 1, 0),
	BPF_JUMP(BPF_JMP+BPF_JGE+BPF_K, 0, 1, 0),
	RETURN_ERRNO(EPERM),
#endif

	// syscall list
#ifdef SYS_mount		
	BLACKLIST(SYS_mount),  // mount/unmount filesystems
#endif
#ifdef SYS_umount2		
	BLACKLIST(SYS_umount2),
#endif
#ifdef SYS_ptrace 		
	BLACKLIST(SYS_ptrace), // trace processes
#endif
#ifdef SYS_kexec_file_load		
	BLACKLIST(SYS_kexec_file_load),
#endif
#ifdef SYS_kexec_load		
	BLACKLIST(SYS_kexec_load), // loading a different kernel
#endif
#ifdef SYS_name_to_handle_at		
	BLACKLIST(SYS_name_to_handle_at),
Example #4
0
// i386 filter installed on amd64 architectures
void seccomp_filter_32(void) {
	// hardcoded syscall values
	struct sock_filter filter[] = {
		VALIDATE_ARCHITECTURE_32,
		EXAMINE_SYSCALL,
		BLACKLIST(21), // mount
		BLACKLIST(52), // umount2
		BLACKLIST(26), // ptrace
		BLACKLIST(283), // kexec_load
		BLACKLIST(342), // open_by_handle_at
		BLACKLIST(128), // init_module
		BLACKLIST(350), // finit_module
		BLACKLIST(129), // delete_module
		BLACKLIST(110), // iopl
		BLACKLIST(101), // ioperm
		BLACKLIST(87), // swapon
		BLACKLIST(115), // swapoff
		BLACKLIST(103), // syslog
		BLACKLIST(347), // process_vm_readv
		BLACKLIST(348), // process_vm_writev
		BLACKLIST(135), // sysfs
		BLACKLIST(149), // _sysctl
		BLACKLIST(124), // adjtimex
		BLACKLIST(343), // clock_adjtime
		BLACKLIST(253), // lookup_dcookie
		BLACKLIST(336), // perf_event_open
		BLACKLIST(338), // fanotify_init
		BLACKLIST(349), // kcmp
		BLACKLIST(286), // add_key
		BLACKLIST(287), // request_key
		BLACKLIST(288), // keyctl
		BLACKLIST(86), // uselib
		BLACKLIST(51), // acct
		BLACKLIST(123), // modify_ldt
		BLACKLIST(217), // pivot_root
		BLACKLIST(245), // io_setup
		BLACKLIST(246), // io_destroy
		BLACKLIST(247), // io_getevents
		BLACKLIST(248), // io_submit
		BLACKLIST(249), // io_cancel
		BLACKLIST(257), // remap_file_pages
		BLACKLIST(274), // mbind
		BLACKLIST(275), // get_mempolicy
		BLACKLIST(276), // set_mempolicy
		BLACKLIST(294), // migrate_pages
		BLACKLIST(317), // move_pages
		BLACKLIST(316), // vmsplice
		BLACKLIST(61),  // chroot
		BLACKLIST(88), // reboot
		BLACKLIST(169), // nfsservctl
		BLACKLIST(130), // get_kernel_syms
		RETURN_ALLOW
	};

	struct sock_fprog prog = {
		.len = (unsigned short)(sizeof(filter) / sizeof(filter[0])),
		.filter = filter,
	};

	if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
		;
	}
	else if (arg_debug) {
		printf("Dual i386/amd64 seccomp filter configured\n");
	}
}

// amd64 filter installed on i386 architectures
void seccomp_filter_64(void) {
	// hardcoded syscall values
	struct sock_filter filter[] = {
		VALIDATE_ARCHITECTURE_64,
		EXAMINE_SYSCALL,
		BLACKLIST(165), // mount
		BLACKLIST(166), // umount2
		BLACKLIST(101), // ptrace
		BLACKLIST(246), // kexec_load
		BLACKLIST(304), // open_by_handle_at
		BLACKLIST(175), // init_module
		BLACKLIST(313), // finit_module
		BLACKLIST(176), // delete_module
		BLACKLIST(172), // iopl
		BLACKLIST(173), // ioperm
		BLACKLIST(167), // swapon
		BLACKLIST(168), // swapoff
		BLACKLIST(103), // syslog
		BLACKLIST(310), // process_vm_readv
		BLACKLIST(311), // process_vm_writev
		BLACKLIST(139), // sysfs
		BLACKLIST(156), // _sysctl
		BLACKLIST(159), // adjtimex
		BLACKLIST(305), // clock_adjtime
		BLACKLIST(212), // lookup_dcookie
		BLACKLIST(298), // perf_event_open
		BLACKLIST(300), // fanotify_init
		BLACKLIST(312), // kcmp
		BLACKLIST(248), // add_key
		BLACKLIST(249), // request_key
		BLACKLIST(250), // keyctl
		BLACKLIST(134), // uselib
		BLACKLIST(163), // acct
		BLACKLIST(154), // modify_ldt
		BLACKLIST(155), // pivot_root
		BLACKLIST(206), // io_setup
		BLACKLIST(207), // io_destroy
		BLACKLIST(208), // io_getevents
		BLACKLIST(209), // io_submit
		BLACKLIST(210), // io_cancel
		BLACKLIST(216), // remap_file_pages
		BLACKLIST(237), // mbind
		BLACKLIST(239), // get_mempolicy
		BLACKLIST(238), // set_mempolicy
		BLACKLIST(256), // migrate_pages
		BLACKLIST(279), // move_pages
		BLACKLIST(278), // vmsplice
		BLACKLIST(161), // chroot
		BLACKLIST(184), // tuxcall
		BLACKLIST(169), // reboot
		BLACKLIST(180), // nfsservctl
		BLACKLIST(177), // get_kernel_syms
		RETURN_ALLOW
	};

	struct sock_fprog prog = {
		.len = (unsigned short)(sizeof(filter) / sizeof(filter[0])),
		.filter = filter,
	};

	if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
		;
	}
	else if (arg_debug) {
		printf("Dual i386/amd64 seccomp filter configured\n");
	}
}


// drop filter for seccomp option
int seccomp_filter_drop(int enforce_seccomp) {
	filter_init();
	
	// default seccomp
	if (cfg.seccomp_list_drop == NULL) {
#if defined(__x86_64__)
		seccomp_filter_32();
#endif
#if defined(__i386__)
		seccomp_filter_64();
#endif

#ifdef SYS_mount		
		filter_add_blacklist(SYS_mount, 0);
#endif
#ifdef SYS_umount2		
		filter_add_blacklist(SYS_umount2, 0);
#endif
#ifdef SYS_ptrace 		
		filter_add_blacklist(SYS_ptrace, 0);
#endif
#ifdef SYS_kexec_load		
		filter_add_blacklist(SYS_kexec_load, 0);
#endif
#ifdef SYS_kexec_file_load		
		filter_add_blacklist(SYS_kexec_file_load, 0);
#endif
#ifdef SYS_open_by_handle_at		
		filter_add_blacklist(SYS_open_by_handle_at, 0);
#endif
#ifdef SYS_init_module		
		filter_add_blacklist(SYS_init_module, 0);
#endif
#ifdef SYS_finit_module // introduced in 2013
		filter_add_blacklist(SYS_finit_module, 0);
#endif
#ifdef SYS_delete_module		
		filter_add_blacklist(SYS_delete_module, 0);
#endif
#ifdef SYS_iopl		
		filter_add_blacklist(SYS_iopl, 0);
#endif
#ifdef 	SYS_ioperm	
		filter_add_blacklist(SYS_ioperm, 0);
#endif
#ifdef SYS_ni_syscall // new io permissions call on arm devices
		filter_add_blacklist(SYS_ni_syscall, 0);
#endif
#ifdef SYS_swapon		
		filter_add_blacklist(SYS_swapon, 0);
#endif
#ifdef SYS_swapoff		
		filter_add_blacklist(SYS_swapoff, 0);
#endif
#ifdef SYS_syslog		
		filter_add_blacklist(SYS_syslog, 0);
#endif
#ifdef SYS_process_vm_readv		
		filter_add_blacklist(SYS_process_vm_readv, 0);
#endif
#ifdef SYS_process_vm_writev		
		filter_add_blacklist(SYS_process_vm_writev, 0);
#endif

// mknod removed in 0.9.29 - it brakes Zotero extension
//#ifdef SYS_mknod		
//		filter_add_blacklist(SYS_mknod, 0);
//#endif
		
		// new syscalls in 0.9,23		
#ifdef SYS_sysfs		
		filter_add_blacklist(SYS_sysfs, 0);
#endif
#ifdef SYS__sysctl	
		filter_add_blacklist(SYS__sysctl, 0);
#endif
#ifdef SYS_adjtimex		
		filter_add_blacklist(SYS_adjtimex, 0);
#endif
#ifdef 	SYS_clock_adjtime	
		filter_add_blacklist(SYS_clock_adjtime, 0);
#endif
#ifdef SYS_lookup_dcookie		
		filter_add_blacklist(SYS_lookup_dcookie, 0);
#endif
#ifdef 	SYS_perf_event_open	
		filter_add_blacklist(SYS_perf_event_open, 0);
#endif
#ifdef	SYS_fanotify_init 	
		filter_add_blacklist(SYS_fanotify_init, 0);
#endif
#ifdef SYS_kcmp
		filter_add_blacklist(SYS_kcmp, 0);
#endif

// 0.9.32
#ifdef SYS_add_key
		filter_add_blacklist(SYS_add_key, 0);
#endif
#ifdef SYS_request_key
		filter_add_blacklist(SYS_request_key, 0);
#endif
#ifdef SYS_keyctl
		filter_add_blacklist(SYS_keyctl, 0);
#endif
#ifdef SYS_uselib
		filter_add_blacklist(SYS_uselib, 0);
#endif
#ifdef SYS_acct
		filter_add_blacklist(SYS_acct, 0);
#endif
#ifdef SYS_modify_ldt
		filter_add_blacklist(SYS_modify_ldt, 0);
#endif
	//#ifdef SYS_unshare
	//		filter_add_blacklist(SYS_unshare, 0);
	//#endif
#ifdef SYS_pivot_root
		filter_add_blacklist(SYS_pivot_root, 0);
#endif
	//#ifdef SYS_quotactl
	//		filter_add_blacklist(SYS_quotactl, 0);
	//#endif
#ifdef SYS_io_setup
		filter_add_blacklist(SYS_io_setup, 0);
#endif
#ifdef SYS_io_destroy
		filter_add_blacklist(SYS_io_destroy, 0);
#endif
#ifdef SYS_io_getevents
		filter_add_blacklist(SYS_io_getevents, 0);
#endif
#ifdef SYS_io_submit
		filter_add_blacklist(SYS_io_submit, 0);
#endif
#ifdef SYS_io_cancel
		filter_add_blacklist(SYS_io_cancel, 0);
#endif
#ifdef SYS_remap_file_pages
		filter_add_blacklist(SYS_remap_file_pages, 0);
#endif
#ifdef SYS_mbind
		filter_add_blacklist(SYS_mbind, 0);
#endif
#ifdef SYS_get_mempolicy
		filter_add_blacklist(SYS_get_mempolicy, 0);
#endif
#ifdef SYS_set_mempolicy
		filter_add_blacklist(SYS_set_mempolicy, 0);
#endif
#ifdef SYS_migrate_pages
		filter_add_blacklist(SYS_migrate_pages, 0);
#endif
#ifdef SYS_move_pages
		filter_add_blacklist(SYS_move_pages, 0);
#endif
#ifdef SYS_vmsplice
		filter_add_blacklist(SYS_vmsplice, 0);
#endif
#ifdef SYS_chroot
		filter_add_blacklist(SYS_chroot, 0);
#endif
	//#ifdef SYS_set_robust_list
	//		filter_add_blacklist(SYS_set_robust_list, 0);
	//#endif
	//#ifdef SYS_get_robust_list
	//		filter_add_blacklist(SYS_get_robust_list, 0);
	//#endif

 // CHECK_SECCOMP(seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(clone), 1,
 //     SCMP_A0(SCMP_CMP_MASKED_EQ, CLONE_NEWUSER, CLONE_NEWUSER)));

// 0.9.39
#ifdef SYS_tuxcall
		filter_add_blacklist(SYS_tuxcall, 0);
#endif
#ifdef SYS_reboot
		filter_add_blacklist(SYS_reboot, 0);
#endif
#ifdef SYS_nfsservctl
		filter_add_blacklist(SYS_nfsservctl, 0);
#endif
#ifdef SYS_get_kernel_syms
		filter_add_blacklist(SYS_get_kernel_syms, 0);
#endif
	}

	// default seccomp filter with additional drop list
	if (cfg.seccomp_list && cfg.seccomp_list_drop == NULL) {
		if (syscall_check_list(cfg.seccomp_list, filter_add_blacklist, 0)) {
			fprintf(stderr, "Error: cannot load seccomp filter\n");
			exit(1);
		}
	}
	// drop list
	else if (cfg.seccomp_list == NULL && cfg.seccomp_list_drop) {
		if (syscall_check_list(cfg.seccomp_list_drop, filter_add_blacklist, 0)) {
			fprintf(stderr, "Error: cannot load seccomp filter\n");
			exit(1);
		}
	}
	
	
	filter_end_blacklist();
	if (arg_debug)
		filter_debug();

	// save seccomp filter in  /tmp/firejail/mnt/seccomp
	// in order to use it in --join operations
	write_seccomp_file();


	struct sock_fprog prog = {
		.len = sfilter_index,
		.filter = sfilter,
	};

	if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
		if (enforce_seccomp) {
			fprintf(stderr, "Error: a seccomp-enabled Linux kernel is required, exiting...\n");
			exit(1);
		}
		else
			fprintf(stderr, "Warning: seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n");

		return 1;
	}
	
	return 0;
}

// keep filter for seccomp option
int seccomp_filter_keep(void) {
	filter_init();

	// these 4 syscalls are used by firejail after the seccomp filter is initialized
	filter_add_whitelist(SYS_setuid, 0);
	filter_add_whitelist(SYS_setgid, 0);
	filter_add_whitelist(SYS_setgroups, 0);
	filter_add_whitelist(SYS_dup, 0);
	
	// apply keep list
	if (cfg.seccomp_list_keep) {
		if (syscall_check_list(cfg.seccomp_list_keep, filter_add_whitelist, 0)) {
			fprintf(stderr, "Error: cannot load seccomp filter\n");
			exit(1);
		}
	}
	
	filter_end_whitelist();
	if (arg_debug)
		filter_debug();

	// save seccomp filter in  /tmp/firejail/mnt/seccomp
	// in order to use it in --join operations
	write_seccomp_file();


	struct sock_fprog prog = {
		.len = sfilter_index,
		.filter = sfilter,
	};

	if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {
		fprintf(stderr, "Warning: seccomp disabled, it requires a Linux kernel version 3.5 or newer.\n");
		return 1;
	}
	else if (arg_debug) {
		printf("seccomp enabled\n");
	}
	
	return 0;
}
Example #5
0
void seccomp_secondary_64(const char *fname) {
	// hardcoded syscall values
	struct sock_filter filter[] = {
		VALIDATE_ARCHITECTURE_64,
		EXAMINE_SYSCALL,
		BLACKLIST(165), // mount
		BLACKLIST(166), // umount2
// todo: implement --allow-debuggers		
		BLACKLIST(101), // ptrace
		BLACKLIST(246), // kexec_load
		BLACKLIST(304), // open_by_handle_at
		BLACKLIST(303), // name_to_handle_at
		BLACKLIST(174), // create_module
		BLACKLIST(175), // init_module
		BLACKLIST(313), // finit_module
		BLACKLIST(176), // delete_module
		BLACKLIST(172), // iopl
		BLACKLIST(173), // ioperm
		BLACKLIST(251), // ioprio_set
		BLACKLIST(167), // swapon
		BLACKLIST(168), // swapoff
		BLACKLIST(103), // syslog
		BLACKLIST(310), // process_vm_readv
		BLACKLIST(311), // process_vm_writev
		BLACKLIST(139), // sysfs
		BLACKLIST(156), // _sysctl
		BLACKLIST(159), // adjtimex
		BLACKLIST(305), // clock_adjtime
		BLACKLIST(212), // lookup_dcookie
		BLACKLIST(298), // perf_event_open
		BLACKLIST(300), // fanotify_init
		BLACKLIST(312), // kcmp
		BLACKLIST(248), // add_key
		BLACKLIST(249), // request_key
		BLACKLIST(250), // keyctl
		BLACKLIST(134), // uselib
		BLACKLIST(163), // acct
		BLACKLIST(154), // modify_ldt
		BLACKLIST(155), // pivot_root
		BLACKLIST(206), // io_setup
		BLACKLIST(207), // io_destroy
		BLACKLIST(208), // io_getevents
		BLACKLIST(209), // io_submit
		BLACKLIST(210), // io_cancel
		BLACKLIST(216), // remap_file_pages
		BLACKLIST(237), // mbind
		BLACKLIST(239), // get_mempolicy
		BLACKLIST(238), // set_mempolicy
		BLACKLIST(256), // migrate_pages
		BLACKLIST(279), // move_pages
		BLACKLIST(278), // vmsplice
		BLACKLIST(161), // chroot
		BLACKLIST(184), // tuxcall
		BLACKLIST(169), // reboot
		BLACKLIST(180), // nfsservctl
		BLACKLIST(177), // get_kernel_syms
		
		RETURN_ALLOW
	};

	// save filter to file
	int dst = open(fname, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
	if (dst < 0) {
		fprintf(stderr, "Error fseccomp: cannot open %s file\n", fname);
		exit(1);
	}
	
	int size = (int) sizeof(filter);
	int written = 0;
	while (written < size) {
		int rv = write(dst, (unsigned char *) filter + written, size - written);
		if (rv == -1) {
			fprintf(stderr, "Error fseccomp: cannot write %s file\n", fname);
			exit(1);
		}
		written += rv;
	}
	close(dst);
}