Changeset View
Changeset View
Standalone View
Standalone View
usr.sbin/jail/command.c
Show All 24 Lines | |||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||||
* SUCH DAMAGE. | * SUCH DAMAGE. | ||||
*/ | */ | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <sys/cpuset.h> | |||||
#include <sys/event.h> | #include <sys/event.h> | ||||
#include <sys/mount.h> | #include <sys/mount.h> | ||||
#include <sys/stat.h> | #include <sys/stat.h> | ||||
#include <sys/sysctl.h> | #include <sys/sysctl.h> | ||||
#include <sys/user.h> | #include <sys/user.h> | ||||
#include <sys/wait.h> | #include <sys/wait.h> | ||||
#include <err.h> | #include <err.h> | ||||
Show All 38 Lines | static int check_path(struct cfjail *j, const char *pname, const char *path, | ||||
int isfile, const char *umount_type); | int isfile, const char *umount_type); | ||||
static struct cfjails sleeping = TAILQ_HEAD_INITIALIZER(sleeping); | static struct cfjails sleeping = TAILQ_HEAD_INITIALIZER(sleeping); | ||||
static struct cfjails runnable = TAILQ_HEAD_INITIALIZER(runnable); | static struct cfjails runnable = TAILQ_HEAD_INITIALIZER(runnable); | ||||
static struct cfstring dummystring = { .len = 1 }; | static struct cfstring dummystring = { .len = 1 }; | ||||
static struct phhead phash[PHASH_SIZE]; | static struct phhead phash[PHASH_SIZE]; | ||||
static int kq; | static int kq; | ||||
static cpusetid_t | |||||
root_cpuset_id(void) | |||||
{ | |||||
static cpusetid_t setid = CPUSET_INVALID; | |||||
static int error; | |||||
/* Only try to get the cpuset once. */ | |||||
if (error == 0 && setid == CPUSET_INVALID) | |||||
error = cpuset_getid(CPU_LEVEL_ROOT, CPU_WHICH_PID, -1, &setid); | |||||
if (error != 0) | |||||
return (CPUSET_INVALID); | |||||
return (setid); | |||||
} | |||||
/* | /* | ||||
* Run the next command associated with a jail. | * Run the next command associated with a jail. | ||||
*/ | */ | ||||
int | int | ||||
next_command(struct cfjail *j) | next_command(struct cfjail *j) | ||||
{ | { | ||||
enum intparam comparam; | enum intparam comparam; | ||||
int create_failed, stopping; | int create_failed, stopping; | ||||
▲ Show 20 Lines • Show All 183 Lines • ▼ Show 20 Lines | run_command(struct cfjail *j) | ||||
const struct cfstring *comstring, *s; | const struct cfstring *comstring, *s; | ||||
login_cap_t *lcap; | login_cap_t *lcap; | ||||
const char **argv; | const char **argv; | ||||
char *acs, *cs, *comcs, *devpath; | char *acs, *cs, *comcs, *devpath; | ||||
const char *jidstr, *conslog, *path, *ruleset, *term, *username; | const char *jidstr, *conslog, *path, *ruleset, *term, *username; | ||||
enum intparam comparam; | enum intparam comparam; | ||||
size_t comlen; | size_t comlen; | ||||
pid_t pid; | pid_t pid; | ||||
cpusetid_t setid; | |||||
int argc, bg, clean, consfd, down, fib, i, injail, sjuser, timeout; | int argc, bg, clean, consfd, down, fib, i, injail, sjuser, timeout; | ||||
#if defined(INET) || defined(INET6) | #if defined(INET) || defined(INET6) | ||||
char *addr, *extrap, *p, *val; | char *addr, *extrap, *p, *val; | ||||
#endif | #endif | ||||
static char *cleanenv; | static char *cleanenv; | ||||
/* Perform some operations that aren't actually commands */ | /* Perform some operations that aren't actually commands */ | ||||
▲ Show 20 Lines • Show All 333 Lines • ▼ Show 20 Lines | if (int_param(j->intparams[IP_EXEC_TIMEOUT], &timeout) && | ||||
timeout != 0) { | timeout != 0) { | ||||
clock_gettime(CLOCK_REALTIME, &j->timeout); | clock_gettime(CLOCK_REALTIME, &j->timeout); | ||||
j->timeout.tv_sec += timeout; | j->timeout.tv_sec += timeout; | ||||
} else | } else | ||||
j->timeout.tv_sec = 0; | j->timeout.tv_sec = 0; | ||||
injail = comparam == IP_EXEC_START || comparam == IP_COMMAND || | injail = comparam == IP_EXEC_START || comparam == IP_COMMAND || | ||||
comparam == IP_EXEC_STOP; | comparam == IP_EXEC_STOP; | ||||
if (injail) | |||||
setid = root_cpuset_id(); | |||||
else | |||||
setid = CPUSET_INVALID; | |||||
clean = bool_param(j->intparams[IP_EXEC_CLEAN]); | clean = bool_param(j->intparams[IP_EXEC_CLEAN]); | ||||
username = string_param(j->intparams[injail | username = string_param(j->intparams[injail | ||||
? IP_EXEC_JAIL_USER : IP_EXEC_SYSTEM_USER]); | ? IP_EXEC_JAIL_USER : IP_EXEC_SYSTEM_USER]); | ||||
sjuser = bool_param(j->intparams[IP_EXEC_SYSTEM_JAIL_USER]); | sjuser = bool_param(j->intparams[IP_EXEC_SYSTEM_JAIL_USER]); | ||||
consfd = 0; | consfd = 0; | ||||
if (injail && | if (injail && | ||||
(conslog = string_param(j->intparams[IP_EXEC_CONSOLELOG]))) { | (conslog = string_param(j->intparams[IP_EXEC_CONSOLELOG]))) { | ||||
▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | if (path && chdir(path) < 0) { | ||||
jail_warnx(j, "chdir %s: %s", path, strerror(errno)); | jail_warnx(j, "chdir %s: %s", path, strerror(errno)); | ||||
exit(1); | exit(1); | ||||
} | } | ||||
if (int_param(j->intparams[IP_EXEC_FIB], &fib) && | if (int_param(j->intparams[IP_EXEC_FIB], &fib) && | ||||
setfib(fib) < 0) { | setfib(fib) < 0) { | ||||
jail_warnx(j, "setfib: %s", strerror(errno)); | jail_warnx(j, "setfib: %s", strerror(errno)); | ||||
exit(1); | exit(1); | ||||
} | } | ||||
/* | |||||
* We wouldn't have specialized our affinity, so just setid to | |||||
* root. We do this prior to attaching to avoid the kernel | |||||
* having to create a transient cpuset that we'll promptly | |||||
* free up with a reset to the jail's cpuset. | |||||
* | |||||
* This is just a best-effort to use as wide of mask as | |||||
* possible. | |||||
*/ | |||||
if (setid != CPUSET_INVALID) | |||||
(void)cpuset_setid(CPU_WHICH_PID, -1, setid); | |||||
if (jail_attach(j->jid) < 0) { | if (jail_attach(j->jid) < 0) { | ||||
jail_warnx(j, "jail_attach: %s", strerror(errno)); | jail_warnx(j, "jail_attach: %s", strerror(errno)); | ||||
exit(1); | exit(1); | ||||
} | } | ||||
} | } | ||||
if (clean || username) { | if (clean || username) { | ||||
if (!(injail && sjuser) && | if (!(injail && sjuser) && | ||||
get_user_info(j, username, &pwd, &lcap) < 0) | get_user_info(j, username, &pwd, &lcap) < 0) | ||||
▲ Show 20 Lines • Show All 287 Lines • Show Last 20 Lines |