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 /* 23 * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. 24 * Copyright 2022 Garrett D'Amore <garrett@damore.org> 25 */ 26 27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 28 /* All Rights Reserved */ 29 30 /* 31 * Copyright 2019 Joyent, Inc. 32 * Copyright 2026 Oxide Computer Company 33 */ 34 35 #ifndef _SYS_EXEC_H 36 #define _SYS_EXEC_H 37 38 #include <sys/systm.h> 39 #include <vm/seg.h> 40 #include <vm/seg_vn.h> 41 #include <sys/model.h> 42 #include <sys/uio.h> 43 #include <sys/corectl.h> 44 #include <sys/machelf.h> 45 46 #ifdef __cplusplus 47 extern "C" { 48 #endif 49 50 /* 51 * Number of bytes to read for magic string 52 */ 53 #define MAGIC_BYTES 8 54 55 #define getexmag(x) (((x)[0] << 8) + (x)[1]) 56 57 typedef struct execa { 58 const char *fname; 59 const char **argp; 60 const char **envp; 61 } execa_t; 62 63 typedef struct execenv { 64 caddr_t ex_bssbase; 65 caddr_t ex_brkbase; 66 size_t ex_brksize; 67 vnode_t *ex_vp; 68 short ex_magic; 69 } execenv_t; 70 71 #ifdef _KERNEL 72 73 #define LOADABLE_EXEC(e) ((e)->exec_lock) 74 #define LOADED_EXEC(e) ((e)->exec_func) 75 76 77 /* 78 * User argument structure for passing exec information around between the 79 * common and machine-dependent portions of exec and the exec modules. 80 */ 81 typedef struct uarg { 82 ssize_t na; 83 ssize_t ne; 84 ssize_t nc; 85 ssize_t arglen; 86 char *fname; 87 char *pathname; 88 size_t auxsize; 89 caddr_t stackend; 90 size_t stk_align; 91 size_t stk_size; 92 char *stk_base; 93 char *stk_strp; 94 int *stk_offp; 95 size_t usrstack_size; 96 uint_t stk_prot; 97 uint_t dat_prot; 98 int traceinval; 99 int addr32; 100 model_t to_model; 101 model_t from_model; 102 size_t to_ptrsize; 103 size_t from_ptrsize; 104 uio_seg_t argseg; 105 size_t ncargs; 106 struct execsw *execswp; 107 uintptr_t entry; 108 uintptr_t thrptr; 109 vnode_t *ex_vp; 110 char *emulator; 111 char *brandname; 112 char *auxp_auxflags; /* addr of auxflags auxv on the user stack */ 113 char *auxp_brand; /* address of first brand auxv on user stack */ 114 cred_t *pfcred; 115 boolean_t scrubenv; 116 uintptr_t commpage; 117 } uarg_t; 118 119 /* 120 * Possible brand actions for exec. 121 */ 122 #define EBA_NONE 0 123 #define EBA_NATIVE 1 124 #define EBA_BRAND 2 125 126 /* 127 * The following macro is a machine dependent encapsulation of 128 * postfix processing to hide the stack direction from elf.c 129 * thereby making the elf.c code machine independent. 130 */ 131 #define execpoststack(ARGS, ARRAYADDR, BYTESIZE) \ 132 (copyout((caddr_t)(ARRAYADDR), (ARGS)->stackend, (BYTESIZE)) ? EFAULT \ 133 : (((ARGS)->stackend += (BYTESIZE)), 0)) 134 135 /* 136 * This provides the current user stack address for an object of size BYTESIZE. 137 * Used to determine the stack address just before applying execpoststack(). 138 */ 139 #define stackaddress(ARGS, BYTESIZE) ((ARGS)->stackend) 140 141 /* 142 * Macro to add attribute/values the aux vector under construction. 143 */ 144 /* BEGIN CSTYLED */ 145 #if ((_LONG_ALIGNMENT == (2 * _INT_ALIGNMENT)) || \ 146 (_POINTER_ALIGNMENT == (2 * _INT_ALIGNMENT))) 147 /* END CSTYLED */ 148 /* 149 * This convoluted stuff is necessitated by the fact that there is 150 * potential padding in the aux vector, but not necessarily and 151 * without clearing the padding there is a small, but potential 152 * security hole. 153 */ 154 #define ADDAUX(p, a, v) { \ 155 (&(p)->a_type)[1] = 0; \ 156 (p)->a_type = (a); \ 157 (p)->a_un.a_val = (v); \ 158 ++(p); \ 159 } 160 #else 161 #define ADDAUX(p, a, v) { \ 162 (p)->a_type = (a); \ 163 ((p)++)->a_un.a_val = (v); \ 164 } 165 #endif 166 167 #define INTPSZ MAXPATHLEN 168 #define INTP_MAXDEPTH 5 /* Nested interpreter depth matches Linux */ 169 typedef struct intpdata { 170 char *intp; 171 char *intp_name[INTP_MAXDEPTH]; 172 char *intp_arg[INTP_MAXDEPTH]; 173 } intpdata_t; 174 175 #define EXECSETID_SETID 0x1 /* setid exec */ 176 #define EXECSETID_UGIDS 0x2 /* [ug]ids mismatch */ 177 #define EXECSETID_PRIVS 0x4 /* more privs than before */ 178 179 struct execsw { 180 char *exec_magic; 181 int exec_magoff; 182 int exec_maglen; 183 int (*exec_func)(struct vnode *vp, struct execa *uap, 184 struct uarg *args, struct intpdata *idata, int level, 185 size_t *execsz, int setid, caddr_t exec_file, 186 struct cred *cred, int brand_action); 187 int (*exec_core)(struct vnode *vp, struct proc *p, 188 struct cred *cred, rlim64_t rlimit, int sig, 189 core_content_t content); 190 krwlock_t *exec_lock; 191 }; 192 193 extern int nexectype; /* number of elements in execsw */ 194 extern struct execsw execsw[]; 195 extern kmutex_t execsw_lock; 196 197 extern short elfmagic; 198 extern short intpmagic; 199 extern short javamagic; 200 extern short nomagic; 201 202 extern char elf32magicstr[]; 203 extern char elf64magicstr[]; 204 extern char intpmagicstr[]; 205 extern char javamagicstr[]; 206 extern char nomagicstr[]; 207 208 extern int exec_args(execa_t *, uarg_t *, intpdata_t *, void **); 209 extern int exece(uintptr_t, const char **, const char **, int); 210 extern int exec_common(const char *, const char **, const char **, vnode_t *, 211 int, uio_seg_t); 212 extern int gexec(vnode_t **vp, struct execa *uap, struct uarg *args, 213 struct intpdata *idata, int level, size_t *execsz, caddr_t exec_file, 214 struct cred *cred, int brand_action); 215 extern struct execsw *allocate_execsw(char *name, char *magic, 216 size_t magic_size); 217 extern struct execsw *findexecsw(char *magic); 218 extern struct execsw *findexec_by_hdr(char *header); 219 extern struct execsw *findexec_by_magic(char *magic); 220 extern int execpermissions(struct vnode *vp, struct vattr *vattrp, 221 struct uarg *args); 222 extern int execmap(vnode_t *vp, caddr_t addr, size_t len, size_t zfodlen, 223 off_t offset, int prot, int page, uint_t); 224 extern void setexecenv(struct execenv *ep); 225 extern int execopen(struct vnode **vpp, int *fdp); 226 extern int execclose(int fd); 227 extern void setregs(uarg_t *); 228 extern void exec_set_sp(size_t); 229 230 /* 231 * Utility functions for branded process executing 232 */ 233 #if !defined(_ELF32_COMPAT) 234 /* 235 * When compiling 64-bit kernels we don't want these definitions included 236 * when compiling the 32-bit compatability elf code in the elfexec module. 237 */ 238 extern int elfexec(vnode_t *, execa_t *, uarg_t *, intpdata_t *, int, 239 size_t *, int, caddr_t, cred_t *, int); 240 extern int mapexec_brand(vnode_t *, uarg_t *, Ehdr *, Addr *, 241 intptr_t *, caddr_t, int *, caddr_t *, caddr_t *, size_t *, uintptr_t *); 242 extern int elfreadhdr(vnode_t *, cred_t *, Ehdr *, uint_t *, caddr_t *, 243 size_t *); 244 #endif /* !_ELF32_COMPAT */ 245 246 #if defined(_LP64) 247 extern int elf32exec(vnode_t *, execa_t *, uarg_t *, intpdata_t *, int, 248 size_t *, int, caddr_t, cred_t *, int); 249 extern int mapexec32_brand(vnode_t *, uarg_t *, Elf32_Ehdr *, Elf32_Addr *, 250 intptr_t *, caddr_t, int *, caddr_t *, caddr_t *, size_t *, uintptr_t *); 251 extern int elf32readhdr(vnode_t *, cred_t *, Elf32_Ehdr *, uint_t *, caddr_t *, 252 size_t *); 253 #endif /* _LP64 */ 254 255 /* 256 * Utility functions for exec module core routines: 257 */ 258 extern int core_seg(proc_t *, vnode_t *, u_offset_t, caddr_t, size_t, 259 rlim64_t, cred_t *); 260 261 extern int core_write(vnode_t *, enum uio_seg, u_offset_t, const void *, 262 size_t, rlim64_t, cred_t *); 263 264 #endif /* _KERNEL */ 265 266 #ifdef __cplusplus 267 } 268 #endif 269 270 #endif /* _SYS_EXEC_H */ 271