1*9acbbeafSnn /* 2*9acbbeafSnn * CDDL HEADER START 3*9acbbeafSnn * 4*9acbbeafSnn * The contents of this file are subject to the terms of the 5*9acbbeafSnn * Common Development and Distribution License (the "License"). 6*9acbbeafSnn * You may not use this file except in compliance with the License. 7*9acbbeafSnn * 8*9acbbeafSnn * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*9acbbeafSnn * or http://www.opensolaris.org/os/licensing. 10*9acbbeafSnn * See the License for the specific language governing permissions 11*9acbbeafSnn * and limitations under the License. 12*9acbbeafSnn * 13*9acbbeafSnn * When distributing Covered Code, include this CDDL HEADER in each 14*9acbbeafSnn * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*9acbbeafSnn * If applicable, add the following below this CDDL HEADER, with the 16*9acbbeafSnn * fields enclosed by brackets "[]" replaced with your own identifying 17*9acbbeafSnn * information: Portions Copyright [yyyy] [name of copyright owner] 18*9acbbeafSnn * 19*9acbbeafSnn * CDDL HEADER END 20*9acbbeafSnn */ 21*9acbbeafSnn /* 22*9acbbeafSnn * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23*9acbbeafSnn * Use is subject to license terms. 24*9acbbeafSnn */ 25*9acbbeafSnn 26*9acbbeafSnn #pragma ident "%Z%%M% %I% %E% SMI" 27*9acbbeafSnn 28*9acbbeafSnn #include <sys/errno.h> 29*9acbbeafSnn #include <sys/exec.h> 30*9acbbeafSnn #include <sys/kmem.h> 31*9acbbeafSnn #include <sys/modctl.h> 32*9acbbeafSnn #include <sys/model.h> 33*9acbbeafSnn #include <sys/proc.h> 34*9acbbeafSnn #include <sys/syscall.h> 35*9acbbeafSnn #include <sys/systm.h> 36*9acbbeafSnn #include <sys/thread.h> 37*9acbbeafSnn #include <sys/cmn_err.h> 38*9acbbeafSnn #include <sys/archsystm.h> 39*9acbbeafSnn 40*9acbbeafSnn #include <sys/machbrand.h> 41*9acbbeafSnn #include <sys/brand.h> 42*9acbbeafSnn #include "sn1_brand.h" 43*9acbbeafSnn 44*9acbbeafSnn char *sn1_emulation_table = NULL; 45*9acbbeafSnn 46*9acbbeafSnn void sn1_setbrand(proc_t *); 47*9acbbeafSnn int sn1_getattr(zone_t *, int, void *, size_t *); 48*9acbbeafSnn int sn1_setattr(zone_t *, int, void *, size_t); 49*9acbbeafSnn int sn1_brandsys(int, int64_t *, uintptr_t, uintptr_t, uintptr_t, 50*9acbbeafSnn uintptr_t, uintptr_t, uintptr_t); 51*9acbbeafSnn void sn1_copy_procdata(proc_t *, proc_t *); 52*9acbbeafSnn void sn1_proc_exit(struct proc *, klwp_t *); 53*9acbbeafSnn void sn1_exec(); 54*9acbbeafSnn int sn1_initlwp(klwp_t *); 55*9acbbeafSnn void sn1_forklwp(klwp_t *, klwp_t *); 56*9acbbeafSnn void sn1_freelwp(klwp_t *); 57*9acbbeafSnn void sn1_lwpexit(klwp_t *); 58*9acbbeafSnn int sn1_elfexec(vnode_t *, execa_t *, uarg_t *, intpdata_t *, int, 59*9acbbeafSnn long *, int, caddr_t, cred_t *, int); 60*9acbbeafSnn 61*9acbbeafSnn /* sn1 brand */ 62*9acbbeafSnn struct brand_ops sn1_brops = { 63*9acbbeafSnn sn1_brandsys, 64*9acbbeafSnn sn1_setbrand, 65*9acbbeafSnn sn1_getattr, 66*9acbbeafSnn sn1_setattr, 67*9acbbeafSnn sn1_copy_procdata, 68*9acbbeafSnn sn1_proc_exit, 69*9acbbeafSnn sn1_exec, 70*9acbbeafSnn lwp_setrval, 71*9acbbeafSnn sn1_initlwp, 72*9acbbeafSnn sn1_forklwp, 73*9acbbeafSnn sn1_freelwp, 74*9acbbeafSnn sn1_lwpexit, 75*9acbbeafSnn sn1_elfexec 76*9acbbeafSnn }; 77*9acbbeafSnn 78*9acbbeafSnn #ifdef sparc 79*9acbbeafSnn 80*9acbbeafSnn struct brand_mach_ops sn1_mops = { 81*9acbbeafSnn sn1_brand_syscall_callback, 82*9acbbeafSnn sn1_brand_syscall_callback 83*9acbbeafSnn }; 84*9acbbeafSnn 85*9acbbeafSnn #else /* sparc */ 86*9acbbeafSnn 87*9acbbeafSnn #ifdef __amd64 88*9acbbeafSnn 89*9acbbeafSnn struct brand_mach_ops sn1_mops = { 90*9acbbeafSnn sn1_brand_sysenter_callback, 91*9acbbeafSnn NULL, 92*9acbbeafSnn sn1_brand_int91_callback, 93*9acbbeafSnn sn1_brand_syscall_callback, 94*9acbbeafSnn sn1_brand_syscall32_callback, 95*9acbbeafSnn NULL 96*9acbbeafSnn }; 97*9acbbeafSnn 98*9acbbeafSnn #else /* ! __amd64 */ 99*9acbbeafSnn 100*9acbbeafSnn struct brand_mach_ops sn1_mops = { 101*9acbbeafSnn sn1_brand_sysenter_callback, 102*9acbbeafSnn NULL, 103*9acbbeafSnn NULL, 104*9acbbeafSnn sn1_brand_syscall_callback, 105*9acbbeafSnn NULL, 106*9acbbeafSnn NULL 107*9acbbeafSnn }; 108*9acbbeafSnn #endif /* __amd64 */ 109*9acbbeafSnn 110*9acbbeafSnn #endif /* _sparc */ 111*9acbbeafSnn 112*9acbbeafSnn struct brand sn1_brand = { 113*9acbbeafSnn BRAND_VER_1, 114*9acbbeafSnn "sn1", 115*9acbbeafSnn &sn1_brops, 116*9acbbeafSnn &sn1_mops 117*9acbbeafSnn }; 118*9acbbeafSnn 119*9acbbeafSnn static struct modlbrand modlbrand = { 120*9acbbeafSnn &mod_brandops, "Solaris N-1 Brand %I%", &sn1_brand 121*9acbbeafSnn }; 122*9acbbeafSnn 123*9acbbeafSnn static struct modlinkage modlinkage = { 124*9acbbeafSnn MODREV_1, (void *)&modlbrand, NULL 125*9acbbeafSnn }; 126*9acbbeafSnn 127*9acbbeafSnn void 128*9acbbeafSnn sn1_setbrand(proc_t *p) 129*9acbbeafSnn { 130*9acbbeafSnn p->p_brand_data = NULL; 131*9acbbeafSnn p->p_brand = &sn1_brand; 132*9acbbeafSnn } 133*9acbbeafSnn 134*9acbbeafSnn /* ARGSUSED */ 135*9acbbeafSnn int 136*9acbbeafSnn sn1_getattr(zone_t *zone, int attr, void *buf, size_t *bufsize) 137*9acbbeafSnn { 138*9acbbeafSnn return (EINVAL); 139*9acbbeafSnn } 140*9acbbeafSnn 141*9acbbeafSnn /* ARGSUSED */ 142*9acbbeafSnn int 143*9acbbeafSnn sn1_setattr(zone_t *zone, int attr, void *buf, size_t bufsize) 144*9acbbeafSnn { 145*9acbbeafSnn return (EINVAL); 146*9acbbeafSnn } 147*9acbbeafSnn 148*9acbbeafSnn /* 149*9acbbeafSnn * Get the address of the user-space system call handler from the user 150*9acbbeafSnn * process and attach it to the proc structure. 151*9acbbeafSnn */ 152*9acbbeafSnn /*ARGSUSED*/ 153*9acbbeafSnn int 154*9acbbeafSnn sn1_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2, 155*9acbbeafSnn uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, uintptr_t arg6) 156*9acbbeafSnn { 157*9acbbeafSnn proc_t *p = curproc; 158*9acbbeafSnn *rval = 0; 159*9acbbeafSnn 160*9acbbeafSnn if (cmd == B_REGISTER) { 161*9acbbeafSnn p->p_brand = &sn1_brand; 162*9acbbeafSnn p->p_brand_data = (void *) arg1; 163*9acbbeafSnn return (0); 164*9acbbeafSnn } 165*9acbbeafSnn 166*9acbbeafSnn ASSERT(p->p_brand == &sn1_brand); 167*9acbbeafSnn 168*9acbbeafSnn return (EINVAL); 169*9acbbeafSnn } 170*9acbbeafSnn 171*9acbbeafSnn /* 172*9acbbeafSnn * Copy the per-process brand data from a parent proc to a child. In the 173*9acbbeafSnn * sn1 brand, the only per-process state is the address of the user-space 174*9acbbeafSnn * handler. 175*9acbbeafSnn */ 176*9acbbeafSnn void 177*9acbbeafSnn sn1_copy_procdata(proc_t *child, proc_t *parent) 178*9acbbeafSnn { 179*9acbbeafSnn child->p_brand_data = parent->p_brand_data; 180*9acbbeafSnn } 181*9acbbeafSnn 182*9acbbeafSnn /*ARGSUSED*/ 183*9acbbeafSnn void 184*9acbbeafSnn sn1_proc_exit(struct proc *p, klwp_t *l) 185*9acbbeafSnn { 186*9acbbeafSnn p->p_brand_data = NULL; 187*9acbbeafSnn p->p_brand = &native_brand; 188*9acbbeafSnn } 189*9acbbeafSnn 190*9acbbeafSnn void 191*9acbbeafSnn sn1_exec() 192*9acbbeafSnn { 193*9acbbeafSnn curproc->p_brand_data = NULL; 194*9acbbeafSnn } 195*9acbbeafSnn 196*9acbbeafSnn /*ARGSUSED*/ 197*9acbbeafSnn int 198*9acbbeafSnn sn1_initlwp(klwp_t *l) 199*9acbbeafSnn { 200*9acbbeafSnn return (0); 201*9acbbeafSnn } 202*9acbbeafSnn 203*9acbbeafSnn /*ARGSUSED*/ 204*9acbbeafSnn void 205*9acbbeafSnn sn1_forklwp(klwp_t *p, klwp_t *c) 206*9acbbeafSnn { 207*9acbbeafSnn } 208*9acbbeafSnn 209*9acbbeafSnn /*ARGSUSED*/ 210*9acbbeafSnn void 211*9acbbeafSnn sn1_freelwp(klwp_t *l) 212*9acbbeafSnn { 213*9acbbeafSnn } 214*9acbbeafSnn 215*9acbbeafSnn /*ARGSUSED*/ 216*9acbbeafSnn void 217*9acbbeafSnn sn1_lwpexit(klwp_t *l) 218*9acbbeafSnn { 219*9acbbeafSnn } 220*9acbbeafSnn 221*9acbbeafSnn int 222*9acbbeafSnn sn1_elfexec(vnode_t *vp, execa_t *uap, uarg_t *args, intpdata_t *idatap, 223*9acbbeafSnn int level, long *execsz, int setid, caddr_t exec_file, cred_t *cred, 224*9acbbeafSnn int brand_action) 225*9acbbeafSnn { 226*9acbbeafSnn args->brandname = "sn1"; 227*9acbbeafSnn return ((args->execswp->exec_func)(vp, uap, args, idatap, level + 1, 228*9acbbeafSnn execsz, setid, exec_file, cred, brand_action)); 229*9acbbeafSnn } 230*9acbbeafSnn 231*9acbbeafSnn 232*9acbbeafSnn int 233*9acbbeafSnn _init(void) 234*9acbbeafSnn { 235*9acbbeafSnn int err; 236*9acbbeafSnn 237*9acbbeafSnn #if defined(sparc) && !defined(DEBUG) 238*9acbbeafSnn cmn_err(CE_WARN, "The sn1 brand is only supported on DEBUG kernels."); 239*9acbbeafSnn return (ENOTSUP); 240*9acbbeafSnn #else 241*9acbbeafSnn 242*9acbbeafSnn /* 243*9acbbeafSnn * Set up the table indicating which system calls we want to 244*9acbbeafSnn * interpose on. We should probably build this automatically from 245*9acbbeafSnn * a list of system calls that is shared with the user-space 246*9acbbeafSnn * library. 247*9acbbeafSnn */ 248*9acbbeafSnn sn1_emulation_table = kmem_zalloc(NSYSCALL, KM_SLEEP); 249*9acbbeafSnn sn1_emulation_table[SYS_uname] = 1; 250*9acbbeafSnn sn1_emulation_table[SYS_fork1] = 1; 251*9acbbeafSnn 252*9acbbeafSnn err = mod_install(&modlinkage); 253*9acbbeafSnn if (err) { 254*9acbbeafSnn cmn_err(CE_WARN, "Couldn't install brand module"); 255*9acbbeafSnn kmem_free(sn1_emulation_table, NSYSCALL); 256*9acbbeafSnn } 257*9acbbeafSnn 258*9acbbeafSnn return (err); 259*9acbbeafSnn #endif 260*9acbbeafSnn } 261*9acbbeafSnn 262*9acbbeafSnn int 263*9acbbeafSnn _info(struct modinfo *modinfop) 264*9acbbeafSnn { 265*9acbbeafSnn return (mod_info(&modlinkage, modinfop)); 266*9acbbeafSnn } 267*9acbbeafSnn 268*9acbbeafSnn int 269*9acbbeafSnn _fini(void) 270*9acbbeafSnn { 271*9acbbeafSnn int err; 272*9acbbeafSnn 273*9acbbeafSnn /* 274*9acbbeafSnn * If there are any zones using this brand, we can't allow it to be 275*9acbbeafSnn * unloaded. 276*9acbbeafSnn */ 277*9acbbeafSnn if (brand_zone_count(&sn1_brand)) 278*9acbbeafSnn return (EBUSY); 279*9acbbeafSnn 280*9acbbeafSnn kmem_free(sn1_emulation_table, NSYSCALL); 281*9acbbeafSnn sn1_emulation_table = NULL; 282*9acbbeafSnn 283*9acbbeafSnn err = mod_remove(&modlinkage); 284*9acbbeafSnn if (err) 285*9acbbeafSnn cmn_err(CE_WARN, "Couldn't unload sn1 brand module"); 286*9acbbeafSnn 287*9acbbeafSnn return (err); 288*9acbbeafSnn } 289