Print this page
OS-4460 exec brands processes that still have multiple threads
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Joshua M. Clulow <jmc@joyent.com>
OS-4188 NULL dereference in lwp_hash_in
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Joshua M. Clulow <jmc@joyent.com>
OS-4119 lxbrand panic when running native perl inside lx zone
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
OS-4151 setbrand hooks should be sane during fork
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Joshua M. Clulow <jmc@joyent.com>
OS-4129 lxbrand should not abuse p_brand_data for storing exit signal
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Joshua M. Clulow <jmc@joyent.com>
OS-3712 lx brand: DTrace pid provider induces core dumps on 64-bit processes
OS-3517 lx brand: branded zones don't interpret .interp section
OS-3149 lx brand always sends SIGCHLD to parent processes, regardless of how clone was invoked
OS-2887 lxbrand add WALL, WCLONE, WNOTHREAD support to waitid
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
OS-2877 lx_librtld_db falls to load due to NULL DT_DEBUG
OS-2834 ship lx brand
| Split |
Close |
| Expand all |
| Collapse all |
--- old/usr/src/uts/common/os/brand.c
+++ new/usr/src/uts/common/os/brand.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 (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
|
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
23 + * Copyright (c) 2015, Joyent, Inc. All rights reserved.
23 24 */
24 25
25 26 #include <sys/kmem.h>
26 27 #include <sys/errno.h>
27 28 #include <sys/systm.h>
28 29 #include <sys/cmn_err.h>
29 30 #include <sys/brand.h>
30 31 #include <sys/machbrand.h>
31 32 #include <sys/modctl.h>
32 33 #include <sys/rwlock.h>
33 34 #include <sys/zone.h>
34 35 #include <sys/pathname.h>
35 36
36 37 #define SUPPORTED_BRAND_VERSION BRAND_VER_1
37 38
|
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
38 39 #if defined(__sparcv9)
39 40 /* sparcv9 uses system wide brand interposition hooks */
40 41 static void brand_plat_interposition_enable(void);
41 42 static void brand_plat_interposition_disable(void);
42 43
43 44 struct brand_mach_ops native_mach_ops = {
44 45 NULL, NULL
45 46 };
46 47 #else /* !__sparcv9 */
47 48 struct brand_mach_ops native_mach_ops = {
48 - NULL, NULL, NULL, NULL
49 + NULL, NULL, NULL, NULL, NULL, NULL, NULL
49 50 };
50 51 #endif /* !__sparcv9 */
51 52
52 53 brand_t native_brand = {
53 54 BRAND_VER_1,
54 55 "native",
55 56 NULL,
56 - &native_mach_ops
57 + &native_mach_ops,
58 + 0
57 59 };
58 60
59 61 /*
60 62 * Used to maintain a list of all the brands currently loaded into the
61 63 * kernel.
62 64 */
63 65 struct brand_list {
64 66 int bl_refcnt;
65 67 struct brand_list *bl_next;
66 68 brand_t *bl_brand;
67 69 };
68 70
69 71 static struct brand_list *brand_list = NULL;
70 72
71 73 /*
72 74 * This lock protects the integrity of the brand list.
73 75 */
74 76 static kmutex_t brand_list_lock;
75 77
76 78 void
77 79 brand_init()
78 80 {
79 81 mutex_init(&brand_list_lock, NULL, MUTEX_DEFAULT, NULL);
80 82 p0.p_brand = &native_brand;
81 83 }
82 84
83 85 int
84 86 brand_register(brand_t *brand)
85 87 {
86 88 struct brand_list *list, *scan;
87 89
88 90 if (brand == NULL)
89 91 return (EINVAL);
90 92
91 93 if (brand->b_version != SUPPORTED_BRAND_VERSION) {
92 94 if (brand->b_version < SUPPORTED_BRAND_VERSION) {
93 95 cmn_err(CE_WARN,
94 96 "brand '%s' was built to run on older versions "
95 97 "of Solaris.",
96 98 brand->b_name);
97 99 } else {
98 100 cmn_err(CE_WARN,
99 101 "brand '%s' was built to run on a newer version "
100 102 "of Solaris.",
101 103 brand->b_name);
102 104 }
103 105 return (EINVAL);
104 106 }
105 107
106 108 /* Sanity checks */
107 109 if (brand->b_name == NULL || brand->b_ops == NULL ||
108 110 brand->b_ops->b_brandsys == NULL) {
109 111 cmn_err(CE_WARN, "Malformed brand");
110 112 return (EINVAL);
111 113 }
112 114
113 115 list = kmem_alloc(sizeof (struct brand_list), KM_SLEEP);
114 116
115 117 /* Add the brand to the list of loaded brands. */
116 118 mutex_enter(&brand_list_lock);
117 119
118 120 /*
119 121 * Check to be sure we haven't already registered this brand.
120 122 */
121 123 for (scan = brand_list; scan != NULL; scan = scan->bl_next) {
122 124 if (strcmp(brand->b_name, scan->bl_brand->b_name) == 0) {
123 125 cmn_err(CE_WARN,
124 126 "Invalid attempt to load a second instance of "
125 127 "brand %s", brand->b_name);
126 128 mutex_exit(&brand_list_lock);
127 129 kmem_free(list, sizeof (struct brand_list));
128 130 return (EINVAL);
129 131 }
130 132 }
131 133
132 134 #if defined(__sparcv9)
133 135 /* sparcv9 uses system wide brand interposition hooks */
134 136 if (brand_list == NULL)
135 137 brand_plat_interposition_enable();
136 138 #endif /* __sparcv9 */
137 139
138 140 list->bl_brand = brand;
139 141 list->bl_refcnt = 0;
140 142 list->bl_next = brand_list;
141 143 brand_list = list;
142 144
143 145 mutex_exit(&brand_list_lock);
144 146
145 147 return (0);
146 148 }
147 149
148 150 /*
149 151 * The kernel module implementing this brand is being unloaded, so remove
150 152 * it from the list of active brands.
151 153 */
152 154 int
153 155 brand_unregister(brand_t *brand)
154 156 {
155 157 struct brand_list *list, *prev;
156 158
157 159 /* Sanity checks */
158 160 if (brand == NULL || brand->b_name == NULL) {
159 161 cmn_err(CE_WARN, "Malformed brand");
160 162 return (EINVAL);
161 163 }
162 164
163 165 prev = NULL;
164 166 mutex_enter(&brand_list_lock);
165 167
166 168 for (list = brand_list; list != NULL; list = list->bl_next) {
167 169 if (list->bl_brand == brand)
168 170 break;
169 171 prev = list;
170 172 }
171 173
172 174 if (list == NULL) {
173 175 cmn_err(CE_WARN, "Brand %s wasn't registered", brand->b_name);
174 176 mutex_exit(&brand_list_lock);
175 177 return (EINVAL);
176 178 }
177 179
178 180 if (list->bl_refcnt > 0) {
179 181 cmn_err(CE_WARN, "Unregistering brand %s which is still in use",
180 182 brand->b_name);
181 183 mutex_exit(&brand_list_lock);
182 184 return (EBUSY);
183 185 }
184 186
185 187 /* Remove brand from the list */
186 188 if (prev != NULL)
187 189 prev->bl_next = list->bl_next;
188 190 else
189 191 brand_list = list->bl_next;
190 192
191 193 #if defined(__sparcv9)
192 194 /* sparcv9 uses system wide brand interposition hooks */
193 195 if (brand_list == NULL)
194 196 brand_plat_interposition_disable();
195 197 #endif /* __sparcv9 */
196 198
197 199 mutex_exit(&brand_list_lock);
198 200
199 201 kmem_free(list, sizeof (struct brand_list));
200 202
201 203 return (0);
202 204 }
203 205
204 206 /*
205 207 * Record that a zone of this brand has been instantiated. If the kernel
206 208 * module implementing this brand's functionality is not present, this
207 209 * routine attempts to load the module as a side effect.
208 210 */
209 211 brand_t *
210 212 brand_register_zone(struct brand_attr *attr)
211 213 {
212 214 struct brand_list *l = NULL;
213 215 ddi_modhandle_t hdl = NULL;
214 216 char *modname;
215 217 int err = 0;
216 218
217 219 if (is_system_labeled()) {
218 220 cmn_err(CE_WARN,
219 221 "Branded zones are not allowed on labeled systems.");
220 222 return (NULL);
221 223 }
222 224
223 225 /*
224 226 * We make at most two passes through this loop. The first time
225 227 * through, we're looking to see if this is a new user of an
226 228 * already loaded brand. If the brand hasn't been loaded, we
227 229 * call ddi_modopen() to force it to be loaded and then make a
228 230 * second pass through the list of brands. If we don't find the
229 231 * brand the second time through it means that the modname
230 232 * specified in the brand_attr structure doesn't provide the brand
231 233 * specified in the brandname field. This would suggest a bug in
232 234 * the brand's config.xml file. We close the module and return
233 235 * 'NULL' to the caller.
234 236 */
235 237 for (;;) {
236 238 /*
237 239 * Search list of loaded brands
238 240 */
239 241 mutex_enter(&brand_list_lock);
240 242 for (l = brand_list; l != NULL; l = l->bl_next)
241 243 if (strcmp(attr->ba_brandname,
242 244 l->bl_brand->b_name) == 0)
243 245 break;
244 246 if ((l != NULL) || (hdl != NULL))
245 247 break;
246 248 mutex_exit(&brand_list_lock);
247 249
248 250 /*
249 251 * We didn't find that the requested brand has been loaded
250 252 * yet, so we trigger the load of the appropriate kernel
251 253 * module and search the list again.
252 254 */
253 255 modname = kmem_alloc(MAXPATHLEN, KM_SLEEP);
254 256 (void) strcpy(modname, "brand/");
255 257 (void) strcat(modname, attr->ba_modname);
256 258 hdl = ddi_modopen(modname, KRTLD_MODE_FIRST, &err);
257 259 kmem_free(modname, MAXPATHLEN);
258 260
259 261 if (err != 0)
260 262 return (NULL);
261 263 }
262 264
263 265 /*
264 266 * If we found the matching brand, bump its reference count.
265 267 */
266 268 if (l != NULL)
267 269 l->bl_refcnt++;
268 270
269 271 mutex_exit(&brand_list_lock);
270 272
271 273 if (hdl != NULL)
272 274 (void) ddi_modclose(hdl);
273 275
274 276 return ((l != NULL) ? l->bl_brand : NULL);
275 277 }
276 278
277 279 /*
278 280 * Return the number of zones currently using this brand.
279 281 */
280 282 int
281 283 brand_zone_count(struct brand *bp)
282 284 {
283 285 struct brand_list *l;
284 286 int cnt = 0;
285 287
286 288 mutex_enter(&brand_list_lock);
287 289 for (l = brand_list; l != NULL; l = l->bl_next)
288 290 if (l->bl_brand == bp) {
289 291 cnt = l->bl_refcnt;
290 292 break;
291 293 }
292 294 mutex_exit(&brand_list_lock);
293 295
294 296 return (cnt);
295 297 }
296 298
297 299 void
298 300 brand_unregister_zone(struct brand *bp)
299 301 {
300 302 struct brand_list *list;
301 303
302 304 mutex_enter(&brand_list_lock);
|
↓ open down ↓ |
236 lines elided |
↑ open up ↑ |
303 305 for (list = brand_list; list != NULL; list = list->bl_next) {
304 306 if (list->bl_brand == bp) {
305 307 ASSERT(list->bl_refcnt > 0);
306 308 list->bl_refcnt--;
307 309 break;
308 310 }
309 311 }
310 312 mutex_exit(&brand_list_lock);
311 313 }
312 314
313 -void
314 -brand_setbrand(proc_t *p)
315 +int
316 +brand_setbrand(proc_t *p, boolean_t lwps_ok)
315 317 {
316 318 brand_t *bp = p->p_zone->zone_brand;
319 + void *brand_data = NULL;
317 320
318 - ASSERT(bp != NULL);
319 - ASSERT(p->p_brand == &native_brand);
321 + VERIFY(MUTEX_NOT_HELD(&p->p_lock));
322 + VERIFY(bp != NULL);
320 323
321 324 /*
322 - * We should only be called from exec(), when we know the process
323 - * is single-threaded.
325 + * Process branding occurs during fork() and exec(). When it happens
326 + * during fork(), the LWP count will always be 0 since branding is
327 + * performed as part of getproc(), before LWPs have been associated.
328 + * The same is not true during exec(), where a multi-LWP process may
329 + * undergo branding just prior to gexec(). This is to ensure
330 + * exec-related brand hooks are available. While it may seem
331 + * complicated to brand a multi-LWP process, the two possible outcomes
332 + * simplify things:
333 + *
334 + * 1. The exec() succeeds: LWPs besides the caller will be killed and
335 + * any further branding will occur in a single-LWP context.
336 + * 2. The exec() fails: The process will be promptly unbranded since
337 + * the hooks are no longer needed.
338 + *
339 + * To prevent inconsistent brand state from being encountered during
340 + * the exec(), LWPs beyond the caller which are associated with this
341 + * process must be held temporarily. They will be released either when
342 + * they are killed in the exec() success, or when the brand is cleared
343 + * after exec() failure.
324 344 */
325 - ASSERT(p->p_tlist == p->p_tlist->t_forw);
345 + if (lwps_ok) {
346 + /*
347 + * We've been called from a exec() context tolerating the
348 + * existence of multiple LWPs during branding is necessary.
349 + */
350 + VERIFY(p == curproc);
351 + VERIFY(p->p_tlist != NULL);
326 352
353 + if (p->p_tlist != p->p_tlist->t_forw) {
354 + /*
355 + * Multiple LWPs are present. Hold all but the caller.
356 + */
357 + if (!holdlwps(SHOLDFORK1)) {
358 + return (-1);
359 + }
360 + }
361 + } else {
362 + /*
363 + * Processes branded during fork() should not have LWPs at all.
364 + */
365 + VERIFY(p->p_tlist == NULL);
366 + }
367 +
368 + if (bp->b_data_size > 0) {
369 + brand_data = kmem_zalloc(bp->b_data_size, KM_SLEEP);
370 + }
371 +
372 + mutex_enter(&p->p_lock);
373 + ASSERT(!PROC_IS_BRANDED(p));
327 374 p->p_brand = bp;
375 + p->p_brand_data = brand_data;
328 376 ASSERT(PROC_IS_BRANDED(p));
329 377 BROP(p)->b_setbrand(p);
378 + mutex_exit(&p->p_lock);
379 + return (0);
330 380 }
331 381
332 382 void
333 -brand_clearbrand(proc_t *p, boolean_t no_lwps)
383 +brand_clearbrand(proc_t *p, boolean_t lwps_ok)
334 384 {
335 385 brand_t *bp = p->p_zone->zone_brand;
336 - klwp_t *lwp = NULL;
337 - ASSERT(bp != NULL);
338 - ASSERT(!no_lwps || (p->p_tlist == NULL));
386 + void *brand_data;
339 387
340 - /*
341 - * If called from exec_common() or proc_exit(),
342 - * we know the process is single-threaded.
343 - * If called from fork_fail, p_tlist is NULL.
344 - */
345 - if (!no_lwps) {
346 - ASSERT(p->p_tlist == p->p_tlist->t_forw);
347 - lwp = p->p_tlist->t_lwp;
348 - }
388 + VERIFY(MUTEX_NOT_HELD(&p->p_lock));
389 + VERIFY(bp != NULL);
390 + VERIFY(PROC_IS_BRANDED(p));
349 391
350 - ASSERT(PROC_IS_BRANDED(p));
351 - BROP(p)->b_proc_exit(p, lwp);
392 + mutex_enter(&p->p_lock);
352 393 p->p_brand = &native_brand;
394 + brand_data = p->p_brand_data;
395 + p->p_brand_data = NULL;
396 +
397 + if (lwps_ok) {
398 + VERIFY(p == curproc);
399 + /*
400 + * A process with multiple LWPs is being de-branded after
401 + * failing an exec. The other LWPs were held as part of the
402 + * procedure, so they must be resumed now.
403 + */
404 + if (p->p_tlist != NULL && p->p_tlist != p->p_tlist->t_forw) {
405 + continuelwps(p);
406 + }
407 + } else {
408 + /*
409 + * While clearing the brand, it's ok for one LWP to be present.
410 + * This happens when a native binary is executed inside a
411 + * branded zone, since the brand will be removed during the
412 + * course of a successful exec.
413 + */
414 + VERIFY(p->p_tlist == NULL || p->p_tlist == p->p_tlist->t_forw);
415 + }
416 + mutex_exit(&p->p_lock);
417 +
418 + if (brand_data != NULL) {
419 + kmem_free(brand_data, bp->b_data_size);
420 + }
353 421 }
354 422
355 423 #if defined(__sparcv9)
356 424 /*
357 425 * Currently, only sparc has system level brand syscall interposition.
358 426 * On x86 we're able to enable syscall interposition on a per-cpu basis
359 427 * when a branded thread is scheduled to run on a cpu.
360 428 */
361 429
362 430 /* Local variables needed for dynamic syscall interposition support */
363 431 static uint32_t syscall_trap_patch_instr_orig;
364 432 static uint32_t syscall_trap32_patch_instr_orig;
365 433
366 434 /* Trap Table syscall entry hot patch points */
367 435 extern void syscall_trap_patch_point(void);
368 436 extern void syscall_trap32_patch_point(void);
369 437
370 438 /* Alternate syscall entry handlers used when branded zones are running */
371 439 extern void syscall_wrapper(void);
372 440 extern void syscall_wrapper32(void);
373 441
374 442 /* Macros used to facilitate sparcv9 instruction generation */
375 443 #define BA_A_INSTR 0x30800000 /* ba,a addr */
376 444 #define DISP22(from, to) \
377 445 ((((uintptr_t)(to) - (uintptr_t)(from)) >> 2) & 0x3fffff)
378 446
379 447 /*ARGSUSED*/
380 448 static void
381 449 brand_plat_interposition_enable(void)
382 450 {
383 451 ASSERT(MUTEX_HELD(&brand_list_lock));
384 452
385 453 /*
386 454 * Before we hot patch the kernel save the current instructions
387 455 * so that we can restore them later.
388 456 */
389 457 syscall_trap_patch_instr_orig =
390 458 *(uint32_t *)syscall_trap_patch_point;
391 459 syscall_trap32_patch_instr_orig =
392 460 *(uint32_t *)syscall_trap32_patch_point;
393 461
394 462 /*
395 463 * Modify the trap table at the patch points.
396 464 *
397 465 * We basically replace the first instruction at the patch
398 466 * point with a ba,a instruction that will transfer control
399 467 * to syscall_wrapper or syscall_wrapper32 for 64-bit and
400 468 * 32-bit syscalls respectively. It's important to note that
401 469 * the annul bit is set in the branch so we don't execute
402 470 * the instruction directly following the one we're patching
403 471 * during the branch's delay slot.
404 472 *
405 473 * It also doesn't matter that we're not atomically updating both
406 474 * the 64 and 32 bit syscall paths at the same time since there's
407 475 * no actual branded processes running on the system yet.
408 476 */
409 477 hot_patch_kernel_text((caddr_t)syscall_trap_patch_point,
410 478 BA_A_INSTR | DISP22(syscall_trap_patch_point, syscall_wrapper),
411 479 4);
412 480 hot_patch_kernel_text((caddr_t)syscall_trap32_patch_point,
413 481 BA_A_INSTR | DISP22(syscall_trap32_patch_point, syscall_wrapper32),
414 482 4);
415 483 }
416 484
417 485 /*ARGSUSED*/
418 486 static void
419 487 brand_plat_interposition_disable(void)
420 488 {
421 489 ASSERT(MUTEX_HELD(&brand_list_lock));
422 490
423 491 /*
424 492 * Restore the original instructions at the trap table syscall
425 493 * patch points to disable the brand syscall interposition
426 494 * mechanism.
427 495 */
428 496 hot_patch_kernel_text((caddr_t)syscall_trap_patch_point,
429 497 syscall_trap_patch_instr_orig, 4);
430 498 hot_patch_kernel_text((caddr_t)syscall_trap32_patch_point,
431 499 syscall_trap32_patch_instr_orig, 4);
432 500 }
433 501 #endif /* __sparcv9 */
434 502
435 503 /*
436 504 * The following functions can be shared among kernel brand modules which
437 505 * implement Solaris-derived brands, all of which need to do similar tasks
438 506 * to manage the brand.
439 507 */
440 508
441 509 #if defined(_LP64)
442 510 static void
443 511 Ehdr32to64(Elf32_Ehdr *src, Ehdr *dst)
444 512 {
445 513 bcopy(src->e_ident, dst->e_ident, sizeof (src->e_ident));
446 514 dst->e_type = src->e_type;
447 515 dst->e_machine = src->e_machine;
448 516 dst->e_version = src->e_version;
449 517 dst->e_entry = src->e_entry;
450 518 dst->e_phoff = src->e_phoff;
451 519 dst->e_shoff = src->e_shoff;
452 520 dst->e_flags = src->e_flags;
453 521 dst->e_ehsize = src->e_ehsize;
454 522 dst->e_phentsize = src->e_phentsize;
455 523 dst->e_phnum = src->e_phnum;
456 524 dst->e_shentsize = src->e_shentsize;
457 525 dst->e_shnum = src->e_shnum;
458 526 dst->e_shstrndx = src->e_shstrndx;
459 527 }
460 528 #endif /* _LP64 */
461 529
462 530 /*
463 531 * Return -1 if the cmd was not handled by this function.
464 532 */
465 533 /*ARGSUSED*/
466 534 int
467 535 brand_solaris_cmd(int cmd, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3,
468 536 struct brand *pbrand, int brandvers)
469 537 {
470 538 brand_proc_data_t *spd;
471 539 brand_proc_reg_t reg;
472 540 proc_t *p = curproc;
473 541 int err;
474 542
475 543 /*
|
↓ open down ↓ |
113 lines elided |
↑ open up ↑ |
476 544 * There is one operation that is supported for a native
477 545 * process; B_EXEC_BRAND. This brand operaion is redundant
478 546 * since the kernel assumes a native process doing an exec
479 547 * in a branded zone is going to run a branded processes.
480 548 * hence we don't support this operation.
481 549 */
482 550 if (cmd == B_EXEC_BRAND)
483 551 return (ENOSYS);
484 552
485 553 /* For all other operations this must be a branded process. */
486 - if (p->p_brand == &native_brand)
554 + if (!PROC_IS_BRANDED(p))
487 555 return (ENOSYS);
488 556
489 557 ASSERT(p->p_brand == pbrand);
490 558 ASSERT(p->p_brand_data != NULL);
491 559
492 560 spd = (brand_proc_data_t *)p->p_brand_data;
493 561
494 562 switch ((cmd)) {
495 563 case B_EXEC_NATIVE:
496 564 err = exec_common((char *)arg1, (const char **)arg2,
497 565 (const char **)arg3, EBA_NATIVE);
498 566 return (err);
499 567
500 568 /*
501 569 * Get the address of the user-space system call handler from
502 570 * the user process and attach it to the proc structure.
503 571 */
504 572 case B_REGISTER:
505 573 if (p->p_model == DATAMODEL_NATIVE) {
506 574 if (copyin((void *)arg1, ®, sizeof (reg)) != 0)
507 575 return (EFAULT);
508 576 }
509 577 #if defined(_LP64)
510 578 else {
511 579 brand_common_reg32_t reg32;
512 580
513 581 if (copyin((void *)arg1, ®32, sizeof (reg32)) != 0)
514 582 return (EFAULT);
515 583 reg.sbr_version = reg32.sbr_version;
516 584 reg.sbr_handler = (caddr_t)(uintptr_t)reg32.sbr_handler;
517 585 }
518 586 #endif /* _LP64 */
519 587
520 588 if (reg.sbr_version != brandvers)
521 589 return (ENOTSUP);
522 590 spd->spd_handler = reg.sbr_handler;
523 591 return (0);
524 592
525 593 case B_ELFDATA:
526 594 if (p->p_model == DATAMODEL_NATIVE) {
527 595 if (copyout(&spd->spd_elf_data, (void *)arg1,
528 596 sizeof (brand_elf_data_t)) != 0)
529 597 return (EFAULT);
530 598 }
531 599 #if defined(_LP64)
532 600 else {
533 601 brand_elf_data32_t sed32;
534 602
535 603 sed32.sed_phdr = spd->spd_elf_data.sed_phdr;
536 604 sed32.sed_phent = spd->spd_elf_data.sed_phent;
537 605 sed32.sed_phnum = spd->spd_elf_data.sed_phnum;
538 606 sed32.sed_entry = spd->spd_elf_data.sed_entry;
539 607 sed32.sed_base = spd->spd_elf_data.sed_base;
540 608 sed32.sed_ldentry = spd->spd_elf_data.sed_ldentry;
541 609 sed32.sed_lddata = spd->spd_elf_data.sed_lddata;
542 610 if (copyout(&sed32, (void *)arg1, sizeof (sed32))
543 611 != 0)
544 612 return (EFAULT);
545 613 }
546 614 #endif /* _LP64 */
547 615 return (0);
548 616
549 617 /*
550 618 * The B_TRUSS_POINT subcommand exists so that we can see
551 619 * truss output from interposed system calls that return
552 620 * without first calling any other system call, meaning they
553 621 * would be invisible to truss(1).
554 622 * If the second argument is set non-zero, set errno to that
555 623 * value as well.
556 624 *
557 625 * Common arguments seen with truss are:
558 626 *
559 627 * arg1: syscall number
560 628 * arg2: errno
561 629 */
562 630 case B_TRUSS_POINT:
563 631 return ((arg2 == 0) ? 0 : set_errno((uint_t)arg2));
564 632 }
565 633
566 634 return (-1);
567 635 }
568 636
569 637 /*ARGSUSED*/
570 638 void
571 639 brand_solaris_copy_procdata(proc_t *child, proc_t *parent, struct brand *pbrand)
572 640 {
573 641 brand_proc_data_t *spd;
574 642
575 643 ASSERT(parent->p_brand == pbrand);
576 644 ASSERT(child->p_brand == pbrand);
577 645 ASSERT(parent->p_brand_data != NULL);
578 646 ASSERT(child->p_brand_data == NULL);
579 647
580 648 /*
581 649 * Just duplicate all the proc data of the parent for the
582 650 * child
583 651 */
584 652 spd = kmem_alloc(sizeof (brand_proc_data_t), KM_SLEEP);
585 653 bcopy(parent->p_brand_data, spd, sizeof (brand_proc_data_t));
586 654 child->p_brand_data = spd;
587 655 }
588 656
589 657 static void
590 658 restoreexecenv(struct execenv *ep, stack_t *sp)
591 659 {
592 660 klwp_t *lwp = ttolwp(curthread);
593 661
|
↓ open down ↓ |
97 lines elided |
↑ open up ↑ |
594 662 setexecenv(ep);
595 663 lwp->lwp_sigaltstack.ss_sp = sp->ss_sp;
596 664 lwp->lwp_sigaltstack.ss_size = sp->ss_size;
597 665 lwp->lwp_sigaltstack.ss_flags = sp->ss_flags;
598 666 }
599 667
600 668 /*ARGSUSED*/
601 669 int
602 670 brand_solaris_elfexec(vnode_t *vp, execa_t *uap, uarg_t *args,
603 671 intpdata_t *idatap, int level, long *execsz, int setid, caddr_t exec_file,
604 - cred_t *cred, int brand_action, struct brand *pbrand, char *bname,
605 - char *brandlib, char *brandlib32, char *brandlinker, char *brandlinker32)
672 + cred_t *cred, int *brand_action, struct brand *pbrand, char *bname,
673 + char *brandlib, char *brandlib32)
606 674 {
607 675
608 676 vnode_t *nvp;
609 677 Ehdr ehdr;
610 678 Addr uphdr_vaddr;
611 679 intptr_t voffset;
612 - int interp;
680 + char *interp;
613 681 int i, err;
614 682 struct execenv env;
615 683 struct execenv origenv;
616 684 stack_t orig_sigaltstack;
617 685 struct user *up = PTOU(curproc);
618 686 proc_t *p = ttoproc(curthread);
619 687 klwp_t *lwp = ttolwp(curthread);
620 688 brand_proc_data_t *spd;
621 689 brand_elf_data_t sed, *sedp;
622 - char *linker;
623 690 uintptr_t lddata; /* lddata of executable's linker */
624 691
625 692 ASSERT(curproc->p_brand == pbrand);
626 693 ASSERT(curproc->p_brand_data != NULL);
627 694
628 695 spd = (brand_proc_data_t *)curproc->p_brand_data;
629 696 sedp = &spd->spd_elf_data;
630 697
631 698 args->brandname = bname;
632 699
633 700 /*
634 701 * We will exec the brand library and then map in the target
635 702 * application and (optionally) the brand's default linker.
636 703 */
637 704 if (args->to_model == DATAMODEL_NATIVE) {
638 705 args->emulator = brandlib;
639 - linker = brandlinker;
640 706 }
641 707 #if defined(_LP64)
642 708 else {
643 709 args->emulator = brandlib32;
644 - linker = brandlinker32;
645 710 }
646 711 #endif /* _LP64 */
647 712
648 713 if ((err = lookupname(args->emulator, UIO_SYSSPACE, FOLLOW,
649 714 NULLVPP, &nvp)) != 0) {
650 715 uprintf("%s: not found.", args->emulator);
651 716 return (err);
652 717 }
653 718
654 719 /*
655 720 * The following elf{32}exec call changes the execenv in the proc
656 721 * struct which includes changing the p_exec member to be the vnode
657 722 * for the brand library (e.g. /.SUNWnative/usr/lib/s10_brand.so.1).
658 723 * We will eventually set the p_exec member to be the vnode for the new
659 724 * executable when we call setexecenv(). However, if we get an error
660 725 * before that call we need to restore the execenv to its original
661 726 * values so that when we return to the caller fop_close() works
662 727 * properly while cleaning up from the failed exec(). Restoring the
663 728 * original value will also properly decrement the 2nd VN_RELE that we
664 729 * took on the brand library.
665 730 */
666 731 origenv.ex_bssbase = p->p_bssbase;
667 732 origenv.ex_brkbase = p->p_brkbase;
668 733 origenv.ex_brksize = p->p_brksize;
669 734 origenv.ex_vp = p->p_exec;
670 735 orig_sigaltstack.ss_sp = lwp->lwp_sigaltstack.ss_sp;
671 736 orig_sigaltstack.ss_size = lwp->lwp_sigaltstack.ss_size;
672 737 orig_sigaltstack.ss_flags = lwp->lwp_sigaltstack.ss_flags;
673 738
674 739 if (args->to_model == DATAMODEL_NATIVE) {
675 740 err = elfexec(nvp, uap, args, idatap, INTP_MAXDEPTH + 1, execsz,
676 741 setid, exec_file, cred, brand_action);
677 742 }
678 743 #if defined(_LP64)
679 744 else {
680 745 err = elf32exec(nvp, uap, args, idatap, INTP_MAXDEPTH + 1,
681 746 execsz, setid, exec_file, cred, brand_action);
682 747 }
683 748 #endif /* _LP64 */
684 749 VN_RELE(nvp);
685 750 if (err != 0) {
686 751 restoreexecenv(&origenv, &orig_sigaltstack);
687 752 return (err);
688 753 }
689 754
690 755 /*
691 756 * The u_auxv veCTors are set up by elfexec to point to the
692 757 * brand emulation library and linker. Save these so they can
693 758 * be copied to the specific brand aux vectors.
694 759 */
695 760 bzero(&sed, sizeof (sed));
696 761 for (i = 0; i < __KERN_NAUXV_IMPL; i++) {
697 762 switch (up->u_auxv[i].a_type) {
698 763 case AT_SUN_LDDATA:
699 764 sed.sed_lddata = up->u_auxv[i].a_un.a_val;
700 765 break;
701 766 case AT_BASE:
702 767 sed.sed_base = up->u_auxv[i].a_un.a_val;
703 768 break;
704 769 case AT_ENTRY:
705 770 sed.sed_entry = up->u_auxv[i].a_un.a_val;
706 771 break;
707 772 case AT_PHDR:
708 773 sed.sed_phdr = up->u_auxv[i].a_un.a_val;
709 774 break;
710 775 case AT_PHENT:
711 776 sed.sed_phent = up->u_auxv[i].a_un.a_val;
712 777 break;
713 778 case AT_PHNUM:
714 779 sed.sed_phnum = up->u_auxv[i].a_un.a_val;
715 780 break;
716 781 default:
717 782 break;
|
↓ open down ↓ |
63 lines elided |
↑ open up ↑ |
718 783 }
719 784 }
720 785 /* Make sure the emulator has an entry point */
721 786 ASSERT(sed.sed_entry != NULL);
722 787 ASSERT(sed.sed_phdr != NULL);
723 788
724 789 bzero(&env, sizeof (env));
725 790 if (args->to_model == DATAMODEL_NATIVE) {
726 791 err = mapexec_brand(vp, args, &ehdr, &uphdr_vaddr,
727 792 &voffset, exec_file, &interp, &env.ex_bssbase,
728 - &env.ex_brkbase, &env.ex_brksize, NULL);
793 + &env.ex_brkbase, &env.ex_brksize, NULL, NULL);
729 794 }
730 795 #if defined(_LP64)
731 796 else {
732 797 Elf32_Ehdr ehdr32;
733 798 Elf32_Addr uphdr_vaddr32;
734 799 err = mapexec32_brand(vp, args, &ehdr32, &uphdr_vaddr32,
735 800 &voffset, exec_file, &interp, &env.ex_bssbase,
736 - &env.ex_brkbase, &env.ex_brksize, NULL);
801 + &env.ex_brkbase, &env.ex_brksize, NULL, NULL);
737 802 Ehdr32to64(&ehdr32, &ehdr);
738 803
739 804 if (uphdr_vaddr32 == (Elf32_Addr)-1)
740 805 uphdr_vaddr = (Addr)-1;
741 806 else
742 807 uphdr_vaddr = uphdr_vaddr32;
743 808 }
744 809 #endif /* _LP64 */
745 810 if (err != 0) {
746 811 restoreexecenv(&origenv, &orig_sigaltstack);
812 +
813 + if (interp != NULL)
814 + kmem_free(interp, MAXPATHLEN);
815 +
747 816 return (err);
748 817 }
749 818
750 819 /*
751 820 * Save off the important properties of the executable. The
752 821 * brand library will ask us for this data later, when it is
753 822 * initializing and getting ready to transfer control to the
754 823 * brand application.
755 824 */
756 825 if (uphdr_vaddr == (Addr)-1)
757 826 sedp->sed_phdr = voffset + ehdr.e_phoff;
758 827 else
759 828 sedp->sed_phdr = voffset + uphdr_vaddr;
760 829 sedp->sed_entry = voffset + ehdr.e_entry;
761 830 sedp->sed_phent = ehdr.e_phentsize;
762 831 sedp->sed_phnum = ehdr.e_phnum;
763 832
764 - if (interp) {
833 + if (interp != NULL) {
765 834 if (ehdr.e_type == ET_DYN) {
766 835 /*
767 836 * This is a shared object executable, so we
768 837 * need to pick a reasonable place to put the
769 838 * heap. Just don't use the first page.
770 839 */
771 840 env.ex_brkbase = (caddr_t)PAGESIZE;
772 841 env.ex_bssbase = (caddr_t)PAGESIZE;
773 842 }
774 843
775 844 /*
776 845 * If the program needs an interpreter (most do), map
777 846 * it in and store relevant information about it in the
778 847 * aux vector, where the brand library can find it.
779 848 */
780 - if ((err = lookupname(linker, UIO_SYSSPACE,
849 + if ((err = lookupname(interp, UIO_SYSSPACE,
781 850 FOLLOW, NULLVPP, &nvp)) != 0) {
782 - uprintf("%s: not found.", brandlinker);
851 + uprintf("%s: not found.", interp);
783 852 restoreexecenv(&origenv, &orig_sigaltstack);
853 + kmem_free(interp, MAXPATHLEN);
784 854 return (err);
785 855 }
856 +
857 + kmem_free(interp, MAXPATHLEN);
858 +
786 859 if (args->to_model == DATAMODEL_NATIVE) {
787 860 err = mapexec_brand(nvp, args, &ehdr,
788 861 &uphdr_vaddr, &voffset, exec_file, &interp,
789 - NULL, NULL, NULL, &lddata);
862 + NULL, NULL, NULL, &lddata, NULL);
790 863 }
791 864 #if defined(_LP64)
792 865 else {
793 866 Elf32_Ehdr ehdr32;
794 867 Elf32_Addr uphdr_vaddr32;
795 868 err = mapexec32_brand(nvp, args, &ehdr32,
796 869 &uphdr_vaddr32, &voffset, exec_file, &interp,
797 - NULL, NULL, NULL, &lddata);
870 + NULL, NULL, NULL, &lddata, NULL);
798 871 Ehdr32to64(&ehdr32, &ehdr);
799 872
800 873 if (uphdr_vaddr32 == (Elf32_Addr)-1)
801 874 uphdr_vaddr = (Addr)-1;
802 875 else
803 876 uphdr_vaddr = uphdr_vaddr32;
804 877 }
805 878 #endif /* _LP64 */
806 879 VN_RELE(nvp);
807 880 if (err != 0) {
808 881 restoreexecenv(&origenv, &orig_sigaltstack);
809 882 return (err);
810 883 }
811 884
812 885 /*
813 886 * Now that we know the base address of the brand's
814 887 * linker, place it in the aux vector.
815 888 */
816 889 sedp->sed_base = voffset;
817 890 sedp->sed_ldentry = voffset + ehdr.e_entry;
818 891 sedp->sed_lddata = voffset + lddata;
819 892 } else {
820 893 /*
821 894 * This program has no interpreter. The brand library
822 895 * will jump to the address in the AT_SUN_BRAND_LDENTRY
823 896 * aux vector, so in this case, put the entry point of
824 897 * the main executable there.
825 898 */
826 899 if (ehdr.e_type == ET_EXEC) {
827 900 /*
828 901 * An executable with no interpreter, this must
829 902 * be a statically linked executable, which
830 903 * means we loaded it at the address specified
831 904 * in the elf header, in which case the e_entry
832 905 * field of the elf header is an absolute
833 906 * address.
834 907 */
835 908 sedp->sed_ldentry = ehdr.e_entry;
836 909 sedp->sed_entry = ehdr.e_entry;
837 910 sedp->sed_lddata = NULL;
838 911 sedp->sed_base = NULL;
839 912 } else {
840 913 /*
841 914 * A shared object with no interpreter, we use
842 915 * the calculated address from above.
843 916 */
844 917 sedp->sed_ldentry = sedp->sed_entry;
845 918 sedp->sed_entry = NULL;
846 919 sedp->sed_phdr = NULL;
847 920 sedp->sed_phent = NULL;
848 921 sedp->sed_phnum = NULL;
849 922 sedp->sed_lddata = NULL;
850 923 sedp->sed_base = voffset;
851 924
852 925 if (ehdr.e_type == ET_DYN) {
853 926 /*
854 927 * Delay setting the brkbase until the
855 928 * first call to brk(); see elfexec()
856 929 * for details.
857 930 */
858 931 env.ex_bssbase = (caddr_t)0;
859 932 env.ex_brkbase = (caddr_t)0;
860 933 env.ex_brksize = 0;
861 934 }
862 935 }
863 936 }
864 937
865 938 env.ex_magic = elfmagic;
866 939 env.ex_vp = vp;
867 940 setexecenv(&env);
868 941
869 942 /*
870 943 * It's time to manipulate the process aux vectors. First
871 944 * we need to update the AT_SUN_AUXFLAGS aux vector to set
872 945 * the AF_SUN_NOPLM flag.
873 946 */
874 947 if (args->to_model == DATAMODEL_NATIVE) {
875 948 auxv_t auxflags_auxv;
876 949
877 950 if (copyin(args->auxp_auxflags, &auxflags_auxv,
878 951 sizeof (auxflags_auxv)) != 0)
879 952 return (EFAULT);
880 953
881 954 ASSERT(auxflags_auxv.a_type == AT_SUN_AUXFLAGS);
882 955 auxflags_auxv.a_un.a_val |= AF_SUN_NOPLM;
883 956 if (copyout(&auxflags_auxv, args->auxp_auxflags,
884 957 sizeof (auxflags_auxv)) != 0)
885 958 return (EFAULT);
886 959 }
887 960 #if defined(_LP64)
888 961 else {
889 962 auxv32_t auxflags_auxv32;
890 963
891 964 if (copyin(args->auxp_auxflags, &auxflags_auxv32,
892 965 sizeof (auxflags_auxv32)) != 0)
893 966 return (EFAULT);
894 967
895 968 ASSERT(auxflags_auxv32.a_type == AT_SUN_AUXFLAGS);
896 969 auxflags_auxv32.a_un.a_val |= AF_SUN_NOPLM;
897 970 if (copyout(&auxflags_auxv32, args->auxp_auxflags,
898 971 sizeof (auxflags_auxv32)) != 0)
899 972 return (EFAULT);
900 973 }
901 974 #endif /* _LP64 */
902 975
903 976 /* Second, copy out the brand specific aux vectors. */
904 977 if (args->to_model == DATAMODEL_NATIVE) {
905 978 auxv_t brand_auxv[] = {
906 979 { AT_SUN_BRAND_AUX1, 0 },
907 980 { AT_SUN_BRAND_AUX2, 0 },
908 981 { AT_SUN_BRAND_AUX3, 0 }
909 982 };
910 983
911 984 ASSERT(brand_auxv[0].a_type ==
912 985 AT_SUN_BRAND_COMMON_LDDATA);
913 986 brand_auxv[0].a_un.a_val = sed.sed_lddata;
914 987
915 988 if (copyout(&brand_auxv, args->auxp_brand,
916 989 sizeof (brand_auxv)) != 0)
917 990 return (EFAULT);
918 991 }
919 992 #if defined(_LP64)
920 993 else {
921 994 auxv32_t brand_auxv32[] = {
922 995 { AT_SUN_BRAND_AUX1, 0 },
923 996 { AT_SUN_BRAND_AUX2, 0 },
924 997 { AT_SUN_BRAND_AUX3, 0 }
925 998 };
926 999
|
↓ open down ↓ |
119 lines elided |
↑ open up ↑ |
927 1000 ASSERT(brand_auxv32[0].a_type == AT_SUN_BRAND_COMMON_LDDATA);
928 1001 brand_auxv32[0].a_un.a_val = (uint32_t)sed.sed_lddata;
929 1002 if (copyout(&brand_auxv32, args->auxp_brand,
930 1003 sizeof (brand_auxv32)) != 0)
931 1004 return (EFAULT);
932 1005 }
933 1006 #endif /* _LP64 */
934 1007
935 1008 /*
936 1009 * Third, the /proc aux vectors set up by elfexec() point to
937 - * brand emulation library and it's linker. Copy these to the
1010 + * brand emulation library and its linker. Copy these to the
938 1011 * /proc brand specific aux vector, and update the regular
939 - * /proc aux vectors to point to the executable (and it's
1012 + * /proc aux vectors to point to the executable (and its
940 1013 * linker). This will enable debuggers to access the
941 1014 * executable via the usual /proc or elf notes aux vectors.
942 1015 *
943 1016 * The brand emulation library's linker will get it's aux
944 1017 * vectors off the stack, and then update the stack with the
945 1018 * executable's aux vectors before jumping to the executable's
946 1019 * linker.
947 1020 *
948 1021 * Debugging the brand emulation library must be done from
949 1022 * the global zone, where the librtld_db module knows how to
950 1023 * fetch the brand specific aux vectors to access the brand
951 1024 * emulation libraries linker.
952 1025 */
953 1026 for (i = 0; i < __KERN_NAUXV_IMPL; i++) {
954 1027 ulong_t val;
955 1028
956 1029 switch (up->u_auxv[i].a_type) {
957 1030 case AT_SUN_BRAND_COMMON_LDDATA:
958 1031 up->u_auxv[i].a_un.a_val = sed.sed_lddata;
959 1032 continue;
960 1033 case AT_BASE:
961 1034 val = sedp->sed_base;
962 1035 break;
963 1036 case AT_ENTRY:
964 1037 val = sedp->sed_entry;
965 1038 break;
966 1039 case AT_PHDR:
967 1040 val = sedp->sed_phdr;
968 1041 break;
969 1042 case AT_PHENT:
970 1043 val = sedp->sed_phent;
971 1044 break;
972 1045 case AT_PHNUM:
973 1046 val = sedp->sed_phnum;
974 1047 break;
975 1048 case AT_SUN_LDDATA:
976 1049 val = sedp->sed_lddata;
977 1050 break;
978 1051 default:
979 1052 continue;
980 1053 }
981 1054
982 1055 up->u_auxv[i].a_un.a_val = val;
983 1056 if (val == NULL) {
984 1057 /* Hide the entry for static binaries */
985 1058 up->u_auxv[i].a_type = AT_IGNORE;
986 1059 }
987 1060 }
988 1061
989 1062 /*
990 1063 * The last thing we do here is clear spd->spd_handler. This
991 1064 * is important because if we're already a branded process and
992 1065 * if this exec succeeds, there is a window between when the
993 1066 * exec() first returns to the userland of the new process and
994 1067 * when our brand library get's initialized, during which we
995 1068 * don't want system calls to be re-directed to our brand
996 1069 * library since it hasn't been initialized yet.
997 1070 */
998 1071 spd->spd_handler = NULL;
999 1072
1000 1073 return (0);
1001 1074 }
1002 1075
1003 1076 void
1004 1077 brand_solaris_exec(struct brand *pbrand)
1005 1078 {
1006 1079 brand_proc_data_t *spd = curproc->p_brand_data;
1007 1080
1008 1081 ASSERT(curproc->p_brand == pbrand);
1009 1082 ASSERT(curproc->p_brand_data != NULL);
1010 1083 ASSERT(ttolwp(curthread)->lwp_brand != NULL);
1011 1084
1012 1085 /*
1013 1086 * We should only be called from exec(), when we know the process
1014 1087 * is single-threaded.
1015 1088 */
1016 1089 ASSERT(curproc->p_tlist == curproc->p_tlist->t_forw);
1017 1090
1018 1091 /* Upon exec, reset our lwp brand data. */
1019 1092 (void) brand_solaris_freelwp(ttolwp(curthread), pbrand);
1020 1093 (void) brand_solaris_initlwp(ttolwp(curthread), pbrand);
1021 1094
1022 1095 /*
1023 1096 * Upon exec, reset all the proc brand data, except for the elf
1024 1097 * data associated with the executable we are exec'ing.
1025 1098 */
1026 1099 spd->spd_handler = NULL;
1027 1100 }
1028 1101
1029 1102 int
1030 1103 brand_solaris_fini(char **emul_table, struct modlinkage *modlinkage,
1031 1104 struct brand *pbrand)
1032 1105 {
1033 1106 int err;
1034 1107
1035 1108 /*
1036 1109 * If there are any zones using this brand, we can't allow it
1037 1110 * to be unloaded.
1038 1111 */
1039 1112 if (brand_zone_count(pbrand))
1040 1113 return (EBUSY);
1041 1114
1042 1115 kmem_free(*emul_table, NSYSCALL);
1043 1116 *emul_table = NULL;
1044 1117
1045 1118 err = mod_remove(modlinkage);
1046 1119 if (err)
1047 1120 cmn_err(CE_WARN, "Couldn't unload brand module");
1048 1121
1049 1122 return (err);
1050 1123 }
1051 1124
1052 1125 /*ARGSUSED*/
1053 1126 void
1054 1127 brand_solaris_forklwp(klwp_t *p, klwp_t *c, struct brand *pbrand)
1055 1128 {
1056 1129 ASSERT(p->lwp_procp->p_brand == pbrand);
1057 1130 ASSERT(c->lwp_procp->p_brand == pbrand);
1058 1131
1059 1132 ASSERT(p->lwp_procp->p_brand_data != NULL);
1060 1133 ASSERT(c->lwp_procp->p_brand_data != NULL);
1061 1134
1062 1135 /*
1063 1136 * Both LWPs have already had been initialized via
1064 1137 * brand_solaris_initlwp().
1065 1138 */
1066 1139 ASSERT(p->lwp_brand != NULL);
1067 1140 ASSERT(c->lwp_brand != NULL);
1068 1141 }
1069 1142
1070 1143 /*ARGSUSED*/
|
↓ open down ↓ |
121 lines elided |
↑ open up ↑ |
1071 1144 void
1072 1145 brand_solaris_freelwp(klwp_t *l, struct brand *pbrand)
1073 1146 {
1074 1147 ASSERT(l->lwp_procp->p_brand == pbrand);
1075 1148 ASSERT(l->lwp_procp->p_brand_data != NULL);
1076 1149 ASSERT(l->lwp_brand != NULL);
1077 1150 l->lwp_brand = NULL;
1078 1151 }
1079 1152
1080 1153 /*ARGSUSED*/
1081 -int
1154 +void
1082 1155 brand_solaris_initlwp(klwp_t *l, struct brand *pbrand)
1083 1156 {
1084 1157 ASSERT(l->lwp_procp->p_brand == pbrand);
1085 1158 ASSERT(l->lwp_procp->p_brand_data != NULL);
1086 1159 ASSERT(l->lwp_brand == NULL);
1087 1160 l->lwp_brand = (void *)-1;
1088 - return (0);
1089 1161 }
1090 1162
1091 1163 /*ARGSUSED*/
1092 1164 void
1093 1165 brand_solaris_lwpexit(klwp_t *l, struct brand *pbrand)
1094 1166 {
1095 - proc_t *p = l->lwp_procp;
1096 -
1097 1167 ASSERT(l->lwp_procp->p_brand == pbrand);
1098 1168 ASSERT(l->lwp_procp->p_brand_data != NULL);
1099 1169 ASSERT(l->lwp_brand != NULL);
1100 -
1101 - /*
1102 - * We should never be called for the last thread in a process.
1103 - * (That case is handled by brand_solaris_proc_exit().)
1104 - * Therefore this lwp must be exiting from a multi-threaded
1105 - * process.
1106 - */
1107 - ASSERT(p->p_tlist != p->p_tlist->t_forw);
1108 -
1109 - l->lwp_brand = NULL;
1110 1170 }
1111 1171
1112 1172 /*ARGSUSED*/
1113 1173 void
1114 -brand_solaris_proc_exit(struct proc *p, klwp_t *l, struct brand *pbrand)
1174 +brand_solaris_proc_exit(struct proc *p, struct brand *pbrand)
1115 1175 {
1116 1176 ASSERT(p->p_brand == pbrand);
1117 1177 ASSERT(p->p_brand_data != NULL);
1118 1178
1119 - /*
1120 - * When called from proc_exit(), we know that process is
1121 - * single-threaded and free our lwp brand data.
1122 - * otherwise just free p_brand_data and return.
1123 - */
1124 - if (l != NULL) {
1125 - ASSERT(p->p_tlist == p->p_tlist->t_forw);
1126 - ASSERT(p->p_tlist->t_lwp == l);
1127 - (void) brand_solaris_freelwp(l, pbrand);
1128 - }
1129 -
1130 1179 /* upon exit, free our proc brand data */
1131 1180 kmem_free(p->p_brand_data, sizeof (brand_proc_data_t));
1132 1181 p->p_brand_data = NULL;
1133 1182 }
1134 1183
1135 1184 void
1136 1185 brand_solaris_setbrand(proc_t *p, struct brand *pbrand)
1137 1186 {
1138 1187 ASSERT(p->p_brand == pbrand);
1139 1188 ASSERT(p->p_brand_data == NULL);
1140 1189
1141 1190 /*
1142 1191 * We should only be called from exec(), when we know the process
1143 1192 * is single-threaded.
1144 1193 */
1145 1194 ASSERT(p->p_tlist == p->p_tlist->t_forw);
1146 1195
1147 1196 p->p_brand_data = kmem_zalloc(sizeof (brand_proc_data_t), KM_SLEEP);
1148 - (void) brand_solaris_initlwp(p->p_tlist->t_lwp, pbrand);
1149 1197 }
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX