Changeset View
Changeset View
Standalone View
Standalone View
sys/kern/kern_procctl.c
Show All 28 Lines | |||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
__FBSDID("$FreeBSD$"); | __FBSDID("$FreeBSD$"); | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/systm.h> | #include <sys/systm.h> | ||||
#include <sys/capsicum.h> | #include <sys/capsicum.h> | ||||
#include <sys/lock.h> | #include <sys/lock.h> | ||||
#include <sys/mman.h> | |||||
#include <sys/mutex.h> | #include <sys/mutex.h> | ||||
#include <sys/priv.h> | #include <sys/priv.h> | ||||
#include <sys/proc.h> | #include <sys/proc.h> | ||||
#include <sys/procctl.h> | #include <sys/procctl.h> | ||||
#include <sys/sx.h> | #include <sys/sx.h> | ||||
#include <sys/syscallsubr.h> | #include <sys/syscallsubr.h> | ||||
#include <sys/sysproto.h> | #include <sys/sysproto.h> | ||||
#include <sys/wait.h> | #include <sys/wait.h> | ||||
▲ Show 20 Lines • Show All 369 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
*data = (p->p_flag2 & P2_TRAPCAP) != 0 ? PROC_TRAPCAP_CTL_ENABLE : | *data = (p->p_flag2 & P2_TRAPCAP) != 0 ? PROC_TRAPCAP_CTL_ENABLE : | ||||
PROC_TRAPCAP_CTL_DISABLE; | PROC_TRAPCAP_CTL_DISABLE; | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
protmax_ctl(struct thread *td, struct proc *p, int state) | |||||
{ | |||||
PROC_LOCK_ASSERT(p, MA_OWNED); | |||||
switch (state) { | |||||
case PROC_PROTMAX_FORCE_ENABLE: | |||||
p->p_flag2 &= ~P2_PROTMAX_DISABLE; | |||||
p->p_flag2 |= P2_PROTMAX_ENABLE; | |||||
break; | |||||
case PROC_PROTMAX_FORCE_DISABLE: | |||||
p->p_flag2 |= P2_PROTMAX_DISABLE; | |||||
p->p_flag2 &= ~P2_PROTMAX_ENABLE; | |||||
break; | |||||
case PROC_PROTMAX_NOFORCE: | |||||
p->p_flag2 &= ~(P2_PROTMAX_ENABLE | P2_PROTMAX_DISABLE); | |||||
break; | |||||
default: | |||||
return (EINVAL); | |||||
} | |||||
return (0); | |||||
} | |||||
static int | |||||
protmax_status(struct thread *td, struct proc *p, int *data) | |||||
{ | |||||
int d; | |||||
switch (p->p_flag2 & (P2_PROTMAX_ENABLE | P2_PROTMAX_DISABLE)) { | |||||
case 0: | |||||
d = PROC_ASLR_NOFORCE; | |||||
break; | |||||
case P2_PROTMAX_ENABLE: | |||||
d = PROC_PROTMAX_FORCE_ENABLE; | |||||
break; | |||||
case P2_PROTMAX_DISABLE: | |||||
d = PROC_PROTMAX_FORCE_DISABLE; | |||||
break; | |||||
} | |||||
if (kern_mmap_maxprot(p, PROT_READ) == PROT_READ) | |||||
d |= PROC_PROTMAX_ACTIVE; | |||||
*data = d; | |||||
return (0); | |||||
} | |||||
static int | |||||
aslr_ctl(struct thread *td, struct proc *p, int state) | aslr_ctl(struct thread *td, struct proc *p, int state) | ||||
{ | { | ||||
PROC_LOCK_ASSERT(p, MA_OWNED); | PROC_LOCK_ASSERT(p, MA_OWNED); | ||||
switch (state) { | switch (state) { | ||||
case PROC_ASLR_FORCE_ENABLE: | case PROC_ASLR_FORCE_ENABLE: | ||||
p->p_flag2 &= ~P2_ASLR_DISABLE; | p->p_flag2 &= ~P2_ASLR_DISABLE; | ||||
▲ Show 20 Lines • Show All 65 Lines • ▼ Show 20 Lines | sys_procctl(struct thread *td, struct procctl_args *uap) | ||||
int error, error1, flags, signum; | int error, error1, flags, signum; | ||||
if (uap->com >= PROC_PROCCTL_MD_MIN) | if (uap->com >= PROC_PROCCTL_MD_MIN) | ||||
return (cpu_procctl(td, uap->idtype, uap->id, | return (cpu_procctl(td, uap->idtype, uap->id, | ||||
uap->com, uap->data)); | uap->com, uap->data)); | ||||
switch (uap->com) { | switch (uap->com) { | ||||
case PROC_ASLR_CTL: | case PROC_ASLR_CTL: | ||||
case PROC_PROTMAX_CTL: | |||||
case PROC_SPROTECT: | case PROC_SPROTECT: | ||||
case PROC_TRACE_CTL: | case PROC_TRACE_CTL: | ||||
case PROC_TRAPCAP_CTL: | case PROC_TRAPCAP_CTL: | ||||
error = copyin(uap->data, &flags, sizeof(flags)); | error = copyin(uap->data, &flags, sizeof(flags)); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
data = &flags; | data = &flags; | ||||
break; | break; | ||||
Show All 14 Lines | case PROC_REAP_GETPIDS: | ||||
break; | break; | ||||
case PROC_REAP_KILL: | case PROC_REAP_KILL: | ||||
error = copyin(uap->data, &x.rk, sizeof(x.rk)); | error = copyin(uap->data, &x.rk, sizeof(x.rk)); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
data = &x.rk; | data = &x.rk; | ||||
break; | break; | ||||
case PROC_ASLR_STATUS: | case PROC_ASLR_STATUS: | ||||
case PROC_PROTMAX_STATUS: | |||||
case PROC_TRACE_STATUS: | case PROC_TRACE_STATUS: | ||||
case PROC_TRAPCAP_STATUS: | case PROC_TRAPCAP_STATUS: | ||||
data = &flags; | data = &flags; | ||||
break; | break; | ||||
case PROC_PDEATHSIG_CTL: | case PROC_PDEATHSIG_CTL: | ||||
error = copyin(uap->data, &signum, sizeof(signum)); | error = copyin(uap->data, &signum, sizeof(signum)); | ||||
if (error != 0) | if (error != 0) | ||||
return (error); | return (error); | ||||
Show All 12 Lines | if (error == 0) | ||||
error = copyout(&x.rs, uap->data, sizeof(x.rs)); | error = copyout(&x.rs, uap->data, sizeof(x.rs)); | ||||
break; | break; | ||||
case PROC_REAP_KILL: | case PROC_REAP_KILL: | ||||
error1 = copyout(&x.rk, uap->data, sizeof(x.rk)); | error1 = copyout(&x.rk, uap->data, sizeof(x.rk)); | ||||
if (error == 0) | if (error == 0) | ||||
error = error1; | error = error1; | ||||
break; | break; | ||||
case PROC_ASLR_STATUS: | case PROC_ASLR_STATUS: | ||||
case PROC_PROTMAX_STATUS: | |||||
case PROC_TRACE_STATUS: | case PROC_TRACE_STATUS: | ||||
case PROC_TRAPCAP_STATUS: | case PROC_TRAPCAP_STATUS: | ||||
if (error == 0) | if (error == 0) | ||||
error = copyout(&flags, uap->data, sizeof(flags)); | error = copyout(&flags, uap->data, sizeof(flags)); | ||||
break; | break; | ||||
case PROC_PDEATHSIG_STATUS: | case PROC_PDEATHSIG_STATUS: | ||||
if (error == 0) | if (error == 0) | ||||
error = copyout(&signum, uap->data, sizeof(signum)); | error = copyout(&signum, uap->data, sizeof(signum)); | ||||
Show All 9 Lines | kern_procctl_single(struct thread *td, struct proc *p, int com, void *data) | ||||
PROC_LOCK_ASSERT(p, MA_OWNED); | PROC_LOCK_ASSERT(p, MA_OWNED); | ||||
switch (com) { | switch (com) { | ||||
case PROC_ASLR_CTL: | case PROC_ASLR_CTL: | ||||
return (aslr_ctl(td, p, *(int *)data)); | return (aslr_ctl(td, p, *(int *)data)); | ||||
case PROC_ASLR_STATUS: | case PROC_ASLR_STATUS: | ||||
return (aslr_status(td, p, data)); | return (aslr_status(td, p, data)); | ||||
case PROC_SPROTECT: | case PROC_SPROTECT: | ||||
return (protect_set(td, p, *(int *)data)); | return (protect_set(td, p, *(int *)data)); | ||||
case PROC_PROTMAX_CTL: | |||||
return (protmax_ctl(td, p, *(int *)data)); | |||||
case PROC_PROTMAX_STATUS: | |||||
return (protmax_status(td, p, data)); | |||||
case PROC_REAP_ACQUIRE: | case PROC_REAP_ACQUIRE: | ||||
return (reap_acquire(td, p)); | return (reap_acquire(td, p)); | ||||
case PROC_REAP_RELEASE: | case PROC_REAP_RELEASE: | ||||
return (reap_release(td, p)); | return (reap_release(td, p)); | ||||
case PROC_REAP_STATUS: | case PROC_REAP_STATUS: | ||||
return (reap_status(td, p, data)); | return (reap_status(td, p, data)); | ||||
case PROC_REAP_GETPIDS: | case PROC_REAP_GETPIDS: | ||||
return (reap_getpids(td, p, data)); | return (reap_getpids(td, p, data)); | ||||
Show All 19 Lines | kern_procctl(struct thread *td, idtype_t idtype, id_t id, int com, void *data) | ||||
struct proc *p; | struct proc *p; | ||||
int error, first_error, ok; | int error, first_error, ok; | ||||
int signum; | int signum; | ||||
bool tree_locked; | bool tree_locked; | ||||
switch (com) { | switch (com) { | ||||
case PROC_ASLR_CTL: | case PROC_ASLR_CTL: | ||||
case PROC_ASLR_STATUS: | case PROC_ASLR_STATUS: | ||||
case PROC_PROTMAX_CTL: | |||||
case PROC_PROTMAX_STATUS: | |||||
case PROC_REAP_ACQUIRE: | case PROC_REAP_ACQUIRE: | ||||
case PROC_REAP_RELEASE: | case PROC_REAP_RELEASE: | ||||
case PROC_REAP_STATUS: | case PROC_REAP_STATUS: | ||||
case PROC_REAP_GETPIDS: | case PROC_REAP_GETPIDS: | ||||
case PROC_REAP_KILL: | case PROC_REAP_KILL: | ||||
case PROC_TRACE_STATUS: | case PROC_TRACE_STATUS: | ||||
case PROC_TRAPCAP_STATUS: | case PROC_TRAPCAP_STATUS: | ||||
case PROC_PDEATHSIG_CTL: | case PROC_PDEATHSIG_CTL: | ||||
Show All 35 Lines | case PROC_TRAPCAP_CTL: | ||||
break; | break; | ||||
case PROC_REAP_ACQUIRE: | case PROC_REAP_ACQUIRE: | ||||
case PROC_REAP_RELEASE: | case PROC_REAP_RELEASE: | ||||
sx_xlock(&proctree_lock); | sx_xlock(&proctree_lock); | ||||
tree_locked = true; | tree_locked = true; | ||||
break; | break; | ||||
case PROC_ASLR_CTL: | case PROC_ASLR_CTL: | ||||
case PROC_ASLR_STATUS: | case PROC_ASLR_STATUS: | ||||
case PROC_PROTMAX_CTL: | |||||
case PROC_PROTMAX_STATUS: | |||||
case PROC_TRACE_STATUS: | case PROC_TRACE_STATUS: | ||||
case PROC_TRAPCAP_STATUS: | case PROC_TRAPCAP_STATUS: | ||||
tree_locked = false; | tree_locked = false; | ||||
break; | break; | ||||
default: | default: | ||||
return (EINVAL); | return (EINVAL); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 59 Lines • Show Last 20 Lines |