1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #include <sys/errno.h> 27 #include <sys/exec.h> 28 #include <sys/kmem.h> 29 #include <sys/modctl.h> 30 #include <sys/model.h> 31 #include <sys/proc.h> 32 #include <sys/syscall.h> 33 #include <sys/systm.h> 34 #include <sys/thread.h> 35 #include <sys/cmn_err.h> 36 #include <sys/archsystm.h> 37 #include <sys/pathname.h> 38 39 #include <sys/machbrand.h> 40 #include <sys/brand.h> 41 #include "sn1_brand.h" 42 43 char *sn1_emulation_table = NULL; 44 45 void sn1_init_brand_data(zone_t *); 46 void sn1_free_brand_data(zone_t *); 47 void sn1_setbrand(proc_t *); 48 int sn1_getattr(zone_t *, int, void *, size_t *); 49 int sn1_setattr(zone_t *, int, void *, size_t); 50 int sn1_brandsys(int, int64_t *, uintptr_t, uintptr_t, uintptr_t, 51 uintptr_t, uintptr_t, uintptr_t); 52 void sn1_copy_procdata(proc_t *, proc_t *); 53 void sn1_proc_exit(struct proc *, klwp_t *); 54 void sn1_exec(); 55 int sn1_initlwp(klwp_t *); 56 void sn1_forklwp(klwp_t *, klwp_t *); 57 void sn1_freelwp(klwp_t *); 58 void sn1_lwpexit(klwp_t *); 59 int sn1_elfexec(vnode_t *, execa_t *, uarg_t *, intpdata_t *, int, 60 long *, int, caddr_t, cred_t *, int); 61 62 /* sn1 brand */ 63 struct brand_ops sn1_brops = { 64 sn1_init_brand_data, 65 sn1_free_brand_data, 66 sn1_brandsys, 67 sn1_setbrand, 68 sn1_getattr, 69 sn1_setattr, 70 sn1_copy_procdata, 71 sn1_proc_exit, 72 sn1_exec, 73 lwp_setrval, 74 sn1_initlwp, 75 sn1_forklwp, 76 sn1_freelwp, 77 sn1_lwpexit, 78 sn1_elfexec 79 }; 80 81 #ifdef sparc 82 83 struct brand_mach_ops sn1_mops = { 84 sn1_brand_syscall_callback, 85 sn1_brand_syscall32_callback 86 }; 87 88 #else /* sparc */ 89 90 #ifdef __amd64 91 92 struct brand_mach_ops sn1_mops = { 93 sn1_brand_sysenter_callback, 94 NULL, 95 sn1_brand_int91_callback, 96 sn1_brand_syscall_callback, 97 sn1_brand_syscall32_callback, 98 NULL 99 }; 100 101 #else /* ! __amd64 */ 102 103 struct brand_mach_ops sn1_mops = { 104 sn1_brand_sysenter_callback, 105 NULL, 106 NULL, 107 sn1_brand_syscall_callback, 108 NULL, 109 NULL 110 }; 111 #endif /* __amd64 */ 112 113 #endif /* _sparc */ 114 115 struct brand sn1_brand = { 116 BRAND_VER_1, 117 "sn1", 118 &sn1_brops, 119 &sn1_mops 120 }; 121 122 static struct modlbrand modlbrand = { 123 &mod_brandops, /* type of module */ 124 "Solaris N-1 Brand", /* description of module */ 125 &sn1_brand /* driver ops */ 126 }; 127 128 static struct modlinkage modlinkage = { 129 MODREV_1, (void *)&modlbrand, NULL 130 }; 131 132 void 133 sn1_setbrand(proc_t *p) 134 { 135 ASSERT(p->p_brand == &sn1_brand); 136 ASSERT(p->p_brand_data == NULL); 137 138 /* 139 * We should only be called from exec(), when we know the process 140 * is single-threaded. 141 */ 142 ASSERT(p->p_tlist == p->p_tlist->t_forw); 143 144 p->p_brand_data = kmem_zalloc(sizeof (sn1_proc_data_t), KM_SLEEP); 145 (void) sn1_initlwp(p->p_tlist->t_lwp); 146 } 147 148 /* ARGSUSED */ 149 int 150 sn1_getattr(zone_t *zone, int attr, void *buf, size_t *bufsize) 151 { 152 return (EINVAL); 153 } 154 155 /* ARGSUSED */ 156 int 157 sn1_setattr(zone_t *zone, int attr, void *buf, size_t bufsize) 158 { 159 return (EINVAL); 160 } 161 162 /* 163 * Get the address of the user-space system call handler from the user 164 * process and attach it to the proc structure. 165 */ 166 /*ARGSUSED*/ 167 int 168 sn1_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2, 169 uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, uintptr_t arg6) 170 { 171 sn1_proc_data_t *spd; 172 sn1_brand_reg_t reg; 173 proc_t *p = curproc; 174 int err; 175 176 *rval = 0; 177 178 /* 179 * There is one operation that is suppored for non-branded 180 * process. B_EXEC_BRAND. This brand operaion is redundant 181 * since the kernel assumes a native process doing an exec 182 * in a branded zone is going to run a branded processes. 183 * hence we don't support this operation. 184 */ 185 if (cmd == B_EXEC_BRAND) 186 return (ENOSYS); 187 188 /* For all other operations this must be a branded process. */ 189 if (p->p_brand == &native_brand) 190 return (ENOSYS); 191 192 ASSERT(p->p_brand == &sn1_brand); 193 ASSERT(p->p_brand_data != NULL); 194 195 spd = (sn1_proc_data_t *)p->p_brand_data; 196 197 switch (cmd) { 198 case B_EXEC_NATIVE: 199 err = exec_common( 200 (char *)arg1, (const char **)arg2, (const char **)arg3, 201 EBA_NATIVE); 202 return (err); 203 204 case B_REGISTER: 205 if (p->p_model == DATAMODEL_NATIVE) { 206 if (copyin((void *)arg1, ®, sizeof (reg)) != 0) 207 return (EFAULT); 208 #if defined(_LP64) 209 } else { 210 sn1_brand_reg32_t reg32; 211 212 if (copyin((void *)arg1, ®32, sizeof (reg32)) != 0) 213 return (EFAULT); 214 reg.sbr_version = reg32.sbr_version; 215 reg.sbr_handler = (caddr_t)(uintptr_t)reg32.sbr_handler; 216 #endif /* _LP64 */ 217 } 218 219 if (reg.sbr_version != SN1_VERSION) 220 return (ENOTSUP); 221 spd->spd_handler = reg.sbr_handler; 222 return (0); 223 case B_ELFDATA: 224 if (p->p_model == DATAMODEL_NATIVE) { 225 if (copyout(&spd->spd_elf_data, (void *)arg1, 226 sizeof (sn1_elf_data_t)) != 0) 227 return (EFAULT); 228 #if defined(_LP64) 229 } else { 230 sn1_elf_data32_t sed32; 231 232 sed32.sed_phdr = spd->spd_elf_data.sed_phdr; 233 sed32.sed_phent = spd->spd_elf_data.sed_phent; 234 sed32.sed_phnum = spd->spd_elf_data.sed_phnum; 235 sed32.sed_entry = spd->spd_elf_data.sed_entry; 236 sed32.sed_base = spd->spd_elf_data.sed_base; 237 sed32.sed_ldentry = spd->spd_elf_data.sed_ldentry; 238 sed32.sed_lddata = spd->spd_elf_data.sed_lddata; 239 if (copyout(&sed32, (void *)arg1, sizeof (sed32)) != 0) 240 return (EFAULT); 241 #endif /* _LP64 */ 242 } 243 return (0); 244 } 245 246 return (EINVAL); 247 } 248 249 /* 250 * Copy the per-process brand data from a parent proc to a child. 251 */ 252 void 253 sn1_copy_procdata(proc_t *child, proc_t *parent) 254 { 255 sn1_proc_data_t *spd; 256 257 ASSERT(parent->p_brand == &sn1_brand); 258 ASSERT(child->p_brand == &sn1_brand); 259 ASSERT(parent->p_brand_data != NULL); 260 ASSERT(child->p_brand_data == NULL); 261 262 /* Just duplicate all the proc data of the parent for the child */ 263 spd = kmem_alloc(sizeof (sn1_proc_data_t), KM_SLEEP); 264 bcopy(parent->p_brand_data, spd, sizeof (sn1_proc_data_t)); 265 child->p_brand_data = spd; 266 } 267 268 /*ARGSUSED*/ 269 void 270 sn1_proc_exit(struct proc *p, klwp_t *l) 271 { 272 ASSERT(p->p_brand == &sn1_brand); 273 ASSERT(p->p_brand_data != NULL); 274 275 /* 276 * We should only be called from proc_exit(), when we know that 277 * process is single-threaded. 278 */ 279 ASSERT(p->p_tlist == p->p_tlist->t_forw); 280 281 /* upon exit, free our lwp brand data */ 282 (void) sn1_freelwp(ttolwp(curthread)); 283 284 /* upon exit, free our proc brand data */ 285 kmem_free(p->p_brand_data, sizeof (sn1_proc_data_t)); 286 p->p_brand_data = NULL; 287 } 288 289 void 290 sn1_exec() 291 { 292 sn1_proc_data_t *spd = curproc->p_brand_data; 293 294 ASSERT(curproc->p_brand == &sn1_brand); 295 ASSERT(curproc->p_brand_data != NULL); 296 ASSERT(ttolwp(curthread)->lwp_brand != NULL); 297 298 /* 299 * We should only be called from exec(), when we know the process 300 * is single-threaded. 301 */ 302 ASSERT(curproc->p_tlist == curproc->p_tlist->t_forw); 303 304 /* Upon exec, reset our lwp brand data. */ 305 (void) sn1_freelwp(ttolwp(curthread)); 306 (void) sn1_initlwp(ttolwp(curthread)); 307 308 /* 309 * Upon exec, reset all the proc brand data, except for the elf 310 * data associated with the executable we are exec'ing. 311 */ 312 spd->spd_handler = NULL; 313 } 314 315 /*ARGSUSED*/ 316 int 317 sn1_initlwp(klwp_t *l) 318 { 319 ASSERT(l->lwp_procp->p_brand == &sn1_brand); 320 ASSERT(l->lwp_procp->p_brand_data != NULL); 321 ASSERT(l->lwp_brand == NULL); 322 l->lwp_brand = (void *)-1; 323 return (0); 324 } 325 326 /*ARGSUSED*/ 327 void 328 sn1_forklwp(klwp_t *p, klwp_t *c) 329 { 330 ASSERT(p->lwp_procp->p_brand == &sn1_brand); 331 ASSERT(c->lwp_procp->p_brand == &sn1_brand); 332 333 ASSERT(p->lwp_procp->p_brand_data != NULL); 334 ASSERT(c->lwp_procp->p_brand_data != NULL); 335 336 /* Both LWPs have already had been initialized via sn1_initlwp() */ 337 ASSERT(p->lwp_brand != NULL); 338 ASSERT(c->lwp_brand != NULL); 339 } 340 341 /*ARGSUSED*/ 342 void 343 sn1_freelwp(klwp_t *l) 344 { 345 ASSERT(l->lwp_procp->p_brand == &sn1_brand); 346 ASSERT(l->lwp_procp->p_brand_data != NULL); 347 ASSERT(l->lwp_brand != NULL); 348 l->lwp_brand = NULL; 349 } 350 351 /*ARGSUSED*/ 352 void 353 sn1_lwpexit(klwp_t *l) 354 { 355 proc_t *p = l->lwp_procp; 356 357 ASSERT(l->lwp_procp->p_brand == &sn1_brand); 358 ASSERT(l->lwp_procp->p_brand_data != NULL); 359 ASSERT(l->lwp_brand != NULL); 360 361 /* 362 * We should never be called for the last thread in a process. 363 * (That case is handled by sn1_proc_exit().) There for this lwp 364 * must be exiting from a multi-threaded process. 365 */ 366 ASSERT(p->p_tlist != p->p_tlist->t_forw); 367 368 l->lwp_brand = NULL; 369 } 370 371 /*ARGSUSED*/ 372 void 373 sn1_free_brand_data(zone_t *zone) 374 { 375 } 376 377 /*ARGSUSED*/ 378 void 379 sn1_init_brand_data(zone_t *zone) 380 { 381 } 382 383 #if defined(_LP64) 384 static void 385 Ehdr32to64(Elf32_Ehdr *src, Ehdr *dst) 386 { 387 bcopy(src->e_ident, dst->e_ident, sizeof (src->e_ident)); 388 dst->e_type = src->e_type; 389 dst->e_machine = src->e_machine; 390 dst->e_version = src->e_version; 391 dst->e_entry = src->e_entry; 392 dst->e_phoff = src->e_phoff; 393 dst->e_shoff = src->e_shoff; 394 dst->e_flags = src->e_flags; 395 dst->e_ehsize = src->e_ehsize; 396 dst->e_phentsize = src->e_phentsize; 397 dst->e_phnum = src->e_phnum; 398 dst->e_shentsize = src->e_shentsize; 399 dst->e_shnum = src->e_shnum; 400 dst->e_shstrndx = src->e_shstrndx; 401 } 402 #endif /* _LP64 */ 403 404 int 405 sn1_elfexec(vnode_t *vp, execa_t *uap, uarg_t *args, intpdata_t *idatap, 406 int level, long *execsz, int setid, caddr_t exec_file, cred_t *cred, 407 int brand_action) 408 { 409 vnode_t *nvp; 410 Ehdr ehdr; 411 Addr uphdr_vaddr; 412 intptr_t voffset; 413 int interp; 414 int i, err; 415 struct execenv env; 416 struct user *up = PTOU(curproc); 417 sn1_proc_data_t *spd; 418 sn1_elf_data_t sed, *sedp; 419 char *linker; 420 uintptr_t lddata; /* lddata of executable's linker */ 421 422 ASSERT(curproc->p_brand == &sn1_brand); 423 ASSERT(curproc->p_brand_data != NULL); 424 425 spd = (sn1_proc_data_t *)curproc->p_brand_data; 426 sedp = &spd->spd_elf_data; 427 428 args->brandname = SN1_BRANDNAME; 429 430 /* 431 * We will exec the brand library and then map in the target 432 * application and (optionally) the brand's default linker. 433 */ 434 if (args->to_model == DATAMODEL_NATIVE) { 435 args->emulator = SN1_LIB; 436 linker = SN1_LINKER; 437 #if defined(_LP64) 438 } else { 439 args->emulator = SN1_LIB32; 440 linker = SN1_LINKER32; 441 #endif /* _LP64 */ 442 } 443 444 if ((err = lookupname(args->emulator, UIO_SYSSPACE, FOLLOW, NULLVPP, 445 &nvp)) != 0) { 446 uprintf("%s: not found.", args->emulator); 447 return (err); 448 } 449 450 if (args->to_model == DATAMODEL_NATIVE) { 451 err = elfexec(nvp, uap, args, idatap, level + 1, execsz, 452 setid, exec_file, cred, brand_action); 453 #if defined(_LP64) 454 } else { 455 err = elf32exec(nvp, uap, args, idatap, level + 1, execsz, 456 setid, exec_file, cred, brand_action); 457 #endif /* _LP64 */ 458 } 459 VN_RELE(nvp); 460 if (err != 0) 461 return (err); 462 463 /* 464 * The u_auxv vectors are set up by elfexec to point to the brand 465 * emulation library and linker. Save these so they can be copied to 466 * the specific brand aux vectors. 467 */ 468 bzero(&sed, sizeof (sed)); 469 for (i = 0; i < __KERN_NAUXV_IMPL; i++) { 470 switch (up->u_auxv[i].a_type) { 471 case AT_SUN_LDDATA: 472 sed.sed_lddata = up->u_auxv[i].a_un.a_val; 473 break; 474 case AT_BASE: 475 sed.sed_base = up->u_auxv[i].a_un.a_val; 476 break; 477 case AT_ENTRY: 478 sed.sed_entry = up->u_auxv[i].a_un.a_val; 479 break; 480 case AT_PHDR: 481 sed.sed_phdr = up->u_auxv[i].a_un.a_val; 482 break; 483 case AT_PHENT: 484 sed.sed_phent = up->u_auxv[i].a_un.a_val; 485 break; 486 case AT_PHNUM: 487 sed.sed_phnum = up->u_auxv[i].a_un.a_val; 488 break; 489 default: 490 break; 491 } 492 } 493 /* Make sure the emulator has an entry point */ 494 ASSERT(sed.sed_entry != NULL); 495 ASSERT(sed.sed_phdr != NULL); 496 497 bzero(&env, sizeof (env)); 498 if (args->to_model == DATAMODEL_NATIVE) { 499 err = mapexec_brand(vp, args, &ehdr, &uphdr_vaddr, &voffset, 500 exec_file, &interp, &env.ex_bssbase, &env.ex_brkbase, 501 &env.ex_brksize, NULL); 502 #if defined(_LP64) 503 } else { 504 Elf32_Ehdr ehdr32; 505 Elf32_Addr uphdr_vaddr32; 506 err = mapexec32_brand(vp, args, &ehdr32, &uphdr_vaddr32, 507 &voffset, exec_file, &interp, &env.ex_bssbase, 508 &env.ex_brkbase, &env.ex_brksize, NULL); 509 Ehdr32to64(&ehdr32, &ehdr); 510 if (uphdr_vaddr32 == (Elf32_Addr)-1) 511 uphdr_vaddr = (Addr)-1; 512 else 513 uphdr_vaddr = uphdr_vaddr32; 514 #endif /* _LP64 */ 515 } 516 if (err != 0) 517 return (err); 518 519 /* 520 * Save off the important properties of the executable. The brand 521 * library will ask us for this data later, when it is initializing 522 * and getting ready to transfer control to the brand application. 523 */ 524 if (uphdr_vaddr == (Addr)-1) 525 sedp->sed_phdr = voffset + ehdr.e_phoff; 526 else 527 sedp->sed_phdr = voffset + uphdr_vaddr; 528 sedp->sed_entry = voffset + ehdr.e_entry; 529 sedp->sed_phent = ehdr.e_phentsize; 530 sedp->sed_phnum = ehdr.e_phnum; 531 532 if (interp) { 533 if (ehdr.e_type == ET_DYN) { 534 /* 535 * This is a shared object executable, so we need to 536 * pick a reasonable place to put the heap. Just don't 537 * use the first page. 538 */ 539 env.ex_brkbase = (caddr_t)PAGESIZE; 540 env.ex_bssbase = (caddr_t)PAGESIZE; 541 } 542 543 /* 544 * If the program needs an interpreter (most do), map it in and 545 * store relevant information about it in the aux vector, where 546 * the brand library can find it. 547 */ 548 if ((err = lookupname(linker, UIO_SYSSPACE, 549 FOLLOW, NULLVPP, &nvp)) != 0) { 550 uprintf("%s: not found.", SN1_LINKER); 551 return (err); 552 } 553 if (args->to_model == DATAMODEL_NATIVE) { 554 err = mapexec_brand(nvp, args, &ehdr, 555 &uphdr_vaddr, &voffset, exec_file, &interp, 556 NULL, NULL, NULL, &lddata); 557 #if defined(_LP64) 558 } else { 559 Elf32_Ehdr ehdr32; 560 Elf32_Addr uphdr_vaddr32; 561 err = mapexec32_brand(nvp, args, &ehdr32, 562 &uphdr_vaddr32, &voffset, exec_file, &interp, 563 NULL, NULL, NULL, &lddata); 564 Ehdr32to64(&ehdr32, &ehdr); 565 if (uphdr_vaddr32 == (Elf32_Addr)-1) 566 uphdr_vaddr = (Addr)-1; 567 else 568 uphdr_vaddr = uphdr_vaddr32; 569 #endif /* _LP64 */ 570 } 571 VN_RELE(nvp); 572 if (err != 0) 573 return (err); 574 575 /* 576 * Now that we know the base address of the brand's linker, 577 * place it in the aux vector. 578 */ 579 sedp->sed_base = voffset; 580 sedp->sed_ldentry = voffset + ehdr.e_entry; 581 sedp->sed_lddata = voffset + lddata; 582 } else { 583 /* 584 * This program has no interpreter. The brand library will 585 * jump to the address in the AT_SUN_BRAND_LDENTRY aux vector, 586 * so in this case, put the entry point of the main executable 587 * there. 588 */ 589 if (ehdr.e_type == ET_EXEC) { 590 /* 591 * An executable with no interpreter, this must be a 592 * statically linked executable, which means we loaded 593 * it at the address specified in the elf header, in 594 * which case the e_entry field of the elf header is an 595 * absolute address. 596 */ 597 sedp->sed_ldentry = ehdr.e_entry; 598 sedp->sed_entry = ehdr.e_entry; 599 sedp->sed_lddata = NULL; 600 sedp->sed_base = NULL; 601 } else { 602 /* 603 * A shared object with no interpreter, we use the 604 * calculated address from above. 605 */ 606 sedp->sed_ldentry = sedp->sed_entry; 607 sedp->sed_lddata = NULL; 608 sedp->sed_base = NULL; 609 } 610 } 611 612 if (uphdr_vaddr != (Addr)-1) { 613 if (ehdr.e_type == ET_DYN) { 614 /* 615 * Delay setting the brkbase until the first call to 616 * brk(); see elfexec() for details. 617 */ 618 env.ex_bssbase = (caddr_t)0; 619 env.ex_brkbase = (caddr_t)0; 620 env.ex_brksize = 0; 621 } 622 } 623 624 env.ex_magic = elfmagic; 625 env.ex_vp = vp; 626 setexecenv(&env); 627 628 /* 629 * It's time to manipulate the process aux vectors. First 630 * we need to update the AT_SUN_AUXFLAGS aux vector to set 631 * the AF_SUN_NOPLM flag. 632 */ 633 if (args->to_model == DATAMODEL_NATIVE) { 634 auxv_t auxflags_auxv; 635 636 if (copyin(args->auxp_auxflags, &auxflags_auxv, 637 sizeof (auxflags_auxv)) != 0) 638 return (EFAULT); 639 640 ASSERT(auxflags_auxv.a_type == AT_SUN_AUXFLAGS); 641 auxflags_auxv.a_un.a_val |= AF_SUN_NOPLM; 642 if (copyout(&auxflags_auxv, args->auxp_auxflags, 643 sizeof (auxflags_auxv)) != 0) 644 return (EFAULT); 645 #if defined(_LP64) 646 } else { 647 auxv32_t auxflags_auxv32; 648 649 if (copyin(args->auxp_auxflags, &auxflags_auxv32, 650 sizeof (auxflags_auxv32)) != 0) 651 return (EFAULT); 652 653 ASSERT(auxflags_auxv32.a_type == AT_SUN_AUXFLAGS); 654 auxflags_auxv32.a_un.a_val |= AF_SUN_NOPLM; 655 if (copyout(&auxflags_auxv32, args->auxp_auxflags, 656 sizeof (auxflags_auxv32)) != 0) 657 return (EFAULT); 658 #endif /* _LP64 */ 659 } 660 661 /* Second, copy out the brand specific aux vectors. */ 662 if (args->to_model == DATAMODEL_NATIVE) { 663 auxv_t sn1_auxv[] = { 664 { AT_SUN_BRAND_AUX1, 0 }, 665 { AT_SUN_BRAND_AUX2, 0 }, 666 { AT_SUN_BRAND_AUX3, 0 } 667 }; 668 669 ASSERT(sn1_auxv[0].a_type == AT_SUN_BRAND_SN1_LDDATA); 670 sn1_auxv[0].a_un.a_val = sed.sed_lddata; 671 672 if (copyout(&sn1_auxv, args->auxp_brand, 673 sizeof (sn1_auxv)) != 0) 674 return (EFAULT); 675 #if defined(_LP64) 676 } else { 677 auxv32_t sn1_auxv32[] = { 678 { AT_SUN_BRAND_AUX1, 0 }, 679 { AT_SUN_BRAND_AUX2, 0 }, 680 { AT_SUN_BRAND_AUX3, 0 } 681 }; 682 683 ASSERT(sn1_auxv32[0].a_type == AT_SUN_BRAND_SN1_LDDATA); 684 sn1_auxv32[0].a_un.a_val = (uint32_t)sed.sed_lddata; 685 if (copyout(&sn1_auxv32, args->auxp_brand, 686 sizeof (sn1_auxv32)) != 0) 687 return (EFAULT); 688 #endif /* _LP64 */ 689 } 690 691 /* 692 * Third, the the /proc aux vectors set up by elfexec() point to brand 693 * emulation library and it's linker. Copy these to the /proc brand 694 * specific aux vector, and update the regular /proc aux vectors to 695 * point to the executable (and it's linker). This will enable 696 * debuggers to access the executable via the usual /proc or elf notes 697 * aux vectors. 698 * 699 * The brand emulation library's linker will get it's aux vectors off 700 * the stack, and then update the stack with the executable's aux 701 * vectors before jumping to the executable's linker. 702 * 703 * Debugging the brand emulation library must be done from 704 * the global zone, where the librtld_db module knows how to fetch the 705 * brand specific aux vectors to access the brand emulation libraries 706 * linker. 707 */ 708 for (i = 0; i < __KERN_NAUXV_IMPL; i++) { 709 switch (up->u_auxv[i].a_type) { 710 case AT_SUN_BRAND_SN1_LDDATA: 711 up->u_auxv[i].a_un.a_val = sed.sed_lddata; 712 break; 713 case AT_BASE: 714 if (sedp->sed_base == NULL) { 715 /* Hide base for static binaries */ 716 up->u_auxv[i].a_type = AT_IGNORE; 717 up->u_auxv[i].a_un.a_val = NULL; 718 } else { 719 up->u_auxv[i].a_un.a_val = sedp->sed_base; 720 } 721 break; 722 case AT_ENTRY: 723 up->u_auxv[i].a_un.a_val = sedp->sed_entry; 724 break; 725 case AT_PHDR: 726 up->u_auxv[i].a_un.a_val = sedp->sed_phdr; 727 break; 728 case AT_PHENT: 729 up->u_auxv[i].a_un.a_val = sedp->sed_phent; 730 break; 731 case AT_PHNUM: 732 up->u_auxv[i].a_un.a_val = sedp->sed_phnum; 733 break; 734 case AT_SUN_LDDATA: 735 if (sedp->sed_lddata == NULL) { 736 /* Hide lddata for static binaries */ 737 up->u_auxv[i].a_type = AT_IGNORE; 738 up->u_auxv[i].a_un.a_val = NULL; 739 } else { 740 up->u_auxv[i].a_un.a_val = sedp->sed_lddata; 741 } 742 break; 743 default: 744 break; 745 } 746 } 747 748 /* 749 * The last thing we do here is clear spd->spd_handler. This is 750 * important because if we're already a branded process and if this 751 * exec succeeds, there is a window between when the exec() first 752 * returns to the userland of the new process and when our brand 753 * library get's initialized, during which we don't want system 754 * calls to be re-directed to our brand library since it hasn't 755 * been initialized yet. 756 */ 757 spd->spd_handler = NULL; 758 759 return (0); 760 } 761 762 763 int 764 _init(void) 765 { 766 int err; 767 768 /* 769 * Set up the table indicating which system calls we want to 770 * interpose on. We should probably build this automatically from 771 * a list of system calls that is shared with the user-space 772 * library. 773 */ 774 sn1_emulation_table = kmem_zalloc(NSYSCALL, KM_SLEEP); 775 sn1_emulation_table[SYS_read] = 1; /* 3 */ 776 sn1_emulation_table[SYS_write] = 1; /* 4 */ 777 sn1_emulation_table[SYS_wait] = 1; /* 7 */ 778 sn1_emulation_table[SYS_time] = 1; /* 13 */ 779 sn1_emulation_table[SYS_getpid] = 1; /* 20 */ 780 sn1_emulation_table[SYS_mount] = 1; /* 21 */ 781 sn1_emulation_table[SYS_getuid] = 1; /* 24 */ 782 sn1_emulation_table[SYS_times] = 1; /* 43 */ 783 sn1_emulation_table[SYS_getgid] = 1; /* 47 */ 784 sn1_emulation_table[SYS_utssys] = 1; /* 57 */ 785 sn1_emulation_table[SYS_readlink] = 1; /* 90 */ 786 sn1_emulation_table[SYS_uname] = 1; /* 135 */ 787 788 err = mod_install(&modlinkage); 789 if (err) { 790 cmn_err(CE_WARN, "Couldn't install brand module"); 791 kmem_free(sn1_emulation_table, NSYSCALL); 792 } 793 794 return (err); 795 } 796 797 int 798 _info(struct modinfo *modinfop) 799 { 800 return (mod_info(&modlinkage, modinfop)); 801 } 802 803 int 804 _fini(void) 805 { 806 int err; 807 808 /* 809 * If there are any zones using this brand, we can't allow it to be 810 * unloaded. 811 */ 812 if (brand_zone_count(&sn1_brand)) 813 return (EBUSY); 814 815 kmem_free(sn1_emulation_table, NSYSCALL); 816 sn1_emulation_table = NULL; 817 818 err = mod_remove(&modlinkage); 819 if (err) 820 cmn_err(CE_WARN, "Couldn't unload sn1 brand module"); 821 822 return (err); 823 } 824