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