Example #1
0
void fs_build_mnt_dir(void) {
	struct stat s;
	fs_build_firejail_dir();
	
	// create /run/firejail/mnt directory
	if (stat(RUN_MNT_DIR, &s)) {
		if (arg_debug)
			printf("Creating %s directory\n", RUN_MNT_DIR);
		/* coverity[toctou] */
		int rv = mkdir(RUN_MNT_DIR, 0755);
		if (rv == -1)
			errExit("mkdir");
		if (chown(RUN_MNT_DIR, 0, 0) < 0)
			errExit("chown");
		if (chmod(RUN_MNT_DIR, 0755) < 0)
			errExit("chmod");
	}

	// ... and mount tmpfs on top of it
	if (!tmpfs_mounted) {
		// mount tmpfs on top of /run/firejail/mnt
		if (arg_debug)
			printf("Mounting tmpfs on %s directory\n", RUN_MNT_DIR);
		if (mount("tmpfs", RUN_MNT_DIR, "tmpfs", MS_NOSUID | MS_STRICTATIME | MS_REC,  "mode=755,gid=0") < 0)
			errExit("mounting /tmp/firejail/mnt");
		tmpfs_mounted = 1;
	}
}
Example #2
0
static char *create_empty_dir(void) {
	struct stat s;
	fs_build_firejail_dir();
	
	if (stat(RO_DIR, &s)) {
		/* coverity[toctou] */
		int rv = mkdir(RO_DIR, S_IRUSR | S_IXUSR);
		if (rv == -1)
			errExit("mkdir");	
		if (chown(RO_DIR, 0, 0) < 0)
			errExit("chown");
	}
	
	return RO_DIR;
}
Example #3
0
// build /tmp/firejail/overlay directory
void fs_build_overlay_dir(void) {
	struct stat s;
	fs_build_firejail_dir();
	
	// create /tmp/firejail directory
	if (stat(OVERLAY_DIR, &s)) {
		if (arg_debug)
			printf("Creating %s directory\n", MNT_DIR);
		/* coverity[toctou] */
		int rv = mkdir(OVERLAY_DIR, S_IRWXU | S_IRWXG | S_IRWXO);
		if (rv == -1)
			errExit("mkdir");	
		if (chown(OVERLAY_DIR, 0, 0) < 0)
			errExit("chown");
		if (chmod(OVERLAY_DIR, S_IRWXU  | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) < 0)
			errExit("chmod");
	}
}
Example #4
0
static char *create_empty_file(void) {
	struct stat s;
	fs_build_firejail_dir();

	if (stat(RO_FILE, &s)) {
		/* coverity[toctou] */
		FILE *fp = fopen(RO_FILE, "w");
		if (!fp)
			errExit("fopen");
		fclose(fp);
		if (chown(RO_FILE, 0, 0) < 0)
			errExit("chown");
		if (chmod(RO_FILE, S_IRUSR) < 0)
			errExit("chown");
	}
	
	return RO_FILE;
}
Example #5
0
static void disable_file(OPERATION op, const char *filename) {
	assert(filename);
	assert(op <OPERATION_MAX);
	last_disable = UNSUCCESSFUL;
	
	// rebuild /run/firejail directory in case tmpfs was mounted on top of /run
	fs_build_firejail_dir();
	
	// Resolve all symlinks
	char* fname = realpath(filename, NULL);
	if (fname == NULL && errno != EACCES) {
		if (arg_debug)
			printf("Warning (realpath): %s is an invalid file, skipping...\n", filename);
		return;
	}
	if (fname == NULL && errno == EACCES) {
		if (arg_debug)
			printf("Debug: no access to file %s, forcing mount\n", filename);
		// realpath and stat funtions will fail on FUSE filesystems
		// they don't seem to like a uid of 0
		// force mounting
		int rv = mount(RUN_RO_DIR, filename, "none", MS_BIND, "mode=400,gid=0");
		if (rv == 0)
			last_disable = SUCCESSFUL;
		else {
			rv = mount(RUN_RO_FILE, filename, "none", MS_BIND, "mode=400,gid=0");
			if (rv == 0)
				last_disable = SUCCESSFUL;
		}
		if (last_disable == SUCCESSFUL) {
			if (arg_debug)
				printf("Disable %s\n", filename);
			if (op == BLACKLIST_FILE)
				fs_logger2("blacklist", filename);
			else
				fs_logger2("blacklist-nolog", filename);
		}
		else {
			if (arg_debug)
				printf("Warning (blacklisting): %s is an invalid file, skipping...\n", filename);
		}
				
		return;
	}
	
	// if the file is not present, do nothing
	struct stat s;
	if (fname == NULL)
		return;
	if (stat(fname, &s) == -1) {
		if (arg_debug)
			printf("Warning: %s does not exist, skipping...\n", fname);
		free(fname);
		return;
	}

	// modify the file
	if (op == BLACKLIST_FILE || op == BLACKLIST_NOLOG) {
		// some distros put all executables under /usr/bin and make /bin a symbolic link
		if ((strcmp(fname, "/bin") == 0 || strcmp(fname, "/usr/bin") == 0) &&
		      is_link(filename) &&
		      S_ISDIR(s.st_mode))
			fprintf(stderr, "Warning: %s directory link was not blacklisted\n", filename);
			
		else {
			if (arg_debug)
				printf("Disable %s\n", fname);
			else if (arg_debug_blacklists) {
				printf("Disable %s", fname);
				if (op == BLACKLIST_FILE)
					printf("\n");
				else
					printf(" - no logging\n");
			}
			if (S_ISDIR(s.st_mode)) {
				if (mount(RUN_RO_DIR, fname, "none", MS_BIND, "mode=400,gid=0") < 0)
					errExit("disable file");
			}
			else {
				if (mount(RUN_RO_FILE, fname, "none", MS_BIND, "mode=400,gid=0") < 0)
					errExit("disable file");
			}
			last_disable = SUCCESSFUL;
			if (op == BLACKLIST_FILE)
				fs_logger2("blacklist", fname);
			else
				fs_logger2("blacklist-nolog", fname);
		}
	}
	else if (op == MOUNT_READONLY) {
		if (arg_debug)
			printf("Mounting read-only %s\n", fname);
		fs_rdonly(fname);
// todo: last_disable = SUCCESSFUL;
	}
	else if (op == MOUNT_TMPFS) {
		if (S_ISDIR(s.st_mode)) {
			if (arg_debug)
				printf("Mounting tmpfs on %s\n", fname);
			// preserve owner and mode for the directory
			if (mount("tmpfs", fname, "tmpfs", MS_NOSUID | MS_NODEV | MS_STRICTATIME | MS_REC,  0) < 0)
				errExit("mounting tmpfs");
			/* coverity[toctou] */
			if (chown(fname, s.st_uid, s.st_gid) == -1)
				errExit("mounting tmpfs chmod");
			last_disable = SUCCESSFUL;
			fs_logger2("mount tmpfs on", fname);
		}
		else
			printf("Warning: %s is not a directory; cannot mount a tmpfs on top of it.\n", fname);
	}
	else
		assert(0);

	free(fname);
}