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