예제 #1
0
static void duplicate(char *name) {
	char *fname = check_dir_or_file(name);

	if (arg_debug)
		printf("Private home: duplicating %s\n", fname);
	assert(strncmp(fname, cfg.homedir, strlen(cfg.homedir)) == 0);

	struct stat s;
	if (lstat(fname, &s) == -1) {
		free(fname);
		return;
	}
	else if (S_ISDIR(s.st_mode)) {
		// create the directory in RUN_HOME_DIR
		char *name;
		char *ptr = strrchr(fname, '/');
		ptr++;
		if (asprintf(&name, "%s/%s", RUN_HOME_DIR, ptr) == -1)
			errExit("asprintf");
		mkdir_attr(name, 0755, getuid(), getgid());
		sbox_run(SBOX_USER| SBOX_CAPS_NONE | SBOX_SECCOMP, 3, PATH_FCOPY, fname, name);
		free(name);
	}
	else
		sbox_run(SBOX_USER| SBOX_CAPS_NONE | SBOX_SECCOMP, 3, PATH_FCOPY, fname, RUN_HOME_DIR);
	fs_logger2("clone", fname);
	fs_logger_print();	// save the current log

	free(fname);
}
예제 #2
0
void netfilter(const char *fname) {
    // find iptables command
    struct stat s;
    char *iptables = NULL;
    char *iptables_restore = NULL;
    if (stat("/sbin/iptables", &s) == 0) {
        iptables = "/sbin/iptables";
        iptables_restore = "/sbin/iptables-restore";
    }
    else if (stat("/usr/sbin/iptables", &s) == 0) {
        iptables = "/usr/sbin/iptables";
        iptables_restore = "/usr/sbin/iptables-restore";
    }
    if (iptables == NULL || iptables_restore == NULL) {
        fprintf(stderr, "Error: iptables command not found, netfilter not configured\n");
        return;
    }

    // read filter
    char *filter = client_filter;
    int allocated = 0;
    if (netfilter_default)
        fname = netfilter_default;
    if (fname) {
        filter = read_text_file_or_exit(fname);
        allocated = 1;
    }

    // create the filter file
    FILE *fp = fopen(SBOX_STDIN_FILE, "w");
    if (!fp) {
        fprintf(stderr, "Error: cannot open %s\n", SBOX_STDIN_FILE);
        exit(1);
    }
    fprintf(fp, "%s\n", filter);
    fclose(fp);


    // push filter
    if (arg_debug)
        printf("Installing network filter:\n%s\n", filter);

    // first run of iptables on this platform installs a number of kernel modules such as ip_tables, x_tables, iptable_filter
    // we run this command with caps and seccomp disabled in order to allow the loading of these modules
    sbox_run(SBOX_ROOT /* | SBOX_CAPS_NETWORK | SBOX_SECCOMP*/ | SBOX_STDIN_FROM_FILE, 1, iptables_restore);
    unlink(SBOX_STDIN_FILE);

    // debug
    if (arg_debug)
        sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 2, iptables, "-vL");

    if (allocated)
        free(filter);
    return;
}
예제 #3
0
void net_configure_veth_pair(Bridge *br, const char *ifname, pid_t child) {
	assert(br);
	if (br->configured == 0)
		return;

	// create a veth pair
	char *dev;
	if (br->veth_name == NULL) {
		if (asprintf(&dev, "veth%u%s", getpid(), ifname) < 0)
			errExit("asprintf");
	}
	else
		dev = br->veth_name;
		
	char *cstr;
	if (asprintf(&cstr, "%d", child) == -1)
		errExit("asprintf");
	sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 7, PATH_FNET, "create", "veth", dev, ifname, br->dev, cstr);
	free(cstr);

	char *msg;
	if (asprintf(&msg, "%d.%d.%d.%d address assigned to sandbox", PRINT_IP(br->ipsandbox)) == -1)
		errExit("asprintf");
	logmsg(msg);
	fflush(0);
	free(msg);
}
예제 #4
0
void network_main(pid_t child) {
	char *cstr;
	if (asprintf(&cstr, "%d", child) == -1)
		errExit("asprintf");

	// create veth pair or macvlan device
	if (cfg.bridge0.configured) {
		if (cfg.bridge0.macvlan == 0) {
			net_configure_veth_pair(&cfg.bridge0, "eth0", child);
		}
		else
			sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 6, PATH_FNET, "create", "macvlan", cfg.bridge0.devsandbox, cfg.bridge0.dev, cstr);
	}
	
	if (cfg.bridge1.configured) {
		if (cfg.bridge1.macvlan == 0)
			net_configure_veth_pair(&cfg.bridge1, "eth1", child);
		else
			sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 6, PATH_FNET, "create", "macvlan", cfg.bridge1.devsandbox, cfg.bridge1.dev, cstr);
	}
	
	if (cfg.bridge2.configured) {
		if (cfg.bridge2.macvlan == 0)
			net_configure_veth_pair(&cfg.bridge2, "eth2", child);
		else
			sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 6, PATH_FNET, "create", "macvlan", cfg.bridge2.devsandbox, cfg.bridge2.dev, cstr);
	}
	
	if (cfg.bridge3.configured) {
		if (cfg.bridge3.macvlan == 0)
			net_configure_veth_pair(&cfg.bridge3, "eth3", child);
		else
			sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 6, PATH_FNET, "create", "macvlan", cfg.bridge3.devsandbox, cfg.bridge3.dev, cstr);
	}

	// move interfaces in sandbox
	if (cfg.interface0.configured) {
		sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 4, PATH_FNET, "moveif", cfg.interface0.dev, cstr);
	}
	if (cfg.interface1.configured) {
		sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 4, PATH_FNET, "moveif", cfg.interface1.dev, cstr);
	}
	if (cfg.interface2.configured) {
		sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 4, PATH_FNET, "moveif", cfg.interface3.dev, cstr);
	}
	if (cfg.interface3.configured) {
		sbox_run(SBOX_ROOT | SBOX_CAPS_NETWORK | SBOX_SECCOMP, 4, PATH_FNET, "moveif", cfg.interface3.dev, cstr);
	}

	free(cstr);
}
예제 #5
0
파일: seccomp.c 프로젝트: maces/firejail
// keep filter for seccomp option
int seccomp_filter_keep(void) {
	if (arg_debug)
		printf("Build drop seccomp filter\n");
	
	// build the seccomp filter as a regular user
	sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 4,
		PATH_FSECCOMP, "keep", RUN_SECCOMP_CFG, cfg.seccomp_list_keep);
	if (arg_debug)
		printf("seccomp filter configured\n");

		
	return seccomp_load(RUN_SECCOMP_CFG);
}
예제 #6
0
파일: seccomp.c 프로젝트: maces/firejail
void seccomp_print_filter(pid_t pid) {
	EUID_ASSERT();

	// if the pid is that of a firejail  process, use the pid of the first child process
	EUID_ROOT();
	char *comm = pid_proc_comm(pid);
	EUID_USER();
	if (comm) {
		if (strcmp(comm, "firejail") == 0) {
			pid_t child;
			if (find_child(pid, &child) == 0) {
				pid = child;
			}
		}
		free(comm);
	}

	// check privileges for non-root users
	uid_t uid = getuid();
	if (uid != 0) {
		uid_t sandbox_uid = pid_get_uid(pid);
		if (uid != sandbox_uid) {
			fprintf(stderr, "Error: permission denied.\n");
			exit(1);
		}
	}

	// find the seccomp filter
	EUID_ROOT();
	char *fname;
	if (asprintf(&fname, "/proc/%d/root%s", pid, RUN_SECCOMP_CFG) == -1)
		errExit("asprintf");

	struct stat s;
	if (stat(fname, &s) == -1) {
		printf("Cannot access seccomp filter.\n");
		exit(1);
	}

	// read and print the filter - run this as root, the user doesn't have access
	sbox_run(SBOX_ROOT | SBOX_SECCOMP, 3, PATH_FSECCOMP, "print", fname);
	free(fname);

	exit(0);
}
예제 #7
0
파일: seccomp.c 프로젝트: maces/firejail
// drop filter for seccomp option
int seccomp_filter_drop(int enforce_seccomp) {
	// default seccomp
	if (cfg.seccomp_list_drop == NULL && cfg.seccomp_list == NULL) {
#if defined(__x86_64__)
		seccomp_filter_32();
#endif
#if defined(__i386__)
		seccomp_filter_64();
#endif
	}
	// default seccomp filter with additional drop list
	else if (cfg.seccomp_list && cfg.seccomp_list_drop == NULL) {
#if defined(__x86_64__)
		seccomp_filter_32();
#endif
#if defined(__i386__)
		seccomp_filter_64();
#endif
		if (arg_debug)
			printf("Build default+drop seccomp filter\n");
		
		// build the seccomp filter as a regular user
		int rv;
		if (arg_allow_debuggers)
			rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 6,
				PATH_FSECCOMP, "default", "drop", RUN_SECCOMP_CFG, cfg.seccomp_list, "allow-debuggers");
		else
			rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 5,
				PATH_FSECCOMP, "default", "drop", RUN_SECCOMP_CFG, cfg.seccomp_list);
		if (rv)
			exit(rv);
	}
	
	// drop list without defaults - secondary filters are not installed
	else if (cfg.seccomp_list == NULL && cfg.seccomp_list_drop) {
		if (arg_debug)
			printf("Build drop seccomp filter\n");

		// build the seccomp filter as a regular user
		int rv;
		if (arg_allow_debuggers)
			rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 5,
				PATH_FSECCOMP, "drop", RUN_SECCOMP_CFG, cfg.seccomp_list_drop,  "allow-debuggers");
		else
			rv = sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 4,
				PATH_FSECCOMP, "drop", RUN_SECCOMP_CFG, cfg.seccomp_list_drop);

		if (rv)
			exit(rv);
	}
	else {
		assert(0);
	}
	
	// load the filter
	if (seccomp_load(RUN_SECCOMP_CFG) == 0) {
		if (arg_debug)
			printf("seccomp filter configured\n");
	}
	else if (enforce_seccomp) {
		fprintf(stderr, "Error: a seccomp-enabled Linux kernel is required, exiting...\n");
		exit(1);
	}
	
	if (arg_debug && access(PATH_FSECCOMP, X_OK) == 0)
		sbox_run(SBOX_USER | SBOX_CAPS_NONE | SBOX_SECCOMP, 3,
			PATH_FSECCOMP, "print", RUN_SECCOMP_CFG);

	return seccomp_load(RUN_SECCOMP_CFG);
}