Exemplo n.º 1
0
// disable firejail configuration in /etc/firejail and in ~/.config/firejail
static void disable_firejail_config(void) {
	struct stat s;
	if (stat("/etc/firejail", &s) == 0)
		disable_file(BLACKLIST_FILE, "/etc/firejail");

	char *fname;
	if (asprintf(&fname, "%s/.config/firejail", cfg.homedir) == -1)
		errExit("asprintf");
	if (stat(fname, &s) == 0)
		disable_file(BLACKLIST_FILE, fname);
	
	if (stat("/usr/local/etc/firejail", &s) == 0)
		disable_file(BLACKLIST_FILE, "/usr/local/etc/firejail");

	if (strcmp(PREFIX, "/usr/local")) {
		if (asprintf(&fname, "%s/etc/firejail", PREFIX) == -1)
			errExit("asprintf");
		if (stat(fname, &s) == 0)
			disable_file(BLACKLIST_FILE, fname);
	}

	
	
	free(fname);
}
Exemplo n.º 2
0
// disable pulseaudio socket
void pulseaudio_disable(void) {
	// blacklist user config directory
	disable_file(cfg.homedir, ".config/pulse");

	// blacklist any pulse* file in /tmp directory
	DIR *dir;
	if (!(dir = opendir("/tmp"))) {
		// sleep 2 seconds and try again
		sleep(2);
		if (!(dir = opendir("/tmp"))) {
			fprintf(stderr, "Warning: cannot open /tmp directory. PulseAudio sockets are not disabled\n");
			return;
		}
	}

	struct dirent *entry;
	while ((entry = readdir(dir))) {
		if (strncmp(entry->d_name, "pulse-", 6) == 0) {
			disable_file("/tmp", entry->d_name);
		}
	}

	closedir(dir);

	// blacklist XDG_RUNTIME_DIR
	char *name = getenv("XDG_RUNTIME_DIR");
	if (name)
		disable_file(name, "pulse/native");
}
Exemplo n.º 3
0
Arquivo: fs.c Projeto: pyther/firejail
// disable firejail configuration in /etc/firejail and in ~/.config/firejail
static void disable_firejail_config(void) {
	struct stat s;
	if (stat("/etc/firejail", &s) == 0)
		disable_file(BLACKLIST_FILE, "/etc/firejail");

	char *fname;
	if (asprintf(&fname, "%s/.config/firejail", cfg.homedir) == -1)
		errExit("asprintf");
	if (stat(fname, &s) == 0)
		disable_file(BLACKLIST_FILE, fname);
	
	if (stat("/usr/local/etc/firejail", &s) == 0)
		disable_file(BLACKLIST_FILE, "/usr/local/etc/firejail");

	if (strcmp(PREFIX, "/usr/local")) {
		if (asprintf(&fname, "%s/etc/firejail", PREFIX) == -1)
			errExit("asprintf");
		if (stat(fname, &s) == 0)
			disable_file(BLACKLIST_FILE, fname);
	}
	
	free(fname);
	
	// disable run time information
	if (stat(RUN_FIREJAIL_NETWORK_DIR, &s) == 0)
		disable_file(BLACKLIST_FILE, RUN_FIREJAIL_NETWORK_DIR);
	if (stat(RUN_FIREJAIL_BANDWIDTH_DIR, &s) == 0)
		disable_file(BLACKLIST_FILE, RUN_FIREJAIL_BANDWIDTH_DIR);
	if (stat(RUN_FIREJAIL_NAME_DIR, &s) == 0)
		disable_file(BLACKLIST_FILE, RUN_FIREJAIL_NAME_DIR);
	if (stat(RUN_FIREJAIL_X11_DIR, &s) == 0)
		disable_file(BLACKLIST_FILE, RUN_FIREJAIL_X11_DIR);
}
Exemplo n.º 4
0
static void globbing(OPERATION op, const char *fname, const char *emptydir, const char *emptyfile) {
	assert(fname);
	assert(emptydir);
	assert(emptyfile);

	// filename globbing: expand * macro and continue processing for every single file
	if (strchr(fname, '*')) {
		glob_t globbuf;
		globbuf.gl_offs = 0;
		glob(fname, GLOB_DOOFFS, NULL, &globbuf);
		int i;
		for (i = 0; i < globbuf.gl_pathc; i++) {
			assert(globbuf.gl_pathv[i]);
			disable_file(op, globbuf.gl_pathv[i], emptydir, emptyfile);
		}
	}
	else
		disable_file(op, fname, emptydir, emptyfile);
}
Exemplo n.º 5
0
// Treat pattern as a shell glob pattern and blacklist matching files
static void globbing(OPERATION op, const char *pattern, const char *noblacklist[], size_t noblacklist_len) {
	assert(pattern);

	glob_t globbuf;
	// Profiles contain blacklists for files that might not exist on a user's machine.
	// GLOB_NOCHECK makes that okay.
	int globerr = glob(pattern, GLOB_NOCHECK | GLOB_NOSORT, NULL, &globbuf);
	if (globerr) {
		fprintf(stderr, "Error: failed to glob pattern %s\n", pattern);
		exit(1);
	}

	size_t i, j;
	for (i = 0; i < globbuf.gl_pathc; i++) {
		char *path = globbuf.gl_pathv[i];
		assert(path);
		// /home/me/.* can glob to /home/me/.. which would blacklist /home/
		const char *base = gnu_basename(path);
		if (strcmp(base, ".") == 0 || strcmp(base, "..") == 0)
			continue;
		// noblacklist is expected to be short in normal cases, so stupid and correct brute force is okay
		bool okay_to_blacklist = true;
		for (j = 0; j < noblacklist_len; j++) {
			int result = fnmatch(noblacklist[j], path, FNM_PATHNAME);
			if (result == FNM_NOMATCH)
				continue;
			else if (result == 0) {
				okay_to_blacklist = false;
				break;
			}
			else {
				fprintf(stderr, "Error: failed to compare path %s with pattern %s\n", path, noblacklist[j]);
				exit(1);
			}
		}
		if (okay_to_blacklist)
			disable_file(op, path);
		else if (arg_debug)
			printf("Not blacklist %s\n", path);
	}
	globfree(&globbuf);
}
Exemplo n.º 6
0
static void sanitize_home(void) {
	// extract current /home directory data
	struct dirent *dir;
	DIR *d = opendir("/home");
	if (d == NULL)
		return;

	char *emptydir = create_empty_dir();
	while ((dir = readdir(d))) {
		if(strcmp(dir->d_name, "." ) == 0 || strcmp(dir->d_name, ".." ) == 0)
			continue;

		if (dir->d_type == DT_DIR ) {
			// get properties
			struct stat s;
			char *name;
			if (asprintf(&name, "/home/%s", dir->d_name) == -1)
				continue;
			if (stat(name, &s) == -1)
				continue;
			if (S_ISLNK(s.st_mode)) {
				free(name);
				continue;
			}
			
			if (strcmp(name, cfg.homedir) == 0)
				continue;

//			printf("directory %u %u:%u #%s#\n",
//				s.st_mode,
//				s.st_uid,
//				s.st_gid,
//				name);
			
			// disable directory
			disable_file(BLACKLIST_FILE, name, emptydir, "not used");
			free(name);
		}			
	}
	closedir(d);
}
Exemplo n.º 7
0
// mount /proc and /sys directories
void fs_proc_sys_dev_boot(void) {
	struct stat s;

	if (arg_debug)
		printf("Remounting /proc and /proc/sys filesystems\n");
	if (mount("proc", "/proc", "proc", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_REC, NULL) < 0)
		errExit("mounting /proc");
	fs_logger("remount /proc");

	// remount /proc/sys readonly
	if (mount("/proc/sys", "/proc/sys", NULL, MS_BIND | MS_REC, NULL) < 0)
		errExit("mounting /proc/sys");

	if (mount(NULL, "/proc/sys", NULL, MS_BIND | MS_REMOUNT | MS_RDONLY | MS_REC, NULL) < 0)
		errExit("mounting /proc/sys");
	fs_logger("read-only /proc/sys");


	/* Mount a version of /sys that describes the network namespace */
	if (arg_debug)
		printf("Remounting /sys directory\n");
	if (umount2("/sys", MNT_DETACH) < 0)
		fprintf(stderr, "Warning: failed to unmount /sys\n");
	else {
		if (mount("sysfs", "/sys", "sysfs", MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REC, NULL) < 0)
			fprintf(stderr, "Warning: failed to mount /sys\n");
		else
			fs_logger("remount /sys");
	}
		
	if (stat("/sys/firmware", &s) == 0) {
		disable_file(BLACKLIST_FILE, "/sys/firmware");
	}
		
	if (stat("/sys/hypervisor", &s) == 0) {
		disable_file(BLACKLIST_FILE, "/sys/hypervisor");
	}

	if (stat("/sys/fs", &s) == 0) {
		disable_file(BLACKLIST_FILE, "/sys/fs");
	}

	if (stat("/sys/module", &s) == 0) {
		disable_file(BLACKLIST_FILE, "/sys/module");
	}

	if (stat("/sys/power", &s) == 0) {
		disable_file(BLACKLIST_FILE, "/sys/power");
	}

//	if (mount("sysfs", "/sys", "sysfs", MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REC, NULL) < 0)
//		errExit("mounting /sys");

	// Disable SysRq
	// a linux box can be shut down easily using the following commands (as root):
	// # echo 1 > /proc/sys/kernel/sysrq
	// #echo b > /proc/sysrq-trigger
	// for more information see https://www.kernel.org/doc/Documentation/sysrq.txt
	if (arg_debug)
		printf("Disable /proc/sysrq-trigger\n");
	fs_rdonly_noexit("/proc/sysrq-trigger");
	
	// disable hotplug and uevent_helper
	if (arg_debug)
		printf("Disable /proc/sys/kernel/hotplug\n");
	fs_rdonly_noexit("/proc/sys/kernel/hotplug");
	if (arg_debug)
		printf("Disable /sys/kernel/uevent_helper\n");
	fs_rdonly_noexit("/sys/kernel/uevent_helper");
	
	// read-only /proc/irq and /proc/bus
	if (arg_debug)
		printf("Disable /proc/irq\n");
	fs_rdonly_noexit("/proc/irq");
	if (arg_debug)
		printf("Disable /proc/bus\n");
	fs_rdonly_noexit("/proc/bus");
	
	// disable /proc/kcore
	disable_file(BLACKLIST_FILE, "/proc/kcore");

	// disable /proc/kallsyms
	disable_file(BLACKLIST_FILE, "/proc/kallsyms");
	
	// disable /boot
	if (stat("/boot", &s) == 0) {
		if (arg_debug)
			printf("Disable /boot directory\n");
		disable_file(BLACKLIST_FILE, "/boot");
	}
	
	// disable /selinux
	if (stat("/selinux", &s) == 0) {
		if (arg_debug)
			printf("Disable /selinux directory\n");
		disable_file(BLACKLIST_FILE, "/selinux");
	}
	
	// disable /dev/port
	if (stat("/dev/port", &s) == 0) {
		disable_file(BLACKLIST_FILE, "/dev/port");
	}
	
	if (getuid() != 0) {
		// disable /dev/kmsg
		if (stat("/dev/kmsg", &s) == 0) {
			disable_file(BLACKLIST_FILE, "/dev/kmsg");
		}
		
		// disable /proc/kmsg
		if (stat("/proc/kmsg", &s) == 0) {
			disable_file(BLACKLIST_FILE, "/proc/kmsg");
		}
	}
}
Exemplo n.º 8
0
// mount /proc and /sys directories
void fs_proc_sys_dev_boot(void) {
	struct stat s;

	if (arg_debug)
		printf("Remounting /proc and /proc/sys filesystems\n");
	if (mount("proc", "/proc", "proc", MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_REC, NULL) < 0)
		errExit("mounting /proc");

	// remount /proc/sys readonly
	if (mount("/proc/sys", "/proc/sys", NULL, MS_BIND | MS_REC, NULL) < 0)
		errExit("mounting /proc/sys");

	if (mount(NULL, "/proc/sys", NULL, MS_BIND | MS_REMOUNT | MS_RDONLY | MS_REC, NULL) < 0)
		errExit("mounting /proc/sys");


	/* Mount a version of /sys that describes the network namespace */
	if (arg_debug)
		printf("Remounting /sys directory\n");
	if (umount2("/sys", MNT_DETACH) < 0) 
		fprintf(stderr, "Warning: failed to unmount /sys\n");
	if (mount("sysfs", "/sys", "sysfs", MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REC, NULL) < 0)
		fprintf(stderr, "Warning: failed to mount /sys\n");

//	if (mount("sysfs", "/sys", "sysfs", MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REC, NULL) < 0)
//		errExit("mounting /sys");


	// mounting firejail kernel module files
	if (stat("/proc/firejail-uptime", &s) == 0) {
		errno = 0;
		FILE *fp = fopen("/proc/firejail", "w");
		int cnt = 0;
		while (errno == EBUSY && cnt < 10) {
			if (!fp) {
				int s = random();
				s /= 200000;
				usleep(s);
				fp = fopen("/proc/firejail", "w");
			}
			else
				break;
		}
		if (!fp) {
			fprintf(stderr, "Error: cannot register sandbox with firejail-lkm\n");
			exit(1);
		}	
		if (fp) {
			// registration
			fprintf(fp, "register\n");
			fflush(0);
			// filtering x11 connect calls
			if (arg_nox11) {
				fprintf(fp, "no connect unix /tmp/.X11\n");
				fflush(0);
				printf("X11 access disabled\n");
			}
			if (arg_nodbus) {
				fprintf(fp, "no connect unix /var/run/dbus/system_bus_socket\n");
				fflush(0);
				fprintf(fp, "no connect unix /tmp/dbus\n");
				fflush(0);
				printf("D-Bus access disabled\n");
			}
			fclose(fp);
			if (mount("/proc/firejail-uptime", "/proc/uptime", NULL, MS_BIND|MS_REC, NULL) < 0)
				fprintf(stderr, "Warning: cannot mount /proc/firejail-uptime\n");
		}
	}

	// Disable SysRq
	// a linux box can be shut down easily using the following commands (as root):
	// # echo 1 > /proc/sys/kernel/sysrq
	// #echo b > /proc/sysrq-trigger
	// for more information see https://www.kernel.org/doc/Documentation/sysrq.txt
	if (arg_debug)
		printf("Disable /proc/sysrq-trigger\n");
	fs_rdonly_noexit("/proc/sysrq-trigger");
	
	// disable hotplug and uevent_helper
	if (arg_debug)
		printf("Disable /proc/sys/kernel/hotplug\n");
	fs_rdonly_noexit("/proc/sys/kernel/hotplug");
	if (arg_debug)
		printf("Disable /sys/kernel/uevent_helper\n");
	fs_rdonly_noexit("/sys/kernel/uevent_helper");
	
	// read-only /proc/irq and /proc/bus
	if (arg_debug)
		printf("Disable /proc/irq\n");
	fs_rdonly_noexit("/proc/irq");
	if (arg_debug)
		printf("Disable /proc/bus\n");
	fs_rdonly_noexit("/proc/bus");
	
	// disable /proc/kcore
	disable_file(BLACKLIST_FILE, "/proc/kcore", "not used", "/dev/null");

	// disable /proc/kallsyms
	disable_file(BLACKLIST_FILE, "/proc/kallsyms", "not used", "/dev/null");
	
	// disable /boot
	if (stat("/boot", &s) == 0) {
		if (arg_debug)
			printf("Mounting a new /boot directory\n");
		if (mount("tmpfs", "/boot", "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC,  "mode=777,gid=0") < 0)
			errExit("mounting /boot directory");
	}
	
	// disable /dev/port
	if (stat("/dev/port", &s) == 0) {
		disable_file(BLACKLIST_FILE, "/dev/port", "not used", "/dev/null");
	}
}