Print this page
uts: Allow for address space randomisation.
Randomise the base addresses of shared objects, non-fixed mappings, the
stack and the heap. Introduce a service, svc:/system/process-security,
and a tool psecflags(1) to control and observe it
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/os/proc.c
+++ new/usr/src/uts/common/os/proc.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License, Version 1.0 only
6 6 * (the "License"). You may not use this file except in compliance
7 7 * with the License.
8 8 *
9 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 10 * or http://www.opensolaris.org/os/licensing.
11 11 * See the License for the specific language governing permissions
12 12 * and limitations under the License.
13 13 *
14 14 * When distributing Covered Code, include this CDDL HEADER in each
15 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 16 * If applicable, add the following below this CDDL HEADER, with the
17 17 * fields enclosed by brackets "[]" replaced with your own identifying
18 18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 19 *
20 20 * CDDL HEADER END
21 21 */
22 22 /*
23 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 24 * Use is subject to license terms.
25 25 * Copyright (c) 2013, Joyent, Inc. All rights reserved.
26 26 */
27 27
28 28 #include <sys/proc.h>
29 29 #include <sys/cpuvar.h>
30 30 #include <sys/disp.h>
31 31
32 32 /*
33 33 * Install process context ops for the current process.
34 34 */
35 35 void
36 36 installpctx(
37 37 proc_t *p,
38 38 void *arg,
39 39 void (*save)(void *),
40 40 void (*restore)(void *),
41 41 void (*fork)(void *, void *),
42 42 void (*exit)(void *),
43 43 void (*free)(void *, int))
44 44 {
45 45 struct pctxop *pctx;
46 46
47 47 pctx = kmem_alloc(sizeof (struct pctxop), KM_SLEEP);
48 48 pctx->save_op = save;
49 49 pctx->restore_op = restore;
50 50 pctx->fork_op = fork;
51 51 pctx->exit_op = exit;
52 52 pctx->free_op = free;
53 53 pctx->arg = arg;
54 54 pctx->next = p->p_pctx;
55 55 p->p_pctx = pctx;
56 56 }
57 57
58 58 /*
59 59 * Remove a process context ops from the current process.
60 60 */
61 61 int
62 62 removepctx(
63 63 proc_t *p,
64 64 void *arg,
65 65 void (*save)(void *),
66 66 void (*restore)(void *),
67 67 void (*fork)(void *, void *),
68 68 void (*exit)(void *),
69 69 void (*free)(void *, int))
70 70 {
71 71 struct pctxop *pctx, *prev_pctx;
72 72
73 73 prev_pctx = NULL;
74 74 kpreempt_disable();
75 75 for (pctx = p->p_pctx; pctx != NULL; pctx = pctx->next) {
76 76 if (pctx->save_op == save && pctx->restore_op == restore &&
77 77 pctx->fork_op == fork &&
78 78 pctx->exit_op == exit && pctx->free_op == free &&
79 79 pctx->arg == arg) {
80 80 if (prev_pctx)
81 81 prev_pctx->next = pctx->next;
82 82 else
83 83 p->p_pctx = pctx->next;
84 84 if (pctx->free_op != NULL)
85 85 (pctx->free_op)(pctx->arg, 0);
86 86 kmem_free(pctx, sizeof (struct pctxop));
87 87 kpreempt_enable();
88 88 return (1);
89 89 }
90 90 prev_pctx = pctx;
91 91 }
92 92 kpreempt_enable();
93 93 return (0);
94 94 }
95 95
96 96 void
97 97 savepctx(proc_t *p)
98 98 {
99 99 struct pctxop *pctx;
100 100
101 101 ASSERT(p == curthread->t_procp);
102 102 for (pctx = p->p_pctx; pctx != 0; pctx = pctx->next)
103 103 if (pctx->save_op != NULL)
104 104 (pctx->save_op)(pctx->arg);
105 105 }
106 106
107 107 void
108 108 restorepctx(proc_t *p)
109 109 {
110 110 struct pctxop *pctx;
111 111
112 112 ASSERT(p == curthread->t_procp);
113 113 for (pctx = p->p_pctx; pctx != 0; pctx = pctx->next)
114 114 if (pctx->restore_op != NULL)
115 115 (pctx->restore_op)(pctx->arg);
116 116 }
117 117
118 118 void
119 119 forkpctx(proc_t *p, proc_t *cp)
120 120 {
121 121 struct pctxop *pctx;
122 122
123 123 for (pctx = p->p_pctx; pctx != NULL; pctx = pctx->next)
124 124 if (pctx->fork_op != NULL)
125 125 (pctx->fork_op)(p, cp);
126 126 }
127 127
128 128 /*
129 129 * exitpctx is called during thread/lwp exit to perform any actions
130 130 * needed when an LWP in the process leaves the processor for the last
131 131 * time. This routine is not intended to deal with freeing memory; freepctx()
132 132 * is used for that purpose during proc_exit(). This routine is provided to
133 133 * allow for clean-up that can't wait until thread_free().
134 134 */
135 135 void
136 136 exitpctx(proc_t *p)
137 137 {
138 138 struct pctxop *pctx;
139 139
140 140 for (pctx = p->p_pctx; pctx != NULL; pctx = pctx->next)
141 141 if (pctx->exit_op != NULL)
142 142 (pctx->exit_op)(p);
143 143 }
144 144
145 145 /*
146 146 * freepctx is called from proc_exit() to get rid of the actual context ops.
147 147 */
148 148 void
149 149 freepctx(proc_t *p, int isexec)
150 150 {
151 151 struct pctxop *pctx;
↓ open down ↓ |
151 lines elided |
↑ open up ↑ |
152 152
153 153 kpreempt_disable();
154 154 while ((pctx = p->p_pctx) != NULL) {
155 155 p->p_pctx = pctx->next;
156 156 if (pctx->free_op != NULL)
157 157 (pctx->free_op)(pctx->arg, isexec);
158 158 kmem_free(pctx, sizeof (struct pctxop));
159 159 }
160 160 kpreempt_enable();
161 161 }
162 +
163 +boolean_t
164 +secflag_enabled(proc_t *p, uint_t flag)
165 +{
166 + return ((p->p_secflags.psf_effective & flag) != 0);
167 +}
168 +
169 +void
170 +secflag_set(proc_t *p, uint_t flag)
171 +{
172 + p->p_secflags.psf_inherit = flag;
173 +}
174 +
175 +void
176 +secflag_enable(proc_t *p, uint_t flag) {
177 + p->p_secflags.psf_inherit |= flag;
178 +}
179 +
180 +void
181 +secflag_disable(proc_t *p, uint_t flag) {
182 + p->p_secflags.psf_inherit &= ~flag;
183 +}
184 +
185 +void
186 +secflag_promote(proc_t *p) {
187 + p->p_secflags.psf_effective = p->p_secflags.psf_inherit;
188 +}
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX