19acbbeafSnn /*
29acbbeafSnn  * CDDL HEADER START
39acbbeafSnn  *
49acbbeafSnn  * The contents of this file are subject to the terms of the
59acbbeafSnn  * Common Development and Distribution License (the "License").
69acbbeafSnn  * You may not use this file except in compliance with the License.
79acbbeafSnn  *
89acbbeafSnn  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99acbbeafSnn  * or http://www.opensolaris.org/os/licensing.
109acbbeafSnn  * See the License for the specific language governing permissions
119acbbeafSnn  * and limitations under the License.
129acbbeafSnn  *
139acbbeafSnn  * When distributing Covered Code, include this CDDL HEADER in each
149acbbeafSnn  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159acbbeafSnn  * If applicable, add the following below this CDDL HEADER, with the
169acbbeafSnn  * fields enclosed by brackets "[]" replaced with your own identifying
179acbbeafSnn  * information: Portions Copyright [yyyy] [name of copyright owner]
189acbbeafSnn  *
199acbbeafSnn  * CDDL HEADER END
209acbbeafSnn  */
21794f0adbSRoger A. Faulkner 
229acbbeafSnn /*
2380e2ca85S  * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
24*4e18e297SPatrick Mooney  * Copyright 2019 Joyent, Inc.
259acbbeafSnn  */
269acbbeafSnn 
279acbbeafSnn #include <sys/errno.h>
289acbbeafSnn #include <sys/exec.h>
299acbbeafSnn #include <sys/kmem.h>
309acbbeafSnn #include <sys/modctl.h>
319acbbeafSnn #include <sys/model.h>
329acbbeafSnn #include <sys/proc.h>
339acbbeafSnn #include <sys/syscall.h>
349acbbeafSnn #include <sys/systm.h>
359acbbeafSnn #include <sys/thread.h>
369acbbeafSnn #include <sys/cmn_err.h>
379acbbeafSnn #include <sys/archsystm.h>
38628e3cbeSEdward Pilatowicz #include <sys/pathname.h>
399acbbeafSnn 
409acbbeafSnn #include <sys/machbrand.h>
419acbbeafSnn #include <sys/brand.h>
429acbbeafSnn #include "sn1_brand.h"
439acbbeafSnn 
449acbbeafSnn char *sn1_emulation_table = NULL;
459acbbeafSnn 
46319378d9Seh void	sn1_init_brand_data(zone_t *);
47319378d9Seh void	sn1_free_brand_data(zone_t *);
489acbbeafSnn void	sn1_setbrand(proc_t *);
499acbbeafSnn int	sn1_getattr(zone_t *, int, void *, size_t *);
509acbbeafSnn int	sn1_setattr(zone_t *, int, void *, size_t);
519acbbeafSnn int	sn1_brandsys(int, int64_t *, uintptr_t, uintptr_t, uintptr_t,
529acbbeafSnn 		uintptr_t, uintptr_t, uintptr_t);
539acbbeafSnn void	sn1_copy_procdata(proc_t *, proc_t *);
549acbbeafSnn void	sn1_proc_exit(struct proc *, klwp_t *);
559acbbeafSnn void	sn1_exec();
569acbbeafSnn int	sn1_initlwp(klwp_t *);
579acbbeafSnn void	sn1_forklwp(klwp_t *, klwp_t *);
589acbbeafSnn void	sn1_freelwp(klwp_t *);
599acbbeafSnn void	sn1_lwpexit(klwp_t *);
609acbbeafSnn int	sn1_elfexec(vnode_t *, execa_t *, uarg_t *, intpdata_t *, int,
61*4e18e297SPatrick Mooney 	size_t *, int, caddr_t, cred_t *, int);
629acbbeafSnn 
639acbbeafSnn /* sn1 brand */
649acbbeafSnn struct brand_ops sn1_brops = {
65319378d9Seh 	sn1_init_brand_data,
66319378d9Seh 	sn1_free_brand_data,
679acbbeafSnn 	sn1_brandsys,
689acbbeafSnn 	sn1_setbrand,
699acbbeafSnn 	sn1_getattr,
709acbbeafSnn 	sn1_setattr,
719acbbeafSnn 	sn1_copy_procdata,
729acbbeafSnn 	sn1_proc_exit,
739acbbeafSnn 	sn1_exec,
749acbbeafSnn 	lwp_setrval,
759acbbeafSnn 	sn1_initlwp,
769acbbeafSnn 	sn1_forklwp,
779acbbeafSnn 	sn1_freelwp,
789acbbeafSnn 	sn1_lwpexit,
79eb9dbf0cSRoger A. Faulkner 	sn1_elfexec,
808f798d3aSRoger A. Faulkner 	NULL,
818f798d3aSRoger A. Faulkner 	NULL,
828f798d3aSRoger A. Faulkner 	NSIG,
839acbbeafSnn };
849acbbeafSnn 
859acbbeafSnn #ifdef	sparc
869acbbeafSnn 
879acbbeafSnn struct brand_mach_ops sn1_mops = {
889acbbeafSnn 	sn1_brand_syscall_callback,
89628e3cbeSEdward Pilatowicz 	sn1_brand_syscall32_callback
909acbbeafSnn };
919acbbeafSnn 
929acbbeafSnn #else	/* sparc */
939acbbeafSnn 
949acbbeafSnn #ifdef	__amd64
959acbbeafSnn 
969acbbeafSnn struct brand_mach_ops sn1_mops = {
979acbbeafSnn 	sn1_brand_sysenter_callback,
989acbbeafSnn 	sn1_brand_int91_callback,
999acbbeafSnn 	sn1_brand_syscall_callback,
100eb5a5c78SSurya Prakki 	sn1_brand_syscall32_callback
1019acbbeafSnn };
1029acbbeafSnn 
1039acbbeafSnn #else	/* ! __amd64 */
1049acbbeafSnn 
1059acbbeafSnn struct brand_mach_ops sn1_mops = {
1069acbbeafSnn 	sn1_brand_sysenter_callback,
1079acbbeafSnn 	NULL,
1089acbbeafSnn 	sn1_brand_syscall_callback,
1099acbbeafSnn 	NULL
1109acbbeafSnn };
1119acbbeafSnn #endif	/* __amd64 */
1129acbbeafSnn 
1139acbbeafSnn #endif	/* _sparc */
1149acbbeafSnn 
1159acbbeafSnn struct brand	sn1_brand = {
1169acbbeafSnn 	BRAND_VER_1,
1179acbbeafSnn 	"sn1",
1189acbbeafSnn 	&sn1_brops,
1199acbbeafSnn 	&sn1_mops
1209acbbeafSnn };
1219acbbeafSnn 
1229acbbeafSnn static struct modlbrand modlbrand = {
123c6f42f0eSedp 	&mod_brandops,		/* type of module */
124c6f42f0eSedp 	"Solaris N-1 Brand",	/* description of module */
125c6f42f0eSedp 	&sn1_brand		/* driver ops */
1269acbbeafSnn };
1279acbbeafSnn 
1289acbbeafSnn static struct modlinkage modlinkage = {
1299acbbeafSnn 	MODREV_1, (void *)&modlbrand, NULL
1309acbbeafSnn };
1319acbbeafSnn 
1329acbbeafSnn void
sn1_setbrand(proc_t * p)1339acbbeafSnn sn1_setbrand(proc_t *p)
1349acbbeafSnn {
13580e2ca85S 	brand_solaris_setbrand(p, &sn1_brand);
1369acbbeafSnn }
1379acbbeafSnn 
1389acbbeafSnn /* ARGSUSED */
1399acbbeafSnn int
sn1_getattr(zone_t * zone,int attr,void * buf,size_t * bufsize)1409acbbeafSnn sn1_getattr(zone_t *zone, int attr, void *buf, size_t *bufsize)
1419acbbeafSnn {
1429acbbeafSnn 	return (EINVAL);
1439acbbeafSnn }
1449acbbeafSnn 
1459acbbeafSnn /* ARGSUSED */
1469acbbeafSnn int
sn1_setattr(zone_t * zone,int attr,void * buf,size_t bufsize)1479acbbeafSnn sn1_setattr(zone_t *zone, int attr, void *buf, size_t bufsize)
1489acbbeafSnn {
1499acbbeafSnn 	return (EINVAL);
1509acbbeafSnn }
1519acbbeafSnn 
1529acbbeafSnn /*ARGSUSED*/
1539acbbeafSnn int
sn1_brandsys(int cmd,int64_t * rval,uintptr_t arg1,uintptr_t arg2,uintptr_t arg3,uintptr_t arg4,uintptr_t arg5,uintptr_t arg6)1549acbbeafSnn sn1_brandsys(int cmd, int64_t *rval, uintptr_t arg1, uintptr_t arg2,
1559acbbeafSnn     uintptr_t arg3, uintptr_t arg4, uintptr_t arg5, uintptr_t arg6)
1569acbbeafSnn {
15780e2ca85S 	int	res;
158628e3cbeSEdward Pilatowicz 
1599acbbeafSnn 	*rval = 0;
1609acbbeafSnn 
16180e2ca85S 	res = brand_solaris_cmd(cmd, arg1, arg2, arg3, &sn1_brand, SN1_VERSION);
16280e2ca85S 	if (res >= 0)
16380e2ca85S 		return (res);
1649acbbeafSnn 
1659acbbeafSnn 	return (EINVAL);
1669acbbeafSnn }
1679acbbeafSnn 
1689acbbeafSnn void
sn1_copy_procdata(proc_t * child,proc_t * parent)1699acbbeafSnn sn1_copy_procdata(proc_t *child, proc_t *parent)
1709acbbeafSnn {
17180e2ca85S 	brand_solaris_copy_procdata(child, parent, &sn1_brand);
1729acbbeafSnn }
1739acbbeafSnn 
1749acbbeafSnn void
sn1_proc_exit(struct proc * p,klwp_t * l)1759acbbeafSnn sn1_proc_exit(struct proc *p, klwp_t *l)
1769acbbeafSnn {
17780e2ca85S 	brand_solaris_proc_exit(p, l, &sn1_brand);
1789acbbeafSnn }
1799acbbeafSnn 
1809acbbeafSnn void
sn1_exec()1819acbbeafSnn sn1_exec()
1829acbbeafSnn {
18380e2ca85S 	brand_solaris_exec(&sn1_brand);
1849acbbeafSnn }
1859acbbeafSnn 
1869acbbeafSnn int
sn1_initlwp(klwp_t * l)1879acbbeafSnn sn1_initlwp(klwp_t *l)
1889acbbeafSnn {
18980e2ca85S 	return (brand_solaris_initlwp(l, &sn1_brand));
1909acbbeafSnn }
1919acbbeafSnn 
192319378d9Seh void
sn1_forklwp(klwp_t * p,klwp_t * c)193fd9e7635Sedp sn1_forklwp(klwp_t *p, klwp_t *c)
194319378d9Seh {
19580e2ca85S 	brand_solaris_forklwp(p, c, &sn1_brand);
196319378d9Seh }
197319378d9Seh 
198319378d9Seh void
sn1_freelwp(klwp_t * l)199fd9e7635Sedp sn1_freelwp(klwp_t *l)
200319378d9Seh {
20180e2ca85S 	brand_solaris_freelwp(l, &sn1_brand);
202319378d9Seh }
203319378d9Seh 
2049acbbeafSnn void
sn1_lwpexit(klwp_t * l)205fd9e7635Sedp sn1_lwpexit(klwp_t *l)
2069acbbeafSnn {
20780e2ca85S 	brand_solaris_lwpexit(l, &sn1_brand);
2089acbbeafSnn }
2099acbbeafSnn 
2109acbbeafSnn /*ARGSUSED*/
2119acbbeafSnn void
sn1_free_brand_data(zone_t * zone)212628e3cbeSEdward Pilatowicz sn1_free_brand_data(zone_t *zone)
2139acbbeafSnn {
2149acbbeafSnn }
2159acbbeafSnn 
2169acbbeafSnn /*ARGSUSED*/
2179acbbeafSnn void
sn1_init_brand_data(zone_t * zone)218628e3cbeSEdward Pilatowicz sn1_init_brand_data(zone_t *zone)
219628e3cbeSEdward Pilatowicz {
220628e3cbeSEdward Pilatowicz }
221628e3cbeSEdward Pilatowicz 
2229acbbeafSnn int
sn1_elfexec(vnode_t * vp,execa_t * uap,uarg_t * args,intpdata_t * idatap,int level,size_t * execsz,int setid,caddr_t exec_file,cred_t * cred,int brand_action)2239acbbeafSnn sn1_elfexec(vnode_t *vp, execa_t *uap, uarg_t *args, intpdata_t *idatap,
224*4e18e297SPatrick Mooney     int level, size_t *execsz, int setid, caddr_t exec_file, cred_t *cred,
225*4e18e297SPatrick Mooney     int brand_action)
2269acbbeafSnn {
22780e2ca85S 	return (brand_solaris_elfexec(vp, uap, args, idatap, level, execsz,
22880e2ca85S 	    setid, exec_file, cred, brand_action, &sn1_brand, SN1_BRANDNAME,
22980e2ca85S 	    SN1_LIB, SN1_LIB32, SN1_LINKER, SN1_LINKER32));
2309acbbeafSnn }
2319acbbeafSnn 
2329acbbeafSnn int
_init(void)2339acbbeafSnn _init(void)
2349acbbeafSnn {
2359acbbeafSnn 	int err;
2369acbbeafSnn 
2379acbbeafSnn 	/*
2389acbbeafSnn 	 * Set up the table indicating which system calls we want to
2399acbbeafSnn 	 * interpose on.  We should probably build this automatically from
2409acbbeafSnn 	 * a list of system calls that is shared with the user-space
2419acbbeafSnn 	 * library.
2429acbbeafSnn 	 */
2439acbbeafSnn 	sn1_emulation_table = kmem_zalloc(NSYSCALL, KM_SLEEP);
244628e3cbeSEdward Pilatowicz 	sn1_emulation_table[SYS_read] = 1;			/*   3 */
245628e3cbeSEdward Pilatowicz 	sn1_emulation_table[SYS_write] = 1;			/*   4 */
246628e3cbeSEdward Pilatowicz 	sn1_emulation_table[SYS_time] = 1;			/*  13 */
247628e3cbeSEdward Pilatowicz 	sn1_emulation_table[SYS_getpid] = 1;			/*  20 */
248628e3cbeSEdward Pilatowicz 	sn1_emulation_table[SYS_mount] = 1;			/*  21 */
249628e3cbeSEdward Pilatowicz 	sn1_emulation_table[SYS_getuid] = 1;			/*  24 */
250628e3cbeSEdward Pilatowicz 	sn1_emulation_table[SYS_times] = 1;			/*  43 */
251628e3cbeSEdward Pilatowicz 	sn1_emulation_table[SYS_getgid] = 1;			/*  47 */
252628e3cbeSEdward Pilatowicz 	sn1_emulation_table[SYS_utssys] = 1;			/*  57 */
2538fd04b83SRoger A. Faulkner 	sn1_emulation_table[SYS_waitid] = 1;			/* 107 */
254628e3cbeSEdward Pilatowicz 	sn1_emulation_table[SYS_uname] = 1;			/* 135 */
2559acbbeafSnn 
2569acbbeafSnn 	err = mod_install(&modlinkage);
2579acbbeafSnn 	if (err) {
2589acbbeafSnn 		cmn_err(CE_WARN, "Couldn't install brand module");
2599acbbeafSnn 		kmem_free(sn1_emulation_table, NSYSCALL);
2609acbbeafSnn 	}
2619acbbeafSnn 
2629acbbeafSnn 	return (err);
2639acbbeafSnn }
2649acbbeafSnn 
2659acbbeafSnn int
_info(struct modinfo * modinfop)2669acbbeafSnn _info(struct modinfo *modinfop)
2679acbbeafSnn {
2689acbbeafSnn 	return (mod_info(&modlinkage, modinfop));
2699acbbeafSnn }
2709acbbeafSnn 
2719acbbeafSnn int
_fini(void)2729acbbeafSnn _fini(void)
2739acbbeafSnn {
27480e2ca85S 	return (brand_solaris_fini(&sn1_emulation_table, &modlinkage,
27580e2ca85S 	    &sn1_brand));
2769acbbeafSnn }
277