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