kern_procctl_single(): convert to use table data
Reviewed by: emaste, markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D32513
This commit is contained in:
parent
34f39a8c0e
commit
68dc5b381a
@ -102,10 +102,11 @@ protect_setchildren(struct thread *td, struct proc *top, int flags)
|
||||
}
|
||||
|
||||
static int
|
||||
protect_set(struct thread *td, struct proc *p, int flags)
|
||||
protect_set(struct thread *td, struct proc *p, void *data)
|
||||
{
|
||||
int error, ret;
|
||||
int error, flags, ret;
|
||||
|
||||
flags = *(int *)data;
|
||||
switch (PPROT_OP(flags)) {
|
||||
case PPROT_SET:
|
||||
case PPROT_CLEAR:
|
||||
@ -131,7 +132,7 @@ protect_set(struct thread *td, struct proc *p, int flags)
|
||||
}
|
||||
|
||||
static int
|
||||
reap_acquire(struct thread *td, struct proc *p)
|
||||
reap_acquire(struct thread *td, struct proc *p, void *data __unused)
|
||||
{
|
||||
|
||||
sx_assert(&proctree_lock, SX_XLOCKED);
|
||||
@ -148,7 +149,7 @@ reap_acquire(struct thread *td, struct proc *p)
|
||||
}
|
||||
|
||||
static int
|
||||
reap_release(struct thread *td, struct proc *p)
|
||||
reap_release(struct thread *td, struct proc *p, void *data __unused)
|
||||
{
|
||||
|
||||
sx_assert(&proctree_lock, SX_XLOCKED);
|
||||
@ -163,11 +164,12 @@ reap_release(struct thread *td, struct proc *p)
|
||||
}
|
||||
|
||||
static int
|
||||
reap_status(struct thread *td, struct proc *p,
|
||||
struct procctl_reaper_status *rs)
|
||||
reap_status(struct thread *td, struct proc *p, void *data)
|
||||
{
|
||||
struct proc *reap, *p2, *first_p;
|
||||
struct procctl_reaper_status *rs;
|
||||
|
||||
rs = data;
|
||||
sx_assert(&proctree_lock, SX_LOCKED);
|
||||
bzero(rs, sizeof(*rs));
|
||||
if ((p->p_treeflag & P_TREE_REAPER) == 0) {
|
||||
@ -198,13 +200,15 @@ reap_status(struct thread *td, struct proc *p,
|
||||
}
|
||||
|
||||
static int
|
||||
reap_getpids(struct thread *td, struct proc *p, struct procctl_reaper_pids *rp)
|
||||
reap_getpids(struct thread *td, struct proc *p, void *data)
|
||||
{
|
||||
struct proc *reap, *p2;
|
||||
struct procctl_reaper_pidinfo *pi, *pip;
|
||||
struct procctl_reaper_pids *rp;
|
||||
u_int i, n;
|
||||
int error;
|
||||
|
||||
rp = data;
|
||||
sx_assert(&proctree_lock, SX_LOCKED);
|
||||
PROC_UNLOCK(p);
|
||||
reap = (p->p_treeflag & P_TREE_REAPER) == 0 ? p->p_reaper : p;
|
||||
@ -276,14 +280,16 @@ reap_kill_sched(struct reap_kill_tracker_head *tracker, struct proc *p2)
|
||||
}
|
||||
|
||||
static int
|
||||
reap_kill(struct thread *td, struct proc *p, struct procctl_reaper_kill *rk)
|
||||
reap_kill(struct thread *td, struct proc *p, void *data)
|
||||
{
|
||||
struct proc *reap, *p2;
|
||||
ksiginfo_t ksi;
|
||||
struct reap_kill_tracker_head tracker;
|
||||
struct reap_kill_tracker *t;
|
||||
struct procctl_reaper_kill *rk;
|
||||
int error;
|
||||
|
||||
rk = data;
|
||||
sx_assert(&proctree_lock, SX_LOCKED);
|
||||
if (IN_CAPABILITY_MODE(td))
|
||||
return (ECAPMODE);
|
||||
@ -336,10 +342,12 @@ reap_kill(struct thread *td, struct proc *p, struct procctl_reaper_kill *rk)
|
||||
}
|
||||
|
||||
static int
|
||||
trace_ctl(struct thread *td, struct proc *p, int state)
|
||||
trace_ctl(struct thread *td, struct proc *p, void *data)
|
||||
{
|
||||
int state;
|
||||
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
state = *(int *)data;
|
||||
|
||||
/*
|
||||
* Ktrace changes p_traceflag from or to zero under the
|
||||
@ -376,26 +384,30 @@ trace_ctl(struct thread *td, struct proc *p, int state)
|
||||
}
|
||||
|
||||
static int
|
||||
trace_status(struct thread *td, struct proc *p, int *data)
|
||||
trace_status(struct thread *td, struct proc *p, void *data)
|
||||
{
|
||||
int *status;
|
||||
|
||||
status = data;
|
||||
if ((p->p_flag2 & P2_NOTRACE) != 0) {
|
||||
KASSERT((p->p_flag & P_TRACED) == 0,
|
||||
("%d traced but tracing disabled", p->p_pid));
|
||||
*data = -1;
|
||||
*status = -1;
|
||||
} else if ((p->p_flag & P_TRACED) != 0) {
|
||||
*data = p->p_pptr->p_pid;
|
||||
*status = p->p_pptr->p_pid;
|
||||
} else {
|
||||
*data = 0;
|
||||
*status = 0;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
trapcap_ctl(struct thread *td, struct proc *p, int state)
|
||||
trapcap_ctl(struct thread *td, struct proc *p, void *data)
|
||||
{
|
||||
int state;
|
||||
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
state = *(int *)data;
|
||||
|
||||
switch (state) {
|
||||
case PROC_TRAPCAP_CTL_ENABLE:
|
||||
@ -411,19 +423,23 @@ trapcap_ctl(struct thread *td, struct proc *p, int state)
|
||||
}
|
||||
|
||||
static int
|
||||
trapcap_status(struct thread *td, struct proc *p, int *data)
|
||||
trapcap_status(struct thread *td, struct proc *p, void *data)
|
||||
{
|
||||
int *status;
|
||||
|
||||
*data = (p->p_flag2 & P2_TRAPCAP) != 0 ? PROC_TRAPCAP_CTL_ENABLE :
|
||||
status = data;
|
||||
*status = (p->p_flag2 & P2_TRAPCAP) != 0 ? PROC_TRAPCAP_CTL_ENABLE :
|
||||
PROC_TRAPCAP_CTL_DISABLE;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
no_new_privs_ctl(struct thread *td, struct proc *p, int state)
|
||||
no_new_privs_ctl(struct thread *td, struct proc *p, void *data)
|
||||
{
|
||||
int state;
|
||||
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
state = *(int *)data;
|
||||
|
||||
if (state != PROC_NO_NEW_PRIVS_ENABLE)
|
||||
return (EINVAL);
|
||||
@ -432,18 +448,21 @@ no_new_privs_ctl(struct thread *td, struct proc *p, int state)
|
||||
}
|
||||
|
||||
static int
|
||||
no_new_privs_status(struct thread *td, struct proc *p, int *data)
|
||||
no_new_privs_status(struct thread *td, struct proc *p, void *data)
|
||||
{
|
||||
|
||||
*data = (p->p_flag2 & P2_NO_NEW_PRIVS) != 0 ?
|
||||
*(int *)data = (p->p_flag2 & P2_NO_NEW_PRIVS) != 0 ?
|
||||
PROC_NO_NEW_PRIVS_ENABLE : PROC_NO_NEW_PRIVS_DISABLE;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
protmax_ctl(struct thread *td, struct proc *p, int state)
|
||||
protmax_ctl(struct thread *td, struct proc *p, void *data)
|
||||
{
|
||||
int state;
|
||||
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
state = *(int *)data;
|
||||
|
||||
switch (state) {
|
||||
case PROC_PROTMAX_FORCE_ENABLE:
|
||||
@ -464,7 +483,7 @@ protmax_ctl(struct thread *td, struct proc *p, int state)
|
||||
}
|
||||
|
||||
static int
|
||||
protmax_status(struct thread *td, struct proc *p, int *data)
|
||||
protmax_status(struct thread *td, struct proc *p, void *data)
|
||||
{
|
||||
int d;
|
||||
|
||||
@ -481,15 +500,17 @@ protmax_status(struct thread *td, struct proc *p, int *data)
|
||||
}
|
||||
if (kern_mmap_maxprot(p, PROT_READ) == PROT_READ)
|
||||
d |= PROC_PROTMAX_ACTIVE;
|
||||
*data = d;
|
||||
*(int *)data = d;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
aslr_ctl(struct thread *td, struct proc *p, int state)
|
||||
aslr_ctl(struct thread *td, struct proc *p, void *data)
|
||||
{
|
||||
int state;
|
||||
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
state = *(int *)data;
|
||||
|
||||
switch (state) {
|
||||
case PROC_ASLR_FORCE_ENABLE:
|
||||
@ -510,7 +531,7 @@ aslr_ctl(struct thread *td, struct proc *p, int state)
|
||||
}
|
||||
|
||||
static int
|
||||
aslr_status(struct thread *td, struct proc *p, int *data)
|
||||
aslr_status(struct thread *td, struct proc *p, void *data)
|
||||
{
|
||||
struct vmspace *vm;
|
||||
int d;
|
||||
@ -538,14 +559,17 @@ aslr_status(struct thread *td, struct proc *p, int *data)
|
||||
PROC_LOCK(p);
|
||||
_PRELE(p);
|
||||
}
|
||||
*data = d;
|
||||
*(int *)data = d;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
stackgap_ctl(struct thread *td, struct proc *p, int state)
|
||||
stackgap_ctl(struct thread *td, struct proc *p, void *data)
|
||||
{
|
||||
int state;
|
||||
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
state = *(int *)data;
|
||||
|
||||
if ((state & ~(PROC_STACKGAP_ENABLE | PROC_STACKGAP_DISABLE |
|
||||
PROC_STACKGAP_ENABLE_EXEC | PROC_STACKGAP_DISABLE_EXEC)) != 0)
|
||||
@ -580,26 +604,31 @@ stackgap_ctl(struct thread *td, struct proc *p, int state)
|
||||
}
|
||||
|
||||
static int
|
||||
stackgap_status(struct thread *td, struct proc *p, int *data)
|
||||
stackgap_status(struct thread *td, struct proc *p, void *data)
|
||||
{
|
||||
int d;
|
||||
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
|
||||
*data = (p->p_flag2 & P2_STKGAP_DISABLE) != 0 ? PROC_STACKGAP_DISABLE :
|
||||
d = (p->p_flag2 & P2_STKGAP_DISABLE) != 0 ? PROC_STACKGAP_DISABLE :
|
||||
PROC_STACKGAP_ENABLE;
|
||||
*data |= (p->p_flag2 & P2_STKGAP_DISABLE_EXEC) != 0 ?
|
||||
d |= (p->p_flag2 & P2_STKGAP_DISABLE_EXEC) != 0 ?
|
||||
PROC_STACKGAP_DISABLE_EXEC : PROC_STACKGAP_ENABLE_EXEC;
|
||||
*(int *)data = d;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
wxmap_ctl(struct thread *td, struct proc *p, int state)
|
||||
wxmap_ctl(struct thread *td, struct proc *p, void *data)
|
||||
{
|
||||
struct vmspace *vm;
|
||||
vm_map_t map;
|
||||
int state;
|
||||
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
if ((p->p_flag & P_WEXIT) != 0)
|
||||
return (ESRCH);
|
||||
state = *(int *)data;
|
||||
|
||||
switch (state) {
|
||||
case PROC_WX_MAPPINGS_PERMIT:
|
||||
@ -628,7 +657,7 @@ wxmap_ctl(struct thread *td, struct proc *p, int state)
|
||||
}
|
||||
|
||||
static int
|
||||
wxmap_status(struct thread *td, struct proc *p, int *data)
|
||||
wxmap_status(struct thread *td, struct proc *p, void *data)
|
||||
{
|
||||
struct vmspace *vm;
|
||||
int d;
|
||||
@ -652,21 +681,24 @@ wxmap_status(struct thread *td, struct proc *p, int *data)
|
||||
}
|
||||
PROC_LOCK(p);
|
||||
_PRELE(p);
|
||||
*data = d;
|
||||
*(int *)data = d;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
pdeathsig_ctl(struct thread *td, struct proc *p, int data)
|
||||
pdeathsig_ctl(struct thread *td, struct proc *p, void *data)
|
||||
{
|
||||
if (p != td->td_proc || (data != 0 && !_SIG_VALID(data)))
|
||||
int signum;
|
||||
|
||||
signum = *(int *)data;
|
||||
if (p != td->td_proc || (signum != 0 && !_SIG_VALID(signum)))
|
||||
return (EINVAL);
|
||||
p->p_pdeathsig = data;
|
||||
p->p_pdeathsig = signum;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
pdeathsig_status(struct thread *td, struct proc *p, int *data)
|
||||
pdeathsig_status(struct thread *td, struct proc *p, void *data)
|
||||
{
|
||||
if (p != td->td_proc)
|
||||
return (EINVAL);
|
||||
@ -678,74 +710,97 @@ struct procctl_cmd_info {
|
||||
int lock_tree;
|
||||
bool one_proc : 1;
|
||||
bool esrch_is_einval : 1;
|
||||
int (*exec)(struct thread *, struct proc *, void *);
|
||||
};
|
||||
static const struct procctl_cmd_info procctl_cmds_info[] = {
|
||||
[PROC_SPROTECT] =
|
||||
{ .lock_tree = SA_SLOCKED, .one_proc = false,
|
||||
.esrch_is_einval = false, },
|
||||
.esrch_is_einval = false,
|
||||
.exec = protect_set, },
|
||||
[PROC_REAP_ACQUIRE] =
|
||||
{ .lock_tree = SA_XLOCKED, .one_proc = true,
|
||||
.esrch_is_einval = false, },
|
||||
.esrch_is_einval = false,
|
||||
.exec = reap_acquire, },
|
||||
[PROC_REAP_RELEASE] =
|
||||
{ .lock_tree = SA_XLOCKED, .one_proc = true,
|
||||
.esrch_is_einval = false, },
|
||||
.esrch_is_einval = false,
|
||||
.exec = reap_release, },
|
||||
[PROC_REAP_STATUS] =
|
||||
{ .lock_tree = SA_SLOCKED, .one_proc = true,
|
||||
.esrch_is_einval = false, },
|
||||
.esrch_is_einval = false,
|
||||
.exec = reap_status, },
|
||||
[PROC_REAP_GETPIDS] =
|
||||
{ .lock_tree = SA_SLOCKED, .one_proc = true,
|
||||
.esrch_is_einval = false, },
|
||||
.esrch_is_einval = false,
|
||||
.exec = reap_getpids, },
|
||||
[PROC_REAP_KILL] =
|
||||
{ .lock_tree = SA_SLOCKED, .one_proc = true,
|
||||
.esrch_is_einval = false, },
|
||||
.esrch_is_einval = false,
|
||||
.exec = reap_kill, },
|
||||
[PROC_TRACE_CTL] =
|
||||
{ .lock_tree = SA_SLOCKED, .one_proc = false,
|
||||
.esrch_is_einval = false, },
|
||||
.esrch_is_einval = false,
|
||||
.exec = trace_ctl, },
|
||||
[PROC_TRACE_STATUS] =
|
||||
{ .lock_tree = SA_UNLOCKED, .one_proc = true,
|
||||
.esrch_is_einval = false, },
|
||||
.esrch_is_einval = false,
|
||||
.exec = trace_status, },
|
||||
[PROC_TRAPCAP_CTL] =
|
||||
{ .lock_tree = SA_SLOCKED, .one_proc = false,
|
||||
.esrch_is_einval = false, },
|
||||
.esrch_is_einval = false,
|
||||
.exec = trapcap_ctl, },
|
||||
[PROC_TRAPCAP_STATUS] =
|
||||
{ .lock_tree = SA_UNLOCKED, .one_proc = true,
|
||||
.esrch_is_einval = false, },
|
||||
.esrch_is_einval = false,
|
||||
.exec = trapcap_status, },
|
||||
[PROC_PDEATHSIG_CTL] =
|
||||
{ .lock_tree = SA_UNLOCKED, .one_proc = true,
|
||||
.esrch_is_einval = true, },
|
||||
.esrch_is_einval = true,
|
||||
.exec = pdeathsig_ctl, },
|
||||
[PROC_PDEATHSIG_STATUS] =
|
||||
{ .lock_tree = SA_UNLOCKED, .one_proc = true,
|
||||
.esrch_is_einval = true, },
|
||||
.esrch_is_einval = true,
|
||||
.exec = pdeathsig_status, },
|
||||
[PROC_ASLR_CTL] =
|
||||
{ .lock_tree = SA_UNLOCKED, .one_proc = true,
|
||||
.esrch_is_einval = false, },
|
||||
.esrch_is_einval = false,
|
||||
.exec = aslr_ctl, },
|
||||
[PROC_ASLR_STATUS] =
|
||||
{ .lock_tree = SA_UNLOCKED, .one_proc = true,
|
||||
.esrch_is_einval = false, },
|
||||
.esrch_is_einval = false,
|
||||
.exec = aslr_status, },
|
||||
[PROC_PROTMAX_CTL] =
|
||||
{ .lock_tree = SA_UNLOCKED, .one_proc = true,
|
||||
.esrch_is_einval = false, },
|
||||
.esrch_is_einval = false,
|
||||
.exec = protmax_ctl, },
|
||||
[PROC_PROTMAX_STATUS] =
|
||||
{ .lock_tree = SA_UNLOCKED, .one_proc = true,
|
||||
.esrch_is_einval = false, },
|
||||
.esrch_is_einval = false,
|
||||
.exec = protmax_status, },
|
||||
[PROC_STACKGAP_CTL] =
|
||||
{ .lock_tree = SA_UNLOCKED, .one_proc = true,
|
||||
.esrch_is_einval = false, },
|
||||
.esrch_is_einval = false,
|
||||
.exec = stackgap_ctl, },
|
||||
[PROC_STACKGAP_STATUS] =
|
||||
{ .lock_tree = SA_UNLOCKED, .one_proc = true,
|
||||
.esrch_is_einval = false, },
|
||||
.esrch_is_einval = false,
|
||||
.exec = stackgap_status, },
|
||||
[PROC_NO_NEW_PRIVS_CTL] =
|
||||
{ .lock_tree = SA_SLOCKED, .one_proc = true,
|
||||
.esrch_is_einval = false, },
|
||||
.esrch_is_einval = false,
|
||||
.exec = no_new_privs_ctl, },
|
||||
[PROC_NO_NEW_PRIVS_STATUS] =
|
||||
{ .lock_tree = SA_UNLOCKED, .one_proc = true,
|
||||
.esrch_is_einval = false, },
|
||||
.esrch_is_einval = false,
|
||||
.exec = no_new_privs_status, },
|
||||
[PROC_WXMAP_CTL] =
|
||||
{ .lock_tree = SA_UNLOCKED, .one_proc = true,
|
||||
.esrch_is_einval = false, },
|
||||
.esrch_is_einval = false,
|
||||
.exec = wxmap_ctl, },
|
||||
[PROC_WXMAP_STATUS] =
|
||||
{ .lock_tree = SA_UNLOCKED, .one_proc = true,
|
||||
.esrch_is_einval = false, },
|
||||
.esrch_is_einval = false,
|
||||
.exec = wxmap_status, },
|
||||
};
|
||||
|
||||
int
|
||||
@ -853,54 +908,7 @@ kern_procctl_single(struct thread *td, struct proc *p, int com, void *data)
|
||||
{
|
||||
|
||||
PROC_LOCK_ASSERT(p, MA_OWNED);
|
||||
switch (com) {
|
||||
case PROC_ASLR_CTL:
|
||||
return (aslr_ctl(td, p, *(int *)data));
|
||||
case PROC_ASLR_STATUS:
|
||||
return (aslr_status(td, p, data));
|
||||
case PROC_SPROTECT:
|
||||
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_STACKGAP_CTL:
|
||||
return (stackgap_ctl(td, p, *(int *)data));
|
||||
case PROC_STACKGAP_STATUS:
|
||||
return (stackgap_status(td, p, data));
|
||||
case PROC_REAP_ACQUIRE:
|
||||
return (reap_acquire(td, p));
|
||||
case PROC_REAP_RELEASE:
|
||||
return (reap_release(td, p));
|
||||
case PROC_REAP_STATUS:
|
||||
return (reap_status(td, p, data));
|
||||
case PROC_REAP_GETPIDS:
|
||||
return (reap_getpids(td, p, data));
|
||||
case PROC_REAP_KILL:
|
||||
return (reap_kill(td, p, data));
|
||||
case PROC_TRACE_CTL:
|
||||
return (trace_ctl(td, p, *(int *)data));
|
||||
case PROC_TRACE_STATUS:
|
||||
return (trace_status(td, p, data));
|
||||
case PROC_TRAPCAP_CTL:
|
||||
return (trapcap_ctl(td, p, *(int *)data));
|
||||
case PROC_TRAPCAP_STATUS:
|
||||
return (trapcap_status(td, p, data));
|
||||
case PROC_PDEATHSIG_CTL:
|
||||
return (pdeathsig_ctl(td, p, *(int *)data));
|
||||
case PROC_PDEATHSIG_STATUS:
|
||||
return (pdeathsig_status(td, p, data));
|
||||
case PROC_NO_NEW_PRIVS_CTL:
|
||||
return (no_new_privs_ctl(td, p, *(int *)data));
|
||||
case PROC_NO_NEW_PRIVS_STATUS:
|
||||
return (no_new_privs_status(td, p, data));
|
||||
case PROC_WXMAP_CTL:
|
||||
return (wxmap_ctl(td, p, *(int *)data));
|
||||
case PROC_WXMAP_STATUS:
|
||||
return (wxmap_status(td, p, data));
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
return (procctl_cmds_info[com].exec(td, p, data));
|
||||
}
|
||||
|
||||
int
|
||||
|
Loading…
Reference in New Issue
Block a user