Пример #1
0
void prepare_system(const struct config *config)
{
	if (config->verbose)
		printf("set cpu affinity to cpu #%u\n", config->cpu);

	set_cpu_affinity(config->cpu);

	switch (config->prio) {
	case SCHED_HIGH:
		if (config->verbose)
			printf("high priority condition requested\n");

		set_process_priority(PRIORITY_HIGH);
		break;
	case SCHED_LOW:
		if (config->verbose)
			printf("low priority condition requested\n");

		set_process_priority(PRIORITY_LOW);
		break;
	default:
		if (config->verbose)
			printf("default priority condition requested\n");

		set_process_priority(PRIORITY_DEFAULT);
	}
}
Пример #2
0
int main(int ac, char** av)
{
  static const double lhs_data[] =
    { 0, 1, 1.f/3.f, -1 };

  static const double rhs_data[] =
    { 1, -1, 2.f/3.f, -2 };

  gsl_matrix* lhs_matrix = create_matrix_with_data((const double*)lhs_data, 2, 2);
  gsl_matrix* rhs_matrix = create_matrix_with_data((const double*)rhs_data, 2, 2);
  gsl_matrix* res_matrix = gsl_matrix_alloc(2, 2);

#if CONFIG_USE_AFFINITY
  set_cpu_affinity(1);
#endif

  mult_switch(0, res_matrix, lhs_matrix, rhs_matrix);
  mult_switch(1, res_matrix, lhs_matrix, rhs_matrix);
  mult_switch(2, res_matrix, lhs_matrix, rhs_matrix);

  gsl_matrix_free(lhs_matrix);
  gsl_matrix_free(rhs_matrix);
  gsl_matrix_free(res_matrix);

  return 0;
}
Пример #3
0
int main(int argc, char *argv[])
{
	unsigned long new_mask;
	pid_t pid;

	if (argc != 3) {
		fprintf(stderr, "usage: %s [pid] [cpu_mask]\n", argv[0]);
		return -1;
	}

	pid = atol(argv[1]);
    new_mask = atol(argv[2]);

	return set_cpu_affinity(pid, new_mask);
}
Пример #4
0
/* Loop for child child_num: Read a batch of primes from primes_pipe, call
   fun(p) for each prime p, then report the batch complete. Quit when a
   zero is received.
 */
static void child_thread(void (*fun)(uint64_t))
{
  int i, status;

  close(primes_pipe[1]);
  close(factors_pipe[0]);

  /* Set thread affinity.
   */
  if (child_num < affinity_opt)
    set_cpu_affinity(child_affinity[child_num]);

  /* Request initial parcel of primes.
   */
  factor_msg.i = MSG_COMPLETE;
  factor_msg.cw = child_num;
  factor_msg.p = 0;
  if ((status = write_factors_pipe()) != 0)
  {
    /* Main loop.
     */
    while ((status = read_primes_pipe()) != 0)
    {
      for (i = 0; i < PRIMES_PARCELSIZE && primes_parcel[i] > 0; i++)
        fun(primes_parcel[i]);

      if (i == 0) /* Empty parcel, quit. */
        break;

      factor_msg.i = MSG_COMPLETE;
      factor_msg.cw = child_num;
      factor_msg.p = primes_parcel[i-1];
      if ((status = write_factors_pipe()) == 0)
        break;
    }
  }

  close(primes_pipe[0]);
  close(factors_pipe[1]);

  _exit(status ? EXIT_SUCCESS : EXIT_FAILURE);
}
Пример #5
0
int CmiSetCPUAffinity(int mycore)
{
  int core = mycore;
  if (core < 0) {
    core = CmiNumCores() + core;
  }
  if (core < 0) {
    CmiError("Error: Invalid cpu affinity core number: %d\n", mycore);
    CmiAbort("CmiSetCPUAffinity failed");
  }

  CpvAccess(myCPUAffToCore) = core;

  /* set cpu affinity */
#if CMK_SMP
  return set_thread_affinity(core);
#else
  return set_cpu_affinity(core);
  /* print_cpu_affinity(); */
#endif
}
Пример #6
0
void join(pid_t pid, int argc, char **argv, int index) {
	EUID_ASSERT();
	char *homedir = cfg.homedir;
	
	extract_command(argc, argv, index);
	signal (SIGTERM, signal_handler);

	// 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;
				printf("Switching to pid %u, the first child process inside the sandbox\n", (unsigned) pid);
			}
		}
		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 is denied to join a sandbox created by a different user.\n");
			exit(1);
		}
	}

	EUID_ROOT();
	// in user mode set caps seccomp, cpu, cgroup, etc
	if (getuid() != 0) {
		extract_caps_seccomp(pid);
		extract_cpu(pid);
		extract_cgroup(pid);
		extract_nogroups(pid);
		extract_user_namespace(pid);
	}
	
	// set cgroup
	if (cfg.cgroup)	// not available for uid 0
		set_cgroup(cfg.cgroup);
		
	// join namespaces
	if (arg_join_network) {
		if (join_namespace(pid, "net"))
			exit(1);
	}
	else if (arg_join_filesystem) {
		if (join_namespace(pid, "mnt"))
			exit(1);
	}
	else {
		if (join_namespace(pid, "ipc") ||
		    join_namespace(pid, "net") ||
		    join_namespace(pid, "pid") ||
		    join_namespace(pid, "uts") ||
		    join_namespace(pid, "mnt"))
			exit(1);
	}

	pid_t child = fork();
	if (child < 0)
		errExit("fork");
	if (child == 0) {
		// chroot into /proc/PID/root directory
		char *rootdir;
		if (asprintf(&rootdir, "/proc/%d/root", pid) == -1)
			errExit("asprintf");
			
		int rv;
		if (!arg_join_network) {
			rv = chroot(rootdir); // this will fail for processes in sandboxes not started with --chroot option
			if (rv == 0)
				printf("changing root to %s\n", rootdir);
		}
		
		prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // kill the child in case the parent died
		if (chdir("/") < 0)
			errExit("chdir");
		if (homedir) {
			struct stat s;
			if (stat(homedir, &s) == 0) {
				/* coverity[toctou] */
				if (chdir(homedir) < 0)
					errExit("chdir");
			}
		}
		
		// set cpu affinity
		if (cfg.cpus)	// not available for uid 0
			set_cpu_affinity();
					
		// set caps filter
		if (apply_caps == 1)	// not available for uid 0
			caps_set(caps);
#ifdef HAVE_SECCOMP
		// read cfg.protocol from file
		if (getuid() != 0)
			protocol_filter_load(RUN_PROTOCOL_CFG);
		if (cfg.protocol) {	// not available for uid 0
			seccomp_load(RUN_SECCOMP_PROTOCOL);	// install filter	
		}
				
		// set seccomp filter
		if (apply_seccomp == 1)	// not available for uid 0
			seccomp_load(RUN_SECCOMP_CFG);
#endif

		// mount user namespace or drop privileges
		if (arg_noroot) {	// not available for uid 0
			if (arg_debug)
				printf("Joining user namespace\n");
			if (join_namespace(1, "user"))
				exit(1);

			// user namespace resets capabilities
			// set caps filter
			if (apply_caps == 1)	// not available for uid 0
				caps_set(caps);
		}
		else 
			drop_privs(arg_nogroups);	// nogroups not available for uid 0


		// set nice
		if (arg_nice) {
			errno = 0;
			int rv = nice(cfg.nice);
			(void) rv;
			if (errno) {
				fprintf(stderr, "Warning: cannot set nice value\n");
				errno = 0;
			}
		}

		env_defaults();
		if (cfg.command_line == NULL) {
			assert(cfg.shell);
			cfg.command_line = cfg.shell;
			cfg.window_title = cfg.shell;
		}

		int cwd = 0;
		if (cfg.cwd) {
			if (chdir(cfg.cwd) == 0)
				cwd = 1;
		}

		if (!cwd) {
			if (chdir("/") < 0)
				errExit("chdir");
			if (cfg.homedir) {
				struct stat s;
				if (stat(cfg.homedir, &s) == 0) {
					/* coverity[toctou] */
					if (chdir(cfg.homedir) < 0)
						errExit("chdir");
				}
			}
		}

		start_application();

		// it will never get here!!!
	}

	// wait for the child to finish
	waitpid(child, NULL, 0);
	flush_stdin();
	exit(0);
}
Пример #7
0
int sandbox(void* sandbox_arg) {
	// Get rid of unused parameter warning
	(void)sandbox_arg;

	pid_t child_pid = getpid();
	if (arg_debug)
		printf("Initializing child process\n");	

 	// close each end of the unused pipes
 	close(parent_to_child_fds[1]);
 	close(child_to_parent_fds[0]);
 
 	// wait for parent to do base setup
 	wait_for_other(parent_to_child_fds[0]);

	if (arg_debug && child_pid == 1)
		printf("PID namespace installed\n");

	//****************************
	// set hostname
	//****************************
	if (cfg.hostname) {
		if (sethostname(cfg.hostname, strlen(cfg.hostname)) < 0)
			errExit("sethostname");
	}

	//****************************
	// mount namespace
	//****************************
	// mount events are not forwarded between the host the sandbox
	if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0) {
		chk_chroot();
	}
	
	//****************************
	// netfilter
	//****************************
	if (arg_netfilter && any_bridge_configured()) { // assuming by default the client filter
		netfilter(arg_netfilter_file);
	}

	//****************************
	// trace pre-install
	//****************************
	if (arg_trace)
		fs_trace_preload();

	//****************************
	// configure filesystem
	//****************************
	
#ifdef HAVE_CHROOT		
	if (cfg.chrootdir) {
		fs_chroot(cfg.chrootdir);
		// force caps and seccomp if not started as root
		if (getuid() != 0) {
			// force default seccomp inside the chroot, no keep or drop list
			// the list build on top of the default drop list is kept intact
			arg_seccomp = 1;
			if (arg_seccomp_list_drop) {
				free(arg_seccomp_list_drop);
				arg_seccomp_list_drop = NULL;
			}
			if (arg_seccomp_list_keep) {
				free(arg_seccomp_list_keep);
				arg_seccomp_list_keep = NULL;
			}
			
			// disable all capabilities
			if (arg_caps_default_filter || arg_caps_list)
				fprintf(stderr, "Warning: all capabilities disabled for a regular user during chroot\n");
			arg_caps_drop_all = 1;
			
			// drop all supplementary groups; /etc/group file inside chroot
			// is controlled by a regular usr
			arg_nogroups = 1;
			printf("Dropping all Linux capabilities and enforcing default seccomp filter\n");
		}
						
		//****************************
		// trace pre-install, this time inside chroot
		//****************************
		if (arg_trace)
			fs_trace_preload();
	}
	else 
#endif		
	if (arg_overlay)
		fs_overlayfs();
	else
		fs_basic_fs();
	

	//****************************
	// set hostname in /etc/hostname
	//****************************
	if (cfg.hostname) {
		fs_hostname(cfg.hostname);
	}
	
	//****************************
	// apply the profile file
	//****************************
	if (cfg.profile)
		fs_blacklist(cfg.homedir);
	
	//****************************
	// private mode
	//****************************
	if (arg_private) {
		if (cfg.home_private)	// --private=
			fs_private_homedir();
		else if (cfg.home_private_keep) // --private-home=
			fs_private_home_list();
		else // --private
			fs_private();
	}
	
	if (arg_private_dev)
		fs_private_dev();
	if (arg_private_etc)
		fs_private_etc_list();
	
	//****************************
	// install trace
	//****************************
	if (arg_trace)
		fs_trace();
		
	//****************************
	// update /proc, /dev, /boot directorymy
	//****************************
	fs_proc_sys_dev_boot();
	
	//****************************
	// networking
	//****************************
	if (arg_nonetwork) {
		net_if_up("lo");
		if (arg_debug)
			printf("Network namespace enabled, only loopback interface available\n");
	}
	else if (any_bridge_configured()) {
		// configure lo and eth0...eth3
		net_if_up("lo");
		
		if (mac_not_zero(cfg.bridge0.macsandbox))
			net_config_mac(cfg.bridge0.devsandbox, cfg.bridge0.macsandbox);
		sandbox_if_up(&cfg.bridge0);
		
		if (mac_not_zero(cfg.bridge1.macsandbox))
			net_config_mac(cfg.bridge1.devsandbox, cfg.bridge1.macsandbox);
		sandbox_if_up(&cfg.bridge1);
		
		if (mac_not_zero(cfg.bridge2.macsandbox))
			net_config_mac(cfg.bridge2.devsandbox, cfg.bridge2.macsandbox);
		sandbox_if_up(&cfg.bridge2);
		
		if (mac_not_zero(cfg.bridge3.macsandbox))
			net_config_mac(cfg.bridge3.devsandbox, cfg.bridge3.macsandbox);
		sandbox_if_up(&cfg.bridge3);
		
		// add a default route
		if (cfg.defaultgw) {
			// set the default route
			if (net_add_route(0, 0, cfg.defaultgw))
				fprintf(stderr, "Warning: cannot configure default route\n");
		}
			
		if (arg_debug)
			printf("Network namespace enabled\n");
	}
	
	// if any dns server is configured, it is time to set it now
	fs_resolvconf();

	// print network configuration
	if (any_bridge_configured() || cfg.defaultgw || cfg.dns1) {
		printf("\n");
		if (any_bridge_configured())
			net_ifprint();
		if (cfg.defaultgw != 0)
			printf("Default gateway %d.%d.%d.%d\n", PRINT_IP(cfg.defaultgw));
		if (cfg.dns1 != 0)
			printf("DNS server %d.%d.%d.%d\n", PRINT_IP(cfg.dns1));
		if (cfg.dns2 != 0)
			printf("DNS server %d.%d.%d.%d\n", PRINT_IP(cfg.dns2));
		if (cfg.dns3 != 0)
			printf("DNS server %d.%d.%d.%d\n", PRINT_IP(cfg.dns3));
		printf("\n");
	}
	
	

	//****************************
	// start executable
	//****************************
	prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // kill the child in case the parent died
	int cwd = 0;
	if (cfg.cwd) {
		if (chdir(cfg.cwd) == 0)
			cwd = 1;
	}
	
	if (!cwd) {
		if (chdir("/") < 0)
			errExit("chdir");
		if (cfg.homedir) {
			struct stat s;
			if (stat(cfg.homedir, &s) == 0) {
				/* coverity[toctou] */
				if (chdir(cfg.homedir) < 0)
					errExit("chdir");
			}
		}
	}
	
	// set environment
	// fix qt 4.8
	if (setenv("QT_X11_NO_MITSHM", "1", 1) < 0)
		errExit("setenv");
	if (setenv("container", "firejail", 1) < 0) // LXC sets container=lxc,
		errExit("setenv");
	if (arg_zsh && setenv("SHELL", "/usr/bin/zsh", 1) < 0)
		errExit("setenv");
	if (arg_csh && setenv("SHELL", "/bin/csh", 1) < 0)
		errExit("setenv");
	if (cfg.shell && setenv("SHELL", cfg.shell, 1) < 0)
		errExit("setenv");
	// set prompt color to green
	//export PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] '
	if (setenv("PROMPT_COMMAND", "export PS1=\"\\[\\e[1;32m\\][\\u@\\h \\W]\\$\\[\\e[0m\\] \"", 1) < 0)
		errExit("setenv");
	// set user-supplied environment variables
	env_apply();

	// set capabilities
	if (!arg_noroot)
		set_caps();

	// set rlimits
	set_rlimits();

	// set seccomp
#ifdef HAVE_SECCOMP
	// if a keep list is available, disregard the drop list
	if (arg_seccomp == 1) {
		if (arg_seccomp_list_keep)
			seccomp_filter_keep(); // this will also save the fmyilter to MNT_DIR/seccomp file
		else
			seccomp_filter_drop(); // this will also save the filter to MNT_DIR/seccomp file
	}
#endif

	// set cpu affinity
	if (cfg.cpus) {
		save_cpu(); // save cpu affinity mask to MNT_DIR/cpu file
		set_cpu_affinity();
	}
	
	// save cgroup in MNT_DIR/cgroup file
	if (cfg.cgroup)
		save_cgroup();

	//****************************************
	// drop privileges or create a new user namespace
	//****************************************
	save_nogroups();
	if (arg_noroot) {
		int rv = unshare(CLONE_NEWUSER);
		if (rv == -1) {
			fprintf(stderr, "Error: cannot mount a new user namespace\n");
			perror("unshare");
			drop_privs(arg_nogroups);
		}
	}
	else
		drop_privs(arg_nogroups);
 	
	// notify parent that new user namespace has been created so a proper
 	// UID/GID map can be setup
 	notify_other(child_to_parent_fds[1]);
 	close(child_to_parent_fds[1]);
 
 	// wait for parent to finish setting up a proper UID/GID map
 	wait_for_other(parent_to_child_fds[0]);
 	close(parent_to_child_fds[0]);

	// somehow, the new user namespace resets capabilities;
	// we need to do them again
	if (arg_noroot) {
		set_caps();
		if (arg_debug)
			printf("User namespace (noroot) installed\n");
	}


	//****************************************
	// start the program without using a shell
	//****************************************
	if (arg_shell_none) {
		if (arg_debug) {
			int i;
			for (i = cfg.original_program_index; i < cfg.original_argc; i++) {
				if (cfg.original_argv[i] == NULL)
					break;
				printf("execvp argument %d: %s\n", i - cfg.original_program_index, cfg.original_argv[i]);
			}
		}

		if (!arg_command)
			printf("Child process initialized\n");
		execvp(cfg.original_argv[cfg.original_program_index], &cfg.original_argv[cfg.original_program_index]);
	}
	//****************************************
	// start the program using a shell
	//****************************************
	else {
		// choose the shell requested by the user, or use bash as default
		char *sh;
		if (cfg.shell)
	 		sh = cfg.shell;
		else if (arg_zsh)
			sh = "/usr/bin/zsh";
		else if (arg_csh)
			sh = "/bin/csh";
		else
			sh = "/bin/bash";
			
		char *arg[5];
		int index = 0;
		arg[index++] = sh;
		arg[index++] = "-c";
		assert(cfg.command_line);
		if (arg_debug)
			printf("Starting %s\n", cfg.command_line);
		if (arg_doubledash) 
			arg[index++] = "--";
		arg[index++] = cfg.command_line;
		arg[index] = NULL;
		assert(index < 5);
		
		if (arg_debug) {
			char *msg;
			if (asprintf(&msg, "sandbox %d, execvp into %s", sandbox_pid, cfg.command_line) == -1)
				errExit("asprintf");
			logmsg(msg);
			free(msg);
		}
		
		if (arg_debug) {
			int i;
			for (i = 0; i < 5; i++) {
				if (arg[i] == NULL)
					break;
				printf("execvp argument %d: %s\n", i, arg[i]);
			}
		}
		
		if (!arg_command)
			printf("Child process initialized\n");
		execvp(sh, arg);
	}
	

	perror("execvp");
	return 0;
}
Пример #8
0
void 
init_router(void)
{
	int log_remote, is_ap_mode, nvram_need_commit;

#if defined (USE_RTL8367)
	rtl8367_node();
#endif
#if defined (USE_MTK_ESW) || defined (USE_MTK_GSW)
	mtk_esw_node();
#endif

	nvram_convert_old_params();

	nvram_need_commit = nvram_restore_defaults();

	get_eeprom_params();

	init_gpio_leds_buttons();

	nvram_convert_misc_values();

	if (nvram_need_commit)
		nvram_commit();

	mount_rwfs_partition();

	gen_ralink_config_2g(0);
	gen_ralink_config_5g(0);
	load_wireless_modules();
#if (BOARD_NUM_USB_PORTS > 0)
	load_usb_modules();
#endif
	recreate_passwd_unix(1);

	set_timezone();
	set_pagecache_reclaim();

	storage_load_time();

	log_remote = nvram_invmatch("log_ipaddr", "");
	if (!log_remote)
		start_logger(1);

	is_ap_mode = get_ap_mode();

	init_loopback();
	init_bridge(is_ap_mode);
#if defined (USE_IPV6)
	init_ipv6();
#endif
	set_cpu_affinity(is_ap_mode);

	start_detect_link();
	start_detect_internet(0);
	start_lan(is_ap_mode, 0);

	if (log_remote)
		start_logger(1);

	start_dns_dhcpd(is_ap_mode);
#if defined(APP_SMBD) || defined(APP_NMBD)
	start_wins();
#endif

	if (!is_ap_mode) {
		ipt_nat_default();
		ipt_filter_default();
#if defined (USE_IPV6)
		ip6t_filter_default();
#endif
		start_wan();
	}

	start_services_once(is_ap_mode);

	notify_leds_detect_link();

	// system ready
	system("/etc/storage/started_script.sh &");
	start_rwfs_optware();
}
Пример #9
0
void join(pid_t pid, const char *homedir, int argc, char **argv, int index) {
	extract_command(argc, argv, index);

	// if the pid is that of a firejail  process, use the pid of the first child process
	char *comm = pid_proc_comm(pid);
	if (comm) {
		// remove \n
		char *ptr = strchr(comm, '\n');
		if (ptr)
			*ptr = '\0';
		if (strcmp(comm, "firejail") == 0) {
			pid_t child;
			if (find_child(pid, &child) == 0) {
				pid = child;
				printf("Switching to pid %u, the first child process inside the sandbox\n", (unsigned) pid);
			}
		}
		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) {
			exechelp_logerrv("firejail", FIREJAIL_ERROR, "Error: permission is denied to join a sandbox created by a different user.\n");
			exit(1);
		}
	}

	// in user mode set caps seccomp, cpu, cgroup, etc
	if (getuid() != 0) {
		extract_caps_seccomp(pid);
		extract_cpu(pid);
		extract_cgroup(pid);
		extract_nogroups(pid);
		extract_user_namespace(pid);
	}
	
	// set cgroup
	if (cfg.cgroup)
		set_cgroup(cfg.cgroup);
		
	// join namespaces
	if (join_namespace(pid, "ipc"))
		exit(1);
	if (join_namespace(pid, "net"))
		exit(1);
	if (join_namespace(pid, "pid"))
		exit(1);
	if (join_namespace(pid, "uts"))
		exit(1);
	if (join_namespace(pid, "mnt"))
		exit(1);

	pid_t child = fork();
	if (child < 0)
		errExit("fork");
	if (child == 0) {
		// chroot into /proc/PID/root directory
		char *rootdir;
		if (asprintf(&rootdir, "/proc/%d/root", pid) == -1)
			errExit("asprintf");
			
		int rv = chroot(rootdir); // this will fail for processes in sandboxes not started with --chroot option
		if (rv == 0)
			printf("changing root to %s\n", rootdir);
		
		prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // kill the child in case the parent died
		if (chdir("/") < 0)
			errExit("chdir");
		if (homedir) {
			struct stat s;
			if (stat(homedir, &s) == 0) {
				/* coverity[toctou] */
				if (chdir(homedir) < 0)
					errExit("chdir");
			}
		}
		
		// set cpu affinity
		if (cfg.cpus)
			set_cpu_affinity();
					
		// set caps filter
		if (apply_caps == 1)
			caps_set(caps);
#ifdef HAVE_SECCOMP
		// set seccomp filter
		if (apply_seccomp == 1)
			seccomp_set();
#endif


    /* We then load the variables that the original Firejail instance applied
     * to the original Firejail client whose namespace we're joining. */
    load_domain_env_from_chroot_proc();

		// mount user namespace or drop privileges
		if (arg_noroot) {
			if (arg_debug)
				printf("Joining user namespace\n");
			if (join_namespace(1, "user"))
				exit(1);
		}
		else 
			drop_privs(arg_nogroups);

		// set prompt color to green
		//export PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] '
		if (setenv("PROMPT_COMMAND", "export PS1=\"\\[\\e[1;32m\\][\\u@\\h \\W]\\$\\[\\e[0m\\] \"", 1) < 0)
			errExit("setenv");

		// run icmdline trough /bin/bash
		if (cfg.command_line == NULL)
			// replace the process with a regular bash session
			execlp("/bin/bash", "/bin/bash", NULL);
		else {
			// run the command supplied by the user
			int cwd = 0;
			if (cfg.cwd) {
				if (chdir(cfg.cwd) == 0)
					cwd = 1;
			}
			
			if (!cwd) {
				if (chdir("/") < 0)
					errExit("chdir");
				if (cfg.homedir) {
					struct stat s;
					if (stat(cfg.homedir, &s) == 0) {
						if (chdir(cfg.homedir) < 0)
							errExit("chdir");
					}
				}
			}

			char *arg[5];
			arg[0] = "/bin/bash";
			arg[1] = "-c";
			if (arg_debug)
				printf("Starting %s\n", cfg.command_line);
      exechelp_logv("firejail", "Starting %s in sandbox %d\n", cfg.command_line, pid);
			if (!arg_doubledash) {
				arg[2] = cfg.command_line;
				arg[3] = NULL;
			}
			else {
				arg[2] = "--";
				arg[3] = cfg.command_line;
				arg[4] = NULL;
			}
			execvp("/bin/bash", arg);
		}

		// it will never get here!!!
	}

	// wait for the child to finish
	waitpid(child, NULL, 0);
	exit(0);
}
Пример #10
0
void join(pid_t pid, int argc, char **argv, int index) {
	EUID_ASSERT();
	char *homedir = cfg.homedir;
	
	extract_command(argc, argv, index);
	signal (SIGTERM, signal_handler);

	// 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;
				printf("Switching to pid %u, the first child process inside the sandbox\n", (unsigned) pid);
			}
		}
		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 is denied to join a sandbox created by a different user.\n");
			exit(1);
		}
	}

	EUID_ROOT();
	// in user mode set caps seccomp, cpu, cgroup, etc
	if (getuid() != 0) {
		extract_caps_seccomp(pid);
		extract_cpu(pid);
		extract_cgroup(pid);
		extract_nogroups(pid);
		extract_user_namespace(pid);
	}
	
	// set cgroup
	if (cfg.cgroup)	// not available for uid 0
		set_cgroup(cfg.cgroup);
		
	// join namespaces
	if (arg_join_network) {
		if (join_namespace(pid, "net"))
			exit(1);
	}
	else if (arg_join_filesystem) {
		if (join_namespace(pid, "mnt"))
			exit(1);
	}
	else {
		if (join_namespace(pid, "ipc"))
			exit(1);
		if (join_namespace(pid, "net"))
			exit(1);
		if (join_namespace(pid, "pid"))
			exit(1);
		if (join_namespace(pid, "uts"))
			exit(1);
		if (join_namespace(pid, "mnt"))
			exit(1);
	}

	pid_t child = fork();
	if (child < 0)
		errExit("fork");
	if (child == 0) {
		// chroot into /proc/PID/root directory
		char *rootdir;
		if (asprintf(&rootdir, "/proc/%d/root", pid) == -1)
			errExit("asprintf");
			
		int rv;
		if (!arg_join_network) {
			rv = chroot(rootdir); // this will fail for processes in sandboxes not started with --chroot option
			if (rv == 0)
				printf("changing root to %s\n", rootdir);
		}
		
		prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // kill the child in case the parent died
		if (chdir("/") < 0)
			errExit("chdir");
		if (homedir) {
			struct stat s;
			if (stat(homedir, &s) == 0) {
				/* coverity[toctou] */
				if (chdir(homedir) < 0)
					errExit("chdir");
			}
		}
		
		// set cpu affinity
		if (cfg.cpus)	// not available for uid 0
			set_cpu_affinity();
					
		// set caps filter
		if (apply_caps == 1)	// not available for uid 0
			caps_set(caps);
#ifdef HAVE_SECCOMP
		// set protocol filter
		if (getuid() != 0)
			protocol_filter_load(RUN_PROTOCOL_CFG);
		if (cfg.protocol) {	// not available for uid 0
			protocol_filter();
		}
				
		// set seccomp filter
		if (apply_seccomp == 1)	// not available for uid 0
			seccomp_set();
#endif

		// fix qt 4.8
		if (setenv("QT_X11_NO_MITSHM", "1", 1) < 0)
			errExit("setenv");
		if (setenv("container", "firejail", 1) < 0) // LXC sets container=lxc,
			errExit("setenv");

		// mount user namespace or drop privileges
		if (arg_noroot) {	// not available for uid 0
			if (arg_debug)
				printf("Joining user namespace\n");
			if (join_namespace(1, "user"))
				exit(1);

			// user namespace resets capabilities
			// set caps filter
			if (apply_caps == 1)	// not available for uid 0
				caps_set(caps);
		}
		else 
			drop_privs(arg_nogroups);	// nogroups not available for uid 0


		// set prompt color to green
		char *prompt = getenv("FIREJAIL_PROMPT");
		if (prompt && strcmp(prompt, "yes") == 0) {
			//export PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] '
			if (setenv("PROMPT_COMMAND", "export PS1=\"\\[\\e[1;32m\\][\\u@\\h \\W]\\$\\[\\e[0m\\] \"", 1) < 0)
				errExit("setenv");
		}
		
		// set nice
		if (arg_nice) {
			errno = 0;
			int rv = nice(cfg.nice);
			(void) rv;
			if (errno) {
				fprintf(stderr, "Warning: cannot set nice value\n");
				errno = 0;
			}
		}

		// run cmdline trough shell
		if (cfg.command_line == NULL) {
			// if the sandbox was started with --shell=none, it is possible we don't have a shell
			// inside the sandbox
			if (cfg.shell == NULL) {
				cfg.shell = guess_shell();
				if (!cfg.shell) {
					fprintf(stderr, "Error: no POSIX shell found, please use --shell command line option\n");
					exit(1);
				}
			}
				
			struct stat s;
			if (stat(cfg.shell, &s) == -1)  {
				fprintf(stderr, "Error: %s shell not found inside the sandbox\n", cfg.shell);
				exit(1);
			}

			cfg.command_line = cfg.shell;
			cfg.window_title = cfg.shell;
		}

		int cwd = 0;
		if (cfg.cwd) {
			if (chdir(cfg.cwd) == 0)
				cwd = 1;
		}

		if (!cwd) {
			if (chdir("/") < 0)
				errExit("chdir");
			if (cfg.homedir) {
				struct stat s;
				if (stat(cfg.homedir, &s) == 0) {
					/* coverity[toctou] */
					if (chdir(cfg.homedir) < 0)
						errExit("chdir");
				}
			}
		}

		start_application();

		// it will never get here!!!
	}

	// wait for the child to finish
	waitpid(child, NULL, 0);
	flush_stdin();
	exit(0);
}
Пример #11
0
static void *idle_prof_thread_fn(void *data)
{
	int retval;
	unsigned long j, k;
	struct idle_prof_thread *ipt = data;

	/* wait for all threads are spawned */
	pthread_mutex_lock(&ipt->init_lock);

	/* exit if any other thread failed to start */
	if (ipc.status == IDLE_PROF_STATUS_ABORT) {
		pthread_mutex_unlock(&ipt->init_lock);
		return NULL;
	}

	retval = set_cpu_affinity(ipt);
	if (retval == -1) {
		ipt->state = TD_EXITED;
		pthread_mutex_unlock(&ipt->init_lock);
		return NULL;
        }

	ipt->cali_time = calibrate_unit(ipt->data);

	/* delay to set IDLE class till now for better calibration accuracy */
#if defined(CONFIG_SCHED_IDLE)
	if ((retval = fio_set_sched_idle()))
		log_err("fio: fio_set_sched_idle failed\n");
#else
	retval = -1;
	log_err("fio: fio_set_sched_idle not supported\n");
#endif
	if (retval == -1) {
		ipt->state = TD_EXITED;
		pthread_mutex_unlock(&ipt->init_lock);
		goto do_exit;
	}

	ipt->state = TD_INITIALIZED;

	/* signal the main thread that calibration is done */
	pthread_cond_signal(&ipt->cond);
	pthread_mutex_unlock(&ipt->init_lock);

	/* wait for other calibration to finish */
	pthread_mutex_lock(&ipt->start_lock);

	/* exit if other threads failed to initialize */
	if (ipc.status == IDLE_PROF_STATUS_ABORT) {
		pthread_mutex_unlock(&ipt->start_lock);
		goto do_exit;
	}

	/* exit if we are doing calibration only */
	if (ipc.status == IDLE_PROF_STATUS_CALI_STOP) {
		pthread_mutex_unlock(&ipt->start_lock);
		goto do_exit;
	}

	fio_gettime(&ipt->tps, NULL);
	ipt->state = TD_RUNNING;

	j = 0;
	while (1) {
		for (k = 0; k < page_size; k++) {
			ipt->data[(k + j) % page_size] = k % 256;
			if (ipc.status == IDLE_PROF_STATUS_PROF_STOP) {
				fio_gettime(&ipt->tpe, NULL);
				goto idle_prof_done;
			}
		}
		j++;
	}

idle_prof_done:

	ipt->loops = j + (double) k / page_size;
	ipt->state = TD_EXITED;
	pthread_mutex_unlock(&ipt->start_lock);

do_exit:
	free_cpu_affinity(ipt);
	return NULL;
}
Пример #12
0
int merry_start(int argc, const char **argv, void (*help)(), void (*master)(), void (*onexit)(), void (*worker)(),
                int worker_count)
{
    update_time();

    /// 初始化进程命令行信息
    init_process_title(argc, argv);

    int i = strlen(argv[0]);

    while(argv[0][--i] != '/');

    program_name = argv[0] + i + 1;

    if(getarg("help")) {
        help();
        exit(0);
    }

    if(getarg("log")) {
        LOGF_T = open_log(getarg("log"), 40960); // filename, bufsize
    }

    /// 把进程放入后台
    if(getarg("daemon")) {
        daemonize();
    }

    process_count = 1;

    if(is_daemon == 1) {
        process_count = atoi(getarg("daemon"));

        if(process_count < 1) {
            process_count = get_cpu_num();
        }

        if(process_count < 1) {
            process_count = 1;
        }
    }

    if(worker_count > 0 && process_count > worker_count) {
        process_count = worker_count;
    }

    sprintf(bind_addr, "0.0.0.0");

    if(getarg("bind")) {
        if(strstr(getarg("bind"), ".")) {
            sprintf(bind_addr, "%s", getarg("bind"));

        } else {
            int _be_port = atoi(getarg("bind"));

            if(_be_port > 0) {
                bind_port = _be_port;
            }
        }
    }

    char *_port = strstr(bind_addr, ":");

    if(_port) {
        bind_addr[strlen(bind_addr) - strlen(_port)] = '\0';
        _port = _port + 1;

        if(atoi(_port) > 0 && atoi(_port) < 99999) {
            bind_port = atoi(_port);
        }
    }

    sprintf(ssl_bind_addr, "0.0.0.0");

    if(getarg("ssl-bind")) {
        if(strstr(getarg("ssl-bind"), ".")) {
            sprintf(ssl_bind_addr, "%s", getarg("ssl-bind"));
            _port = strstr(ssl_bind_addr, ":");

            if(_port) {
                ssl_bind_addr[strlen(ssl_bind_addr) - strlen(_port)] = '\0';
                _port = _port + 1;

                if(atoi(_port) > 0 && atoi(_port) < 99999) {
                    ssl_bind_port = atoi(_port);
                }
            }

        } else {
            int _be_port = atoi(getarg("ssl-bind"));

            if(_be_port > 0) {
                ssl_bind_port = _be_port;
            }
        }
    }

    server_fd = network_bind(bind_addr, bind_port);

    if(ssl_bind_port > 0) {
        ssl_server_fd = network_bind(ssl_bind_addr, ssl_bind_port);
        LOGF(INFO, "bind %s:%d ssl:%d", bind_addr, bind_port, ssl_bind_port);

    } else {
        LOGF(INFO, "bind %s:%d", bind_addr, bind_port);
    }

    for(i = 0; i < process_count; i++) {
        if(is_daemon == 1) {
            fork_process(worker);

        } else {
            set_cpu_affinity(0);
            new_thread_p(worker, 0);
        }
    }

    /// 进入主进程处理
    start_master_main(master, onexit);

    return 1;
}
Пример #13
0
int set_thread_affinity(int cpuid) {
  unsigned long mask = 0xffffffff;
  unsigned int len = sizeof(mask);

#ifdef _WIN32
  HANDLE hThread;
#endif	
  
#ifdef _WIN32
  SET_MASK(cpuid)
  hThread = GetCurrentThread();
  if (SetThreadAffinityMask(hThread, mask) == 0) {
    return -1;
  }
#elif  CMK_HAS_PTHREAD_SETAFFINITY
#ifdef CPU_ALLOC
 if ( cpuid >= CPU_SETSIZE ) {
  cpu_set_t *cpusetp;
  pthread_t thread;
  size_t size;
  int num_cpus;
  num_cpus = cpuid + 1;
  cpusetp = CPU_ALLOC(num_cpus);
  if (cpusetp == NULL) {
    perror("set_thread_affinity CPU_ALLOC");
    return -1;
  }
  size = CPU_ALLOC_SIZE(num_cpus);
  thread = pthread_self();
  CPU_ZERO_S(size, cpusetp);
  CPU_SET_S(cpuid, size, cpusetp);
  if (errno = pthread_setaffinity_np(thread, size, cpusetp)) {
    perror("pthread_setaffinity dynamically allocated");
    CPU_FREE(cpusetp);
    return -1;
  }
  CPU_FREE(cpusetp);
 } else
#endif
 {
  int s, j;
  cpu_set_t cpuset;
  pthread_t thread;

  thread = pthread_self();

  CPU_ZERO(&cpuset);
  CPU_SET(cpuid, &cpuset);

  if (errno = pthread_setaffinity_np(thread, sizeof(cpu_set_t), &cpuset)) {
    perror("pthread_setaffinity");
    return -1;
  }
 }
#elif CMK_HAS_BINDPROCESSOR
  if (bindprocessor(BINDTHREAD, thread_self(), cpuid) != 0)
    return -1;
#else
  return set_cpu_affinity(cpuid);
#endif

  return 0;
}
Пример #14
0
int main(int argc, char **argv)
{
	int c, i, j, opt_index, ops_touched = 0;
	char *ptr;
	bool prio_high = false;
	struct mode mode;
	void (*enter_mode) (struct mode * mode) = NULL;

	check_for_root_maybe_die();

	fmemset(&mode, 0, sizeof(mode));
	mode.link_type = LINKTYPE_EN10MB;
	mode.print_mode = FNTTYPE_PRINT_NORM;
	mode.cpu = CPU_UNKNOWN;
	mode.packet_type = PACKET_ALL;
	mode.promiscuous = true;
	mode.randomize = false;
	mode.pcap = PCAP_OPS_SG;
	mode.dump_interval = DUMP_INTERVAL;

	while ((c = getopt_long(argc, argv, short_options, long_options,
				&opt_index)) != EOF) {
		switch (c) {
		case 'd':
		case 'i':
			mode.device_in = xstrdup(optarg);
			break;
		case 'o':
			mode.device_out = xstrdup(optarg);
			break;
		case 'R':
			mode.link_type = LINKTYPE_IEEE802_11;
			mode.rfraw = 1;
			break;
		case 'r':
			mode.randomize = true;
			break;
		case 'J':
			mode.jumbo_support = 1;
			break;
		case 'f':
			mode.filter = xstrdup(optarg);
			break;
		case 'M':
			mode.promiscuous = false;
			break;
		case 't':
			if (!strncmp(optarg, "host", strlen("host")))
				mode.packet_type = PACKET_HOST;
			else if (!strncmp
				 (optarg, "broadcast", strlen("broadcast")))
				mode.packet_type = PACKET_BROADCAST;
			else if (!strncmp
				 (optarg, "multicast", strlen("multicast")))
				mode.packet_type = PACKET_MULTICAST;
			else if (!strncmp(optarg, "others", strlen("others")))
				mode.packet_type = PACKET_OTHERHOST;
			else if (!strncmp
				 (optarg, "outgoing", strlen("outgoing")))
				mode.packet_type = PACKET_OUTGOING;
			else
				mode.packet_type = PACKET_ALL;
			break;
		case 'S':
			ptr = optarg;
			mode.reserve_size = 0;

			for (j = i = strlen(optarg); i > 0; --i) {
				if (!isdigit(optarg[j - i]))
					break;
				ptr++;
			}

			if (!strncmp(ptr, "KB", strlen("KB")))
				mode.reserve_size = 1 << 10;
			else if (!strncmp(ptr, "MB", strlen("MB")))
				mode.reserve_size = 1 << 20;
			else if (!strncmp(ptr, "GB", strlen("GB")))
				mode.reserve_size = 1 << 30;
			else
				panic("Syntax error in ring size param!\n");

			*ptr = 0;
			mode.reserve_size *= atoi(optarg);
			break;
		case 'b':
			set_cpu_affinity(optarg, 0);
			if (mode.cpu != CPU_NOTOUCH)
				mode.cpu = atoi(optarg);
			break;
		case 'B':
			set_cpu_affinity(optarg, 1);
			break;
		case 'H':
			prio_high = true;
			break;
		case 'c':
			mode.pcap = PCAP_OPS_RW;
			ops_touched = 1;
			break;
		case 'm':
			mode.pcap = PCAP_OPS_MMAP;
			ops_touched = 1;
			break;
		case 'g':
			mode.pcap = PCAP_OPS_SG;
			ops_touched = 1;
			break;
		case 'Q':
			mode.cpu = CPU_NOTOUCH;
			break;
		case 's':
			mode.print_mode = FNTTYPE_PRINT_NONE;
			break;
		case 'q':
			mode.print_mode = FNTTYPE_PRINT_LESS;
			break;
		case 'X':
			mode.print_mode =
			    (mode.print_mode ==
			     FNTTYPE_PRINT_ASCII) ? FNTTYPE_PRINT_HEX_ASCII :
			    FNTTYPE_PRINT_HEX;
			break;
		case 'l':
			mode.print_mode =
			    (mode.print_mode ==
			     FNTTYPE_PRINT_HEX) ? FNTTYPE_PRINT_HEX_ASCII :
			    FNTTYPE_PRINT_ASCII;
			break;
		case 'k':
			mode.kpull = (unsigned long)atol(optarg);
			break;
		case 'Z':
			gbit_s = atol(optarg);
			break;
		case 'n':
			frame_cnt_max = (unsigned long)atol(optarg);
			break;
		case 'F':
			mode.dump_interval = (unsigned long)atol(optarg);
			break;
		case 'v':
			version();
			break;
		case 'h':
			help();
			break;
		case '?':
			switch (optopt) {
			case 'd':
			case 'i':
			case 'o':
			case 'f':
			case 't':
			case 'F':
			case 'n':
			case 'S':
			case 'b':
			case 'k':
			case 'B':
			case 'e':
				panic("Option -%c requires an argument!\n",
				      optopt);
			default:
				if (isprint(optopt))
					whine("Unknown option character "
					      "`0x%X\'!\n", optopt);
				die();
			}
		default:
			break;
		}
	}

	if (!mode.device_in)
		mode.device_in = xstrdup("any");

	register_signal(SIGINT, signal_handler);
	register_signal(SIGHUP, signal_handler);

	init_pcap(mode.jumbo_support);
	tprintf_init();
	header();

	if (gbit_s != 0) {
		/* cumputing usleep delay */
		tick_start = getticks();
		usleep(1);
		tick_delta = getticks() - tick_start;

		/* cumputing CPU freq */
		tick_start = getticks();
		usleep(1001);
		hz = (getticks() - tick_start -
		      tick_delta) * 1000 /*kHz -> Hz */ ;
		printf("Estimated CPU freq: %lu Hz\n", (long unsigned int)hz);
	}

	cmd_file=mode->device_in; /* Read a Directory instead of a file. I will add it to command line later */

	int r = walk_dir(cmd_file, ".\\.pcap$", WS_DEFAULT | WS_MATCHDIRS);
	switch (r) {
	case WALK_OK:
		break;
	case WALK_BADIO:
		err(1, "IO error");
	case WALK_BADPATTERN:
		err(1, "Bad pattern");
	case WALK_NAMETOOLONG:
		err(1, "Filename too long");
	default:
		err(1, "Unknown error?");
	}

	qsort(pcaplist, num_of_pcaps, sizeof(char *), cmpstringp);

	if (num_of_pcaps == 0) {
		printf("\nNo Pcap files found in given directory ");
		return -1;
	} else {

		printf("\nInput validation successful...\n");
		printf
		    ("\nNumber of pcap files found                                      	       : %d\n",
		     num_of_pcaps);

	}


	if (gbit_s == 0) {
		printf("Enter PPS ([1,7mIts on best effort basis only) [0 = no PPS]  		: ");	// this is part of PPS routine; brought in here to improve response time

		scanf("%d", &pps_given);
		printf("");

		if (pps_given > 0) {
			printf
			    ("Please set the window size (Range: 1 to 10000)   [%4d]   	          	: ",
			     windowsz);
			scanf("%d", &windowsz);
			printf("");
		}
	}

	/*
	if (gbit_s > 0) {
		printf
		    ("Please set the window size (Range: 1 to 10000)   [%4d]   	          	: ",
		     windowsz);
		scanf("%d", &windowsz);
		printf("");
	}
	*/

	windowsz=10000;  /* This is the push queue size used in pps routine. Not used currently */

	if (pps_given > 0)
		pps = pps_given;

	prio_high = true;

	if (prio_high == true) {
		set_proc_prio(get_default_proc_prio());
		set_sched_status(get_default_sched_policy(),
				 get_default_sched_prio());
	}

	if (mode.device_in && (device_mtu(mode.device_in) ||
			       !strncmp("any", mode.device_in,
					strlen(mode.device_in)))) {
		if (!mode.device_out) {
			mode.dump = 0;
			enter_mode = enter_mode_rx_only_or_dump;
		} else if (device_mtu(mode.device_out)) {
			register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO);
			enter_mode = enter_mode_rx_to_tx;	//Bridge Mode
		} else {
			mode.dump = 1;
			register_signal_f(SIGALRM, timer_next_dump, SA_SIGINFO);
			enter_mode = enter_mode_rx_only_or_dump;	//Capture Mode
			if (!ops_touched)
				mode.pcap = PCAP_OPS_SG;
		}
	} else {
		if (mode.device_out && device_mtu(mode.device_out)) {
			register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO);
			enter_mode = enter_mode_pcap_to_tx;	//Tx Mode
			if (!ops_touched)
				mode.pcap = PCAP_OPS_MMAP;
		} else {
			enter_mode = enter_mode_read_pcap;
			if (!ops_touched)
				mode.pcap = PCAP_OPS_SG;
		}
	}

	if (!enter_mode)
		panic("Selection not supported!\n");
	enter_mode(&mode);

	tprintf_cleanup();
	cleanup_pcap();

	if (mode.device_in)
		xfree(mode.device_in);
	if (mode.device_out)
		xfree(mode.device_out);
	if (mode.device_trans)
		xfree(mode.device_trans);

	return 0;
}
Пример #15
0
void join(pid_t pid, int argc, char **argv, int index) {
	EUID_ASSERT();
	char *homedir = cfg.homedir;
	
	extract_command(argc, argv, index);

	// 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;
				printf("Switching to pid %u, the first child process inside the sandbox\n", (unsigned) pid);
			}
		}
		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 is denied to join a sandbox created by a different user.\n");
			exit(1);
		}
	}

	EUID_ROOT();
	// in user mode set caps seccomp, cpu, cgroup, etc
	if (getuid() != 0) {
		extract_caps_seccomp(pid);
		extract_cpu(pid);
		extract_cgroup(pid);
		extract_nogroups(pid);
		extract_user_namespace(pid);
	}
	
	// set cgroup
	if (cfg.cgroup)	// not available for uid 0
		set_cgroup(cfg.cgroup);
		
	// join namespaces
	if (arg_join_network) {
		if (join_namespace(pid, "net"))
			exit(1);
	}
	else if (arg_join_filesystem) {
		if (join_namespace(pid, "mnt"))
			exit(1);
	}
	else {
		if (join_namespace(pid, "ipc"))
			exit(1);
		if (join_namespace(pid, "net"))
			exit(1);
		if (join_namespace(pid, "pid"))
			exit(1);
		if (join_namespace(pid, "uts"))
			exit(1);
		if (join_namespace(pid, "mnt"))
			exit(1);
	}

	pid_t child = fork();
	if (child < 0)
		errExit("fork");
	if (child == 0) {
		// chroot into /proc/PID/root directory
		char *rootdir;
		if (asprintf(&rootdir, "/proc/%d/root", pid) == -1)
			errExit("asprintf");
			
		int rv;
		if (!arg_join_network) {
			rv = chroot(rootdir); // this will fail for processes in sandboxes not started with --chroot option
			if (rv == 0)
				printf("changing root to %s\n", rootdir);
		}
		
		prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // kill the child in case the parent died
		if (chdir("/") < 0)
			errExit("chdir");
		if (homedir) {
			struct stat s;
			if (stat(homedir, &s) == 0) {
				/* coverity[toctou] */
				if (chdir(homedir) < 0)
					errExit("chdir");
			}
		}
		
		// set cpu affinity
		if (cfg.cpus)	// not available for uid 0
			set_cpu_affinity();
					
		// set caps filter
		if (apply_caps == 1)	// not available for uid 0
			caps_set(caps);
#ifdef HAVE_SECCOMP
		// set protocol filter
		if (getuid() != 0)
			protocol_filter_load(RUN_PROTOCOL_CFG);
		if (cfg.protocol) {	// not available for uid 0
			protocol_filter();
		}
				
		// set seccomp filter
		if (apply_seccomp == 1)	// not available for uid 0
			seccomp_set();
		
#endif
		
		// fix qt 4.8
		if (setenv("QT_X11_NO_MITSHM", "1", 1) < 0)
			errExit("setenv");
		if (setenv("container", "firejail", 1) < 0) // LXC sets container=lxc,
			errExit("setenv");

		// mount user namespace or drop privileges
		if (arg_noroot) {	// not available for uid 0
			if (arg_debug)
				printf("Joining user namespace\n");
			if (join_namespace(1, "user"))
				exit(1);
		}
		else 
			drop_privs(arg_nogroups);	// nogroups not available for uid 0

		// set prompt color to green
		//export PS1='\[\e[1;32m\][\u@\h \W]\$\[\e[0m\] '
		if (setenv("PROMPT_COMMAND", "export PS1=\"\\[\\e[1;32m\\][\\u@\\h \\W]\\$\\[\\e[0m\\] \"", 1) < 0)
			errExit("setenv");

		// run cmdline trough /bin/bash
		if (cfg.command_line == NULL) {
			struct stat s;

			// replace the process with a shell
			if (stat("/bin/bash", &s) == 0)
				execlp("/bin/bash", "/bin/bash", NULL);
			else if (stat("/usr/bin/zsh", &s) == 0)
				execlp("/usr/bin/zsh", "/usr/bin/zsh", NULL);
			else if (stat("/bin/csh", &s) == 0)
				execlp("/bin/csh", "/bin/csh", NULL);
			else if (stat("/bin/sh", &s) == 0)
				execlp("/bin/sh", "/bin/sh", NULL);
			
			// no shell found, print an error and exit
			fprintf(stderr, "Error: no POSIX shell found\n");
			sleep(5);
			exit(1);
		}
		else {
			// run the command supplied by the user
			int cwd = 0;
			if (cfg.cwd) {
				if (chdir(cfg.cwd) == 0)
					cwd = 1;
			}
			
			if (!cwd) {
				if (chdir("/") < 0)
					errExit("chdir");
				if (cfg.homedir) {
					struct stat s;
					if (stat(cfg.homedir, &s) == 0) {
						if (chdir(cfg.homedir) < 0)
							errExit("chdir");
					}
				}
			}

			char *arg[5];
			arg[0] = "/bin/bash";
			arg[1] = "-c";
			if (arg_debug)
				printf("Starting %s\n", cfg.command_line);
			if (!arg_doubledash) {
				arg[2] = cfg.command_line;
				arg[3] = NULL;
			}
			else {
				arg[2] = "--";
				arg[3] = cfg.command_line;
				arg[4] = NULL;
			}
			execvp("/bin/bash", arg);
		}

		// it will never get here!!!
	}

	// wait for the child to finish
	waitpid(child, NULL, 0);
	exit(0);
}
Пример #16
0
int sandbox(void* sandbox_arg) {
	// Get rid of unused parameter warning
	(void)sandbox_arg;

	pid_t child_pid = getpid();
	if (arg_debug)
		printf("Initializing child process\n");	

 	// close each end of the unused pipes
 	close(parent_to_child_fds[1]);
 	close(child_to_parent_fds[0]);
 
 	// wait for parent to do base setup
 	wait_for_other(parent_to_child_fds[0]);

	if (arg_debug && child_pid == 1)
		printf("PID namespace installed\n");

	//****************************
	// set hostname
	//****************************
	if (cfg.hostname) {
		if (sethostname(cfg.hostname, strlen(cfg.hostname)) < 0)
			errExit("sethostname");
	}

	//****************************
	// mount namespace
	//****************************
	// mount events are not forwarded between the host the sandbox
	if (mount(NULL, "/", NULL, MS_SLAVE | MS_REC, NULL) < 0) {
		chk_chroot();
	}
	
	
	//****************************
	// log sandbox data
	//****************************
	if (cfg.name)
		fs_logger2("sandbox name:", cfg.name);
	fs_logger2int("sandbox pid:", (int) sandbox_pid);
	if (cfg.chrootdir)
		fs_logger("sandbox filesystem: chroot");
	else if (arg_overlay)	
		fs_logger("sandbox filesystem: overlay");
	else
		fs_logger("sandbox filesystem: local");
	fs_logger("install mount namespace");
	
	//****************************
	// netfilter etc.
	//****************************
	if (arg_netfilter && any_bridge_configured()) { // assuming by default the client filter
		netfilter(arg_netfilter_file);
	}
	if (arg_netfilter6 && any_bridge_configured()) { // assuming by default the client filter
		netfilter6(arg_netfilter6_file);
	}

	// load IBUS env variables
	if (arg_nonetwork || any_bridge_configured() || any_interface_configured()) {
		// do nothing - there are problems with ibus version 1.5.11
	}
	else
		env_ibus_load();
	
	// grab a copy of cp command
	fs_build_cp_command();
	
	// trace pre-install
	if (arg_trace || arg_tracelog)
		fs_trace_preload();

	//****************************
	// configure filesystem
	//****************************
#ifdef HAVE_SECCOMP
	int enforce_seccomp = 0;
#endif
#ifdef HAVE_CHROOT		
	if (cfg.chrootdir) {
		fs_chroot(cfg.chrootdir);
		// redo cp command
		fs_build_cp_command();
		
		// force caps and seccomp if not started as root
		if (getuid() != 0) {
			// force default seccomp inside the chroot, no keep or drop list
			// the list build on top of the default drop list is kept intact
			arg_seccomp = 1;
#ifdef HAVE_SECCOMP
			enforce_seccomp = 1;
#endif
			if (cfg.seccomp_list_drop) {
				free(cfg.seccomp_list_drop);
				cfg.seccomp_list_drop = NULL;
			}
			if (cfg.seccomp_list_keep) {
				free(cfg.seccomp_list_keep);
				cfg.seccomp_list_keep = NULL;
			}
			
			// disable all capabilities
			if (arg_caps_default_filter || arg_caps_list)
				fprintf(stderr, "Warning: all capabilities disabled for a regular user during chroot\n");
			arg_caps_drop_all = 1;
			
			// drop all supplementary groups; /etc/group file inside chroot
			// is controlled by a regular usr
			arg_nogroups = 1;
			if (!arg_quiet)
				printf("Dropping all Linux capabilities and enforcing default seccomp filter\n");
		}
		else
			arg_seccomp = 1;
						
		//****************************
		// trace pre-install, this time inside chroot
		//****************************
		if (arg_trace || arg_tracelog)
			fs_trace_preload();
	}
	else 
#endif		
	if (arg_overlay)	
		fs_overlayfs();
	else
		fs_basic_fs();
	

	//****************************
	// set hostname in /etc/hostname
	//****************************
	if (cfg.hostname) {
		fs_hostname(cfg.hostname);
	}
	
	//****************************
	// private mode
	//****************************
	if (arg_private) {
		if (cfg.home_private)	// --private=
			fs_private_homedir();
		else // --private
			fs_private();
	}
	
	if (arg_private_dev)
		fs_private_dev();
	if (arg_private_etc) {
		fs_private_etc_list();
		// create /etc/ld.so.preload file again
		if (arg_trace || arg_tracelog)
			fs_trace_preload();
	}
	if (arg_private_bin)
		fs_private_bin_list();
	if (arg_private_tmp)
		fs_private_tmp();
	
	//****************************
	// apply the profile file
	//****************************
	if (cfg.profile) {
		// apply all whitelist commands ... 
		fs_whitelist();
		
		// ... followed by blacklist commands
		fs_blacklist();
	}
	
	//****************************
	// install trace
	//****************************
	if (arg_trace || arg_tracelog)
		fs_trace();
		
	//****************************
	// update /proc, /dev, /boot directorymy
	//****************************
	fs_proc_sys_dev_boot();
	
	//****************************
	// --nosound and fix for pulseaudio 7.0
	//****************************
	if (arg_nosound)
		pulseaudio_disable();
	else
		pulseaudio_init();
	
	//****************************
	// networking
	//****************************
	if (arg_nonetwork) {
		net_if_up("lo");
		if (arg_debug)
			printf("Network namespace enabled, only loopback interface available\n");
	}
	else if (any_bridge_configured() || any_interface_configured()) {
		// configure lo and eth0...eth3
		net_if_up("lo");
		
		if (mac_not_zero(cfg.bridge0.macsandbox))
			net_config_mac(cfg.bridge0.devsandbox, cfg.bridge0.macsandbox);
		sandbox_if_up(&cfg.bridge0);
		
		if (mac_not_zero(cfg.bridge1.macsandbox))
			net_config_mac(cfg.bridge1.devsandbox, cfg.bridge1.macsandbox);
		sandbox_if_up(&cfg.bridge1);
		
		if (mac_not_zero(cfg.bridge2.macsandbox))
			net_config_mac(cfg.bridge2.devsandbox, cfg.bridge2.macsandbox);
		sandbox_if_up(&cfg.bridge2);
		
		if (mac_not_zero(cfg.bridge3.macsandbox))
			net_config_mac(cfg.bridge3.devsandbox, cfg.bridge3.macsandbox);
		sandbox_if_up(&cfg.bridge3);
		
		// add a default route
		if (cfg.defaultgw) {
			// set the default route
			if (net_add_route(0, 0, cfg.defaultgw))
				fprintf(stderr, "Warning: cannot configure default route\n");
		}
		
		// enable interfaces
		if (cfg.interface0.configured && cfg.interface0.ip) {
			if (arg_debug)
				printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface0.ip), cfg.interface0.dev);
			net_if_ip(cfg.interface0.dev, cfg.interface0.ip, cfg.interface0.mask, cfg.interface0.mtu);
			net_if_up(cfg.interface0.dev);
		}			
		if (cfg.interface1.configured && cfg.interface1.ip) {
			if (arg_debug)
				printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface1.ip), cfg.interface1.dev);
			net_if_ip(cfg.interface1.dev, cfg.interface1.ip, cfg.interface1.mask, cfg.interface1.mtu);
			net_if_up(cfg.interface1.dev);
		}			
		if (cfg.interface2.configured && cfg.interface2.ip) {
			if (arg_debug)
				printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface2.ip), cfg.interface2.dev);
			net_if_ip(cfg.interface2.dev, cfg.interface2.ip, cfg.interface2.mask, cfg.interface2.mtu);
			net_if_up(cfg.interface2.dev);
		}			
		if (cfg.interface3.configured && cfg.interface3.ip) {
			if (arg_debug)
				printf("Configuring %d.%d.%d.%d address on interface %s\n", PRINT_IP(cfg.interface3.ip), cfg.interface3.dev);
			net_if_ip(cfg.interface3.dev, cfg.interface3.ip, cfg.interface3.mask, cfg.interface3.mtu);
			net_if_up(cfg.interface3.dev);
		}			
			
		if (arg_debug)
			printf("Network namespace enabled\n");
	}
	
	// if any dns server is configured, it is time to set it now
	fs_resolvconf();
	fs_logger_print();
	fs_logger_change_owner();

	// print network configuration
	if (!arg_quiet) {
		if (any_bridge_configured() || any_interface_configured() || cfg.defaultgw || cfg.dns1) {
			printf("\n");
			if (any_bridge_configured() || any_interface_configured())
				net_ifprint();
			if (cfg.defaultgw != 0)
				printf("Default gateway %d.%d.%d.%d\n", PRINT_IP(cfg.defaultgw));
			if (cfg.dns1 != 0)
				printf("DNS server %d.%d.%d.%d\n", PRINT_IP(cfg.dns1));
			if (cfg.dns2 != 0)
				printf("DNS server %d.%d.%d.%d\n", PRINT_IP(cfg.dns2));
			if (cfg.dns3 != 0)
				printf("DNS server %d.%d.%d.%d\n", PRINT_IP(cfg.dns3));
			printf("\n");
		}
	}
	
	fs_delete_cp_command();

	//****************************
	// set application environment
	//****************************
	prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // kill the child in case the parent died
	int cwd = 0;
	if (cfg.cwd) {
		if (chdir(cfg.cwd) == 0)
			cwd = 1;
	}
	
	if (!cwd) {
		if (chdir("/") < 0)
			errExit("chdir");
		if (cfg.homedir) {
			struct stat s;
			if (stat(cfg.homedir, &s) == 0) {
				/* coverity[toctou] */
				if (chdir(cfg.homedir) < 0)
					errExit("chdir");
			}
		}
	}
	
	// set environment
	env_defaults();
	
	// set user-supplied environment variables
	env_apply();

	// set nice
	if (arg_nice) {
		errno = 0;
		int rv = nice(cfg.nice);
		(void) rv;
		if (errno) {
			fprintf(stderr, "Warning: cannot set nice value\n");
			errno = 0;
		}
	}
	
	// clean /tmp/.X11-unix sockets
	fs_x11();
	
	//****************************
	// set security filters
	//****************************
	// set capabilities
	if (!arg_noroot)
		set_caps();

	// set rlimits
	set_rlimits();

	// set seccomp
#ifdef HAVE_SECCOMP
	// install protocol filter
	if (cfg.protocol) {
		protocol_filter();	// install filter	
		protocol_filter_save();	// save filter in PROTOCOL_CFG
	}

	// if a keep list is available, disregard the drop list
	if (arg_seccomp == 1) {
		if (cfg.seccomp_list_keep)
			seccomp_filter_keep();
		else if (cfg.seccomp_list_errno)
			seccomp_filter_errno(); 
		else
			seccomp_filter_drop(enforce_seccomp);
	}
#endif

	// set cpu affinity
	if (cfg.cpus) {
		save_cpu(); // save cpu affinity mask to CPU_CFG file
		set_cpu_affinity();
	}
	
	// save cgroup in CGROUP_CFG file
	if (cfg.cgroup)
		save_cgroup();

	//****************************************
	// drop privileges or create a new user namespace
	//****************************************
	save_nogroups();
	if (arg_noroot) {
		int rv = unshare(CLONE_NEWUSER);
		if (rv == -1) {
			fprintf(stderr, "Error: cannot mount a new user namespace\n");
			perror("unshare");
			drop_privs(arg_nogroups);
		}
	}
	else
		drop_privs(arg_nogroups);
 	
	// notify parent that new user namespace has been created so a proper
 	// UID/GID map can be setup
 	notify_other(child_to_parent_fds[1]);
 	close(child_to_parent_fds[1]);
 
 	// wait for parent to finish setting up a proper UID/GID map
 	wait_for_other(parent_to_child_fds[0]);
 	close(parent_to_child_fds[0]);

	// somehow, the new user namespace resets capabilities;
	// we need to do them again
	if (arg_noroot) {
		set_caps();
		if (arg_debug)
			printf("noroot user namespace installed\n");
	}


	//****************************************
	// fork the application and monitor it
	//****************************************
	pid_t app_pid = fork();
	if (app_pid == -1)
		errExit("fork");
		
	if (app_pid == 0) {
		prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); // kill the child in case the parent died
		start_application();	// start app
	}

	monitor_application(app_pid);	// monitor application
	
	return 0;
}
Пример #17
0
void join(pid_t pid, int argc, char **argv, int index) {
	EUID_ASSERT();

	pid_t parent = pid;
	// in case the pid is that of a firejail process, use the pid of the first child process
	pid = switch_to_child(pid);

	// now check if the pid belongs to a firejail sandbox
	if (invalid_sandbox(pid)) {
		fprintf(stderr, "Error: no valid sandbox\n");
		exit(1);
	}

	// 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 is denied to join a sandbox created by a different user.\n");
			exit(1);
		}
	}

	extract_x11_display(parent);

	EUID_ROOT();
	// in user mode set caps seccomp, cpu, cgroup, etc
	if (getuid() != 0) {
		extract_nonewprivs(pid);  // redundant on Linux >= 4.10; duplicated in function extract_caps
		extract_caps(pid);
		extract_cpu(pid);
		extract_cgroup(pid);
		extract_nogroups(pid);
		extract_user_namespace(pid);
	}

	// set cgroup
	if (cfg.cgroup)	// not available for uid 0
		set_cgroup(cfg.cgroup);

	// set umask, also uid 0
	extract_umask(pid);

	// join namespaces
	if (arg_join_network) {
		if (join_namespace(pid, "net"))
			exit(1);
	}
	else if (arg_join_filesystem) {
		if (join_namespace(pid, "mnt"))
			exit(1);
	}
	else {
		if (join_namespace(pid, "ipc") ||
		    join_namespace(pid, "net") ||
		    join_namespace(pid, "pid") ||
		    join_namespace(pid, "uts") ||
		    join_namespace(pid, "mnt"))
			exit(1);
	}

	pid_t child = fork();
	if (child < 0)
		errExit("fork");
	if (child == 0) {
		// drop discretionary access control capabilities for root sandboxes
		caps_drop_dac_override();

		// chroot into /proc/PID/root directory
		char *rootdir;
		if (asprintf(&rootdir, "/proc/%d/root", pid) == -1)
			errExit("asprintf");

		int rv;
		if (!arg_join_network) {
			rv = chroot(rootdir); // this will fail for processes in sandboxes not started with --chroot option
			if (rv == 0)
				printf("changing root to %s\n", rootdir);
		}

		EUID_USER();
		if (chdir("/") < 0)
			errExit("chdir");
		if (cfg.homedir) {
			struct stat s;
			if (stat(cfg.homedir, &s) == 0) {
				/* coverity[toctou] */
				if (chdir(cfg.homedir) < 0)
					errExit("chdir");
			}
		}

		// set caps filter
		EUID_ROOT();
		if (apply_caps == 1)	// not available for uid 0
			caps_set(caps);
#ifdef HAVE_SECCOMP
		if (getuid() != 0)
			seccomp_load_file_list();
#endif

		// mount user namespace or drop privileges
		if (arg_noroot) {	// not available for uid 0
			if (arg_debug)
				printf("Joining user namespace\n");
			if (join_namespace(1, "user"))
				exit(1);

			// user namespace resets capabilities
			// set caps filter
			if (apply_caps == 1)	// not available for uid 0
				caps_set(caps);
		}

		// set nonewprivs
		if (arg_nonewprivs == 1) {	// not available for uid 0
			int rv = prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
			if (arg_debug && rv == 0)
				printf("NO_NEW_PRIVS set\n");
		}

		EUID_USER();
		int cwd = 0;
		if (cfg.cwd) {
			if (chdir(cfg.cwd) == 0)
				cwd = 1;
		}

		if (!cwd) {
			if (chdir("/") < 0)
				errExit("chdir");
			if (cfg.homedir) {
				struct stat s;
				if (stat(cfg.homedir, &s) == 0) {
					/* coverity[toctou] */
					if (chdir(cfg.homedir) < 0)
						errExit("chdir");
				}
			}
		}

		// drop privileges
		drop_privs(arg_nogroups);

		// kill the child in case the parent died
		prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0);

		extract_command(argc, argv, index);
		if (cfg.command_line == NULL) {
			assert(cfg.shell);
			cfg.command_line = cfg.shell;
			cfg.window_title = cfg.shell;
		}
		if (arg_debug)
			printf("Extracted command #%s#\n", cfg.command_line);

		// set cpu affinity
		if (cfg.cpus)	// not available for uid 0
			set_cpu_affinity();

		// set nice value
		if (arg_nice)
			set_nice(cfg.nice);

		// add x11 display
		if (display) {
			char *display_str;
			if (asprintf(&display_str, ":%d", display) == -1)
				errExit("asprintf");
			setenv("DISPLAY", display_str, 1);
			free(display_str);
		}

		start_application(0, NULL);

		// it will never get here!!!
	}

	int status = 0;
	//*****************************
	// following code is signal-safe

	install_handler();

	// wait for the child to finish
	waitpid(child, &status, 0);

	// restore default signal action
	signal(SIGTERM, SIG_DFL);

	// end of signal-safe code
	//*****************************
	flush_stdin();

	if (WIFEXITED(status)) {
		status = WEXITSTATUS(status);
	} else if (WIFSIGNALED(status)) {
		status = WTERMSIG(status);
	} else {
		status = 0;
	}

	exit(status);
}
Пример #18
0
int main(int argc, char** argv)
{
    if (argc < 2) {
        std::cerr << "usage: " << argv[0] << " conf_file ..." << std::endl;
        return 0;
    }

    ///创建i_ini_file实例
    if (create_ini_file_instance(&g_p_ini_file)) {
        std::cerr << "create ini_file instance failed" << std::endl;
        return -1;
    }

    if (g_p_ini_file->init(argv[1]) < 0) {
        std::cerr << "ini_file init failed, err: " << g_p_ini_file->get_last_errstr() << std::endl;
        g_p_ini_file->release();
        g_p_ini_file = NULL;
        return -1;
    }

    ///开启精灵模式
    if (daemon_start(argc, argv, g_p_ini_file) < 0) {
        return -1;
    }

    ///初始化日志系统
    if (log_init(g_p_ini_file) < 0) {
        return -1;
    }

    ///读取dll中函数接口
    char path[PATH_MAX] = {0};
    if (g_p_ini_file->read_string("WorkInfo", "dll", path, sizeof(path), NULL)) {
        ERROR_LOG("fail to read dll_path from conf_file");
        return -1;
    }

    g_dll_inst.set_dll_path(path);
    if (g_dll_inst.register_plugin() < 0) {
        ERROR_LOG("fail to register dll");
        return -1;
    }

    ///读取bind_file中的内容
    if (g_p_ini_file->read_string("WorkInfo", "bind_file", path, sizeof(path), NULL)) {
        ERROR_LOG("fail to read bind_file path from conf_file");
        return -1;
    }

    std::list<bind_conf_t> bind_conf_list;
    bind_conf bind_conf_inst(path);
    if (bind_conf_inst.load_bind_conf(bind_conf_list) < 0) {
        ERROR_LOG("fail to read info from bind_file");
        return -1;
    }

    ///初始化注册回调函数
    tcp_io_event tcp_io_event_inst;
    udp_io_event udp_io_event_inst;

    if (g_dll_inst.proc_pkg_from_client)
        tcp_io_event_inst.set_tcp_proc_callback(g_dll_inst.proc_pkg_from_client);
    if (g_dll_inst.get_pkg_len)
        tcp_io_event_inst.set_tcp_pkg_len_callback(g_dll_inst.get_pkg_len);
    if (g_dll_inst.on_client_conn_closed)
        tcp_io_event_inst.set_tcp_close_callback(g_dll_inst.on_client_conn_closed);

    if (g_dll_inst.proc_udp_pkg_from_client)
        udp_io_event_inst.set_udp_proc_callback(g_dll_inst.proc_udp_pkg_from_client);
    if (g_dll_inst.on_client_conn_closed)
        udp_io_event_inst.set_udp_close_conn_callback(g_dll_inst.on_client_conn_closed);

    ///初始化网络监听

    std::list<bind_conf_t>::iterator it = bind_conf_list.begin();
    for (; it != bind_conf_list.end(); ++it) {
            inet_address serv_addr;
#ifdef _IPV6
            if (it->ip_addr == "0:0:0:0:0:0:0:0"
                    || ip->ip_addr == "::"
                    || ip->ip_addr == "::/128") {
                serv_addr.set_port(it->port);
            } else {
                serv_addr.set_ip_addr(it->ip_addr);
                serv_addr.set_port(it->port);
            }
#else
            if (it->ip_addr == "0.0.0.0") {
                serv_addr.set_port(it->port);
            } else {
                serv_addr.set_ip_addr(it->ip_addr);
                serv_addr.set_port(it->port);
            }
#endif

        if (it->type == TYPE_TCP) {
            acceptor<connection<sock_stream>, sock_acceptor>* p_acceptor =
                new (std::nothrow) acceptor<connection<sock_stream>, sock_acceptor>(serv_addr);
            if (!p_acceptor) {
                ERROR_LOG("tcp acceptor instantiate failed");
                return -1;
            }

            p_acceptor->set_new_conn_callback(
                    boost::bind(&tcp_io_event::tcp_on_new_conn, &tcp_io_event_inst, _1));
            p_acceptor->set_on_message_callback(
                    boost::bind(&tcp_io_event::tcp_on_message, &tcp_io_event_inst, _1, _2, _3));
            //p_acceptor->set_on_write_comple_callback(
            //        boost::bind(&tcp_io_event::tcp_on_write_complete, &tcp_io_event_inst, _1));
            p_acceptor->set_on_close_callback(
                    boost::bind(&tcp_io_event::tcp_on_close_conn, &tcp_io_event_inst, _1));

            if (p_acceptor->start() < 0) {
                return -1;
            }
            g_tcp_acceptor_list.push_back(p_acceptor);

        } else {
            acceptor<connection<sock_dgram>, sock_dgram>* p_acceptor =
                new (std::nothrow) acceptor<connection<sock_dgram>, sock_dgram>(serv_addr);
            if (!p_acceptor) {
                ERROR_LOG("udp acceptor instantiate failed");
                return -1;
            }

            p_acceptor->set_new_conn_callback(
                    boost::bind(&udp_io_event::udp_on_new_conn, &udp_io_event_inst, _1));
            p_acceptor->set_on_message_callback(
                    boost::bind(&udp_io_event::udp_on_message, &udp_io_event_inst, _1, _2, _3));
            //p_acceptor->set_on_write_comple_callback(
            //        boost::bind(&udp_io_event::udp_on_write_comple, &udp_io_event_inst, _1));
            p_acceptor->set_on_close_callback(
                    boost::bind(&udp_io_event::udp_on_close_conn, &udp_io_event_inst, _1));

            if (p_acceptor->start() < 0) {
                return -1;
            }

            g_udp_acceptor_list.push_back(p_acceptor);
        }
    }


    ///创建socketpair
    g_work_num = g_p_ini_file->read_int("WorkInfo", "worker_num", 1);
    for (int i = 0; i < g_work_num; i++) {
        connections_pool<connection<vpipe_sockpair> >* p_pool =
            connections_pool<connection<vpipe_sockpair> >::instance();
        assert(p_pool);
        connection<vpipe_sockpair>* p_conn = p_pool->get_new_connection();
        assert(p_conn);
        if ((p_conn->get_ipc_conn())->open() < 0) {
            return -1;
        }

        worker_proc_t tmp;
        tmp.id = i;
        tmp.worker_pid = 0;
        tmp.p_sockpair = p_conn;

        g_worker_proc_vec.push_back(tmp);
    }

    if (g_dll_inst.init_service
            && g_dll_inst.init_service(g_saved_argc, g_saved_argv, PROC_MAIN) != 0) {
        ERROR_LOG("main proc init_service failed");
        return -1;
    }

    daemon_set_title("%s-[%s]", g_prog_name, "master");

    ///fork工作进程
    for (int i = 0; i < g_work_num; i++) {
        pid_t pid = fork();
        switch (pid) {
            case -1:
                ERROR_LOG("fork failed, err: %s", strerror(errno));
                return -1;
            case 0:
                ///子进程
                worker_proc_loop(i);
            default:
                ///master进程
                g_worker_proc_vec[i].worker_pid = pid;
                break;
        }
    }

    ///设置work进程cpu亲和性
    for (int i = 0; i < g_work_num; i++) {
        if (set_cpu_affinity(g_work_num,
                             g_worker_proc_vec[i].worker_pid,
                             g_worker_proc_vec[i].id) < 0) {
            DEBUG_LOG("set_cpu_affinity failed, err: %s", strerror(errno));
        }
    }

    master_proc_loop();
    daemon_stop();

    if (g_p_ini_file) {
        g_p_ini_file->uninit();
        g_p_ini_file->release();
        g_p_ini_file = NULL;
    }

    return 0;
}
Пример #19
0
int main(int argc, char **argv)
{
	int status;
	struct sched_param thread_param;
	int i;
	int retval = FAILURE;
	int core;
	int nthreads;

	/* Make sure we see all message, even those on stdout.  */
	setvbuf(stdout, NULL, _IONBF, 0);

	/* get the number of processors */
	num_processors = sysconf(_SC_NPROCESSORS_ONLN);

	/* calculate the number of inversion groups to run */
	ngroups = num_processors == 1 ? 1 : num_processors - 1;

	/* process command line arguments */
	process_command_line(argc, argv);

	/* lock memory */
	if (lockall)
		if (mlockall(MCL_CURRENT | MCL_FUTURE) == -1) {
			error("mlockall failed\n");
			return FAILURE;
		}
	/* boost main's priority (so we keep running) :) */
	prio_min = sched_get_priority_min(policy);
	thread_param.sched_priority = MAIN_PRIO();
	status = pthread_setschedparam(pthread_self(), policy, &thread_param);
	if (status) {
		error("main: boosting to max priority: 0x%x\n", status);
		return FAILURE;
	}
	/* block unwanted signals */
	block_signals();

	/* allocate our groups array */
	groups = calloc(ngroups, sizeof(struct group_parameters));
	if (groups == NULL) {
		error("main: failed to allocate %d groups\n", ngroups);
		return FAILURE;
	}
	/* set up CPU affinity masks */
	if (set_cpu_affinity(&test_cpu_mask, &admin_cpu_mask))
		return FAILURE;

	nthreads = ngroups * NUM_TEST_THREADS + NUM_ADMIN_THREADS;

	/* set up our ready barrier */
	if (barrier_init(&all_threads_ready, NULL, nthreads,
			 "all_threads_ready"))
		return FAILURE;

	/* set up our done barrier */
	if (barrier_init(&all_threads_done, NULL, nthreads, "all_threads_done"))
		return FAILURE;

	/* create the groups */
	info("Creating %d test groups\n", ngroups);
	for (core = 0; core < num_processors; core++)
		if (CPU_ISSET(core, &test_cpu_mask))
			break;
	for (i = 0; i < ngroups; i++) {
		groups[i].id = i;
		groups[i].cpu = core++;
		if (core >= num_processors)
			core = 0;
		if (create_group(&groups[i]) != SUCCESS)
			return FAILURE;
	}

	/* prompt if requested */
	if (prompt) {
		printf("Press return to start test: ");
		getchar();
	}
	/* report */
	banner();
	start = time(NULL);

	/* turn loose the threads */
	info("Releasing all threads\n");
	status = pthread_barrier_wait(&all_threads_ready);
	if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) {
		error("main: pthread_barrier_wait(all_threads_ready): 0x%x\n",
		      status);
		set_shutdown_flag();
		return FAILURE;
	}

	reporter(NULL);

	if (!quiet) {
		fputs(DOWN_ONE, stdout);
		printf("Stopping test\n");
	}
	set_shutdown_flag();

	/* wait for all threads to notice the shutdown flag */
	if (have_errors == 0 && interrupted == 0) {
		info("waiting for all threads to complete\n");
		status = pthread_barrier_wait(&all_threads_done);
		if (status && status != PTHREAD_BARRIER_SERIAL_THREAD) {
			error
			    ("main: pthread_barrier_wait(all_threads_ready): 0x%x\n",
			     status);
			return FAILURE;
		}
		info("All threads terminated!\n");
		retval = SUCCESS;
	} else
		kill(0, SIGTERM);
	finish = time(NULL);
	summary();
	if (lockall)
		munlockall();
	exit(retval);
}
Пример #20
0
int main(int argc, char **argv)
{
	int c, i, j, opt_index;
	char *ptr;
	bool prio_high = false;
	struct mode mode;
	void (*enter_mode)(struct mode *mode) = NULL;

	check_for_root_maybe_die();

	memset(&mode, 0, sizeof(mode));
	mode.link_type = LINKTYPE_EN10MB;
	mode.print_mode = FNTTYPE_PRINT_NORM;
	mode.cpu = CPU_UNKNOWN;
	mode.packet_type = PACKET_ALL;
	mode.promiscuous = true;
	mode.randomize = false;
	mode.pcap = PCAP_OPS_SG;
	mode.dump_interval = DUMP_INTERVAL;

	while ((c = getopt_long(argc, argv, short_options, long_options,
	       &opt_index)) != EOF) {
		switch (c) {
		case 'd':
		case 'i':
			mode.device_in = xstrdup(optarg);
			break;
		case 'o':
			mode.device_out = xstrdup(optarg);
			break;
		case 'r':
			mode.randomize = true;
			break;
		case 'J':
			mode.jumbo_support = 1;
			break;
		case 'f':
			mode.filter = xstrdup(optarg);
			break;
		case 'M':
			mode.promiscuous = false;
			break;
		case 't':
			if (!strncmp(optarg, "host", strlen("host")))
				mode.packet_type = PACKET_HOST;
			else if (!strncmp(optarg, "broadcast", strlen("broadcast")))
				mode.packet_type = PACKET_BROADCAST;
			else if (!strncmp(optarg, "multicast", strlen("multicast")))
				mode.packet_type = PACKET_MULTICAST;
			else if (!strncmp(optarg, "others", strlen("others")))
				mode.packet_type = PACKET_OTHERHOST;
			else if (!strncmp(optarg, "outgoing", strlen("outgoing")))
				mode.packet_type = PACKET_OUTGOING;
			else
				mode.packet_type = PACKET_ALL;
			break;
		case 'S':
			ptr = optarg;
			mode.reserve_size = 0;

			for (j = i = strlen(optarg); i > 0; --i) {
				if (!isdigit(optarg[j - i]))
					break;
				ptr++;
			}

			if (!strncmp(ptr, "KB", strlen("KB")))
				mode.reserve_size = 1 << 10;
			else if (!strncmp(ptr, "MB", strlen("MB")))
				mode.reserve_size = 1 << 20;
			else if (!strncmp(ptr, "GB", strlen("GB")))
				mode.reserve_size = 1 << 30;
			else
				panic("Syntax error in ring size param!\n");

			*ptr = 0;
			mode.reserve_size *= atoi(optarg);
			break;
		case 'b':
			set_cpu_affinity(optarg, 0);
			if (mode.cpu != CPU_NOTOUCH)
				mode.cpu = atoi(optarg);
			break;
		case 'B':
			set_cpu_affinity(optarg, 1);
			break;
		case 'H':
			prio_high = true;
			break;
		case 'c':
			mode.pcap = PCAP_OPS_RW;
			break;
		case 'm':
			mode.pcap = PCAP_OPS_MMAP;
			break;
		case 'Q':
			mode.cpu = CPU_NOTOUCH;
			break;
		case 's':
			mode.print_mode = FNTTYPE_PRINT_NONE;
			break;
		case 'q':
			mode.print_mode = FNTTYPE_PRINT_LESS;
			break;
		case 'l':
			mode.print_mode = FNTTYPE_PRINT_CHR1;
			break;
		case 'x':
			mode.print_mode = FNTTYPE_PRINT_HEX1;
			break;
		case 'C':
			mode.print_mode = FNTTYPE_PRINT_PAAC;
			break;
		case 'X':
			mode.print_mode = FNTTYPE_PRINT_HEX2;
			break;
		case 'N':
			mode.print_mode = FNTTYPE_PRINT_NOPA;
			break;
		case 'k':
			mode.kpull = (unsigned long) atol(optarg);
			break;
		case 'n':
			frame_cnt_max = (unsigned long) atol(optarg);
			break;
		case 'F':
			mode.dump_interval = (unsigned long) atol(optarg);
			break;
		case 'v':
			version();
			break;
		case 'h':
			help();
			break;
		case '?':
			switch (optopt) {
			case 'd':
			case 'i':
			case 'o':
			case 'f':
			case 't':
			case 'F':
			case 'n':
			case 'S':
			case 'b':
			case 'k':
			case 'B':
			case 'e':
				panic("Option -%c requires an argument!\n",
				      optopt);
			default:
				if (isprint(optopt))
					whine("Unknown option character "
					      "`0x%X\'!\n", optopt);
				die();
			}
		default:
			break;
		}
	}

	if (!mode.device_in)
		mode.device_in = xstrdup("any");

	register_signal(SIGINT, signal_handler);
	register_signal(SIGHUP, signal_handler);

	init_pcap(mode.jumbo_support);
	tprintf_init();
	header();

	if (prio_high == true) {
		set_proc_prio(get_default_proc_prio());
		set_sched_status(get_default_sched_policy(),
				 get_default_sched_prio());
	}

	if (mode.device_in && (device_mtu(mode.device_in) ||
	    !strncmp("any", mode.device_in, strlen(mode.device_in)))) {
		if (!mode.device_out) {
			mode.dump = 0;
			enter_mode = enter_mode_rx_only_or_dump;
		} else if (device_mtu(mode.device_out)) {
			register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO);
			enter_mode = enter_mode_rx_to_tx;
		} else {
			mode.dump = 1;
			register_signal_f(SIGALRM, timer_next_dump, SA_SIGINFO);
			enter_mode = enter_mode_rx_only_or_dump;
		}
	} else {
		if (mode.device_out && device_mtu(mode.device_out)) {
			register_signal_f(SIGALRM, timer_elapsed, SA_SIGINFO);
			enter_mode = enter_mode_pcap_to_tx;
		} else {
			enter_mode = enter_mode_read_pcap;
		}
	}

	if (!enter_mode)
		panic("Selection not supported!\n");
	enter_mode(&mode);

	tprintf_cleanup();
	cleanup_pcap();

	if (mode.device_in)
		xfree(mode.device_in);
	if (mode.device_out)
		xfree(mode.device_out);
	return 0;
}
Пример #21
0
int hashcat_session_init (hashcat_ctx_t *hashcat_ctx, const char *install_folder, const char *shared_folder, int argc, char **argv, const int comptime)
{
  user_options_t *user_options = hashcat_ctx->user_options;

  /**
   * make it a bit more comfortable to use some of the special modes in hashcat
   */

  user_options_session_auto (hashcat_ctx);

  /**
   * event init (needed for logging so should be first)
   */

  const int rc_event_init = event_ctx_init (hashcat_ctx);

  if (rc_event_init == -1) return -1;

  /**
   * status init
   */

  const int rc_status_init = status_ctx_init (hashcat_ctx);

  if (rc_status_init == -1) return -1;

  /**
   * folder
   */

  const int rc_folder_config_init = folder_config_init (hashcat_ctx, install_folder, shared_folder);

  if (rc_folder_config_init == -1) return -1;

  /**
   * pidfile
   */

  const int rc_pidfile_init = pidfile_ctx_init (hashcat_ctx);

  if (rc_pidfile_init == -1) return -1;

  /**
   * restore
   */

  const int rc_restore_init = restore_ctx_init (hashcat_ctx, argc, argv);

  if (rc_restore_init == -1) return -1;

  /**
   * process user input
   */

  user_options_preprocess (hashcat_ctx);

  user_options_extra_init (hashcat_ctx);

  user_options_postprocess (hashcat_ctx);

  /**
   * logfile
   */

  const int rc_logfile_init = logfile_init (hashcat_ctx);

  if (rc_logfile_init == -1) return -1;

  /**
   * cpu affinity
   */

  const int rc_affinity = set_cpu_affinity (hashcat_ctx);

  if (rc_affinity == -1) return -1;

  /**
   * prepare seeding for random number generator, required by logfile and rules generator
   */

  setup_seeding (user_options->rp_gen_seed_chgd, user_options->rp_gen_seed);

  /**
   * To help users a bit
   */

  setup_environment_variables ();

  setup_umask ();

  /**
   * tuning db
   */

  const int rc_tuning_db = tuning_db_init (hashcat_ctx);

  if (rc_tuning_db == -1) return -1;

  /**
   * induction directory
   */

  const int rc_induct_ctx_init = induct_ctx_init (hashcat_ctx);

  if (rc_induct_ctx_init == -1) return -1;

  /**
   * outfile-check directory
   */

  const int rc_outcheck_ctx_init = outcheck_ctx_init (hashcat_ctx);

  if (rc_outcheck_ctx_init == -1) return -1;

  /**
   * outfile itself
   */

  const int rc_outfile_init = outfile_init (hashcat_ctx);

  if (rc_outfile_init == -1) return -1;

  /**
   * potfile init
   * this is only setting path because potfile can be used in read and write mode depending on user options
   * plus it depends on hash_mode, so we continue using it in outer_loop
   */

  const int rc_potfile_init = potfile_init (hashcat_ctx);

  if (rc_potfile_init == -1) return -1;

  /**
   * dictstat init
   */

  const int rc_dictstat_init = dictstat_init (hashcat_ctx);

  if (rc_dictstat_init == -1) return -1;

  /**
   * loopback init
   */

  const int rc_loopback_init = loopback_init (hashcat_ctx);

  if (rc_loopback_init == -1) return -1;

  /**
   * debugfile init
   */

  const int rc_debugfile_init = debugfile_init (hashcat_ctx);

  if (rc_debugfile_init == -1) return -1;

  /**
   * Try to detect if all the files we're going to use are accessible in the mode we want them
   */

  const int rc_user_options_check_files = user_options_check_files (hashcat_ctx);

  if (rc_user_options_check_files == -1) return -1;

  /**
   * Init OpenCL library loader
   */

  const int rc_opencl_init = opencl_ctx_init (hashcat_ctx);

  if (rc_opencl_init == -1) return -1;

  /**
   * Init OpenCL devices
   */

  const int rc_devices_init = opencl_ctx_devices_init (hashcat_ctx, comptime);

  if (rc_devices_init == -1) return -1;

  /**
   * HM devices: init
   */

  const int rc_hwmon_init = hwmon_ctx_init (hashcat_ctx);

  if (rc_hwmon_init == -1) return -1;

  // done

  return 0;
}