1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2014 <contributor>. All rights reserved.
14 */
15
16 #include <sys/ddi.h>
17 #include <sys/errno.h>
18 #include <sys/policy.h>
19 #include <sys/proc.h>
20 #include <sys/procset.h>
21 #include <sys/systm.h>
22 #include <sys/types.h>
23
24 struct psecargs {
25 psecflags_cmd_t cmd;
26 uint_t val;
27 };
28
29 static int
30 psecdo(proc_t *p, struct psecargs *args)
31 {
32 mutex_enter(&p->p_lock);
33
34 if (secpolicy_psecflags(CRED(), p, curproc) != 0) {
35 mutex_exit(&p->p_lock);
36 return (EPERM);
37 }
38
39 switch (args->cmd) {
40 case PSECFLAGS_SET:
41 secflag_set(p, args->val);
42 break;
43 case PSECFLAGS_DISABLE:
44 secflag_disable(p, args->val);
45 break;
46 case PSECFLAGS_ENABLE:
47 secflag_enable(p, args->val);
48 break;
49 }
50 mutex_exit(&p->p_lock);
51
52 return (0);
53 }
54
55 int
56 psecflags(procset_t *psp, psecflags_cmd_t cmd, uint_t arg)
57 {
58 procset_t procset;
59 struct psecargs args = { 0 };
60 int rv = 0;
61
62 /*
63 * We don't check the validity in 'arg' for the sake of newer
64 * software on older systems not just falling down dead.
65 *
66 * XXX: I'm not particularly confident that's not dumb.
67 */
68
69 if (copyin(psp, &procset, sizeof (procset)) != 0)
70 return (set_errno(EFAULT));
71
72 /* secflags are per-process, procset must be in terms of processes */
73 if ((procset.p_lidtype == P_LWPID) ||
74 (procset.p_ridtype == P_LWPID))
75 return (set_errno(EINVAL));
76
77 switch (cmd) {
78 case PSECFLAGS_SET:
79 case PSECFLAGS_DISABLE:
80 case PSECFLAGS_ENABLE:
81 args.cmd = cmd;
82 args.val = arg;
83 rv = dotoprocs(&procset, psecdo,
84 (caddr_t)&args);
85 break;
86 default:
87 return (set_errno(EINVAL));
88 }
89
90 return (rv ? set_errno(rv) : 0);
91 }