This source file includes following definitions.
- osf1_exec_ecoff_hook
- osf1_copyargs
- osf1_exec_ecoff_dynamic
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 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
37 #include <sys/proc.h>
38 #include <sys/malloc.h>
39 #include <sys/namei.h>
40 #include <sys/vnode.h>
41 #include <sys/mount.h>
42 #include <sys/exec.h>
43 #include <sys/exec_ecoff.h>
44 #include <sys/signalvar.h>
45 #include <sys/fcntl.h>
46 #include <sys/stat.h>
47
48 #include <compat/osf1/osf1.h>
49 #include <compat/osf1/osf1_syscall.h>
50 #include <compat/osf1/osf1_util.h>
51 #include <compat/osf1/osf1_cvt.h>
52
53 extern int scdebug;
54 extern char *osf1_syscallnames[];
55
56
57 struct osf1_exec_emul_arg {
58 int flags;
59 #define OSF1_EXEC_EMUL_FLAGS_HAVE_LOADER 0x01
60
61 char exec_name[MAXPATHLEN+1];
62 char loader_name[MAXPATHLEN+1];
63 };
64
65 static void *osf1_copyargs(struct exec_package *pack,
66 struct ps_strings *arginfo, void *stack, void *argp);
67 int osf1_exec_ecoff_hook(struct proc *, struct exec_package *);
68 static int osf1_exec_ecoff_dynamic(struct proc *, struct exec_package *);
69
70 #define MAX_AUX_ENTRIES 4
71
72 extern struct sysent osf1_sysent[];
73 extern void cpu_exec_ecoff_setregs(struct proc *, struct exec_package *,
74 u_long, register_t *);
75 extern char osf1_sigcode[], osf1_esigcode[];
76
77 struct emul emul_osf1 = {
78 "osf1",
79 NULL,
80 sendsig,
81 OSF1_SYS_syscall,
82 OSF1_SYS_MAXSYSCALL,
83 osf1_sysent,
84 #ifdef SYSCALL_DEBUG
85 osf1_syscallnames,
86 #else
87 NULL,
88 #endif
89 0,
90 osf1_copyargs,
91 cpu_exec_ecoff_setregs,
92 NULL,
93 osf1_sigcode,
94 osf1_esigcode,
95 };
96
97 int
98 osf1_exec_ecoff_hook(struct proc *p, struct exec_package *epp)
99 {
100 struct ecoff_exechdr *execp = (struct ecoff_exechdr *)epp->ep_hdr;
101 struct osf1_exec_emul_arg *emul_arg;
102 int error;
103
104
105 epp->ep_emul = &emul_osf1;
106
107
108 emul_arg = malloc(sizeof *emul_arg, M_TEMP, M_WAITOK);
109 epp->ep_emul_arg = emul_arg;
110
111 emul_arg->flags = 0;
112 if (epp->ep_ndp->ni_segflg == UIO_SYSSPACE)
113 error = copystr(epp->ep_ndp->ni_dirp, emul_arg->exec_name,
114 MAXPATHLEN + 1, NULL);
115 else
116 error = copyinstr(epp->ep_ndp->ni_dirp, emul_arg->exec_name,
117 MAXPATHLEN + 1, NULL);
118 #ifdef DIAGNOSTIC
119 if (error != 0)
120 panic("osf1_exec_ecoff_hook: copyinstr failed");
121 #endif
122
123
124 switch (execp->f.f_flags & ECOFF_FLAG_OBJECT_TYPE_MASK) {
125 case ECOFF_OBJECT_TYPE_SHARABLE:
126
127 uprintf("can't execute OSF/1 shared libraries\n");
128 error = ENOEXEC;
129 break;
130
131 case ECOFF_OBJECT_TYPE_CALL_SHARED:
132 error = osf1_exec_ecoff_dynamic(p, epp);
133 break;
134
135 default:
136
137 error = 0;
138 break;
139 }
140
141 if (error) {
142 free(epp->ep_emul_arg, M_TEMP);
143 epp->ep_emul_arg = NULL;
144 kill_vmcmds(&epp->ep_vmcmds);
145 }
146
147 return (error);
148 }
149
150
151
152
153
154 static void *
155 osf1_copyargs(pack, arginfo, stack, argp)
156 struct exec_package *pack;
157 struct ps_strings *arginfo;
158 void *stack;
159 void *argp;
160 {
161 struct proc *p = curproc;
162 struct osf1_exec_emul_arg *emul_arg = pack->ep_emul_arg;
163 struct osf1_auxv ai[MAX_AUX_ENTRIES], *a;
164 char *prognameloc, *loadernameloc;
165 size_t len;
166
167 stack = copyargs(pack, arginfo, stack, argp);
168 if (!stack)
169 goto bad;
170
171 a = ai;
172 memset(ai, 0, sizeof ai);
173
174 prognameloc = (char *)stack + sizeof ai;
175 if (copyoutstr(emul_arg->exec_name, prognameloc, MAXPATHLEN + 1, NULL))
176 goto bad;
177 a->a_type = OSF1_AT_EXEC_FILENAME;
178 a->a_un.a_ptr = prognameloc;
179 a++;
180
181
182
183
184 if (emul_arg->flags & OSF1_EXEC_EMUL_FLAGS_HAVE_LOADER) {
185
186 loadernameloc = prognameloc + MAXPATHLEN + 1;
187 if (copyoutstr(emul_arg->loader_name, loadernameloc,
188 MAXPATHLEN + 1, NULL))
189 goto bad;
190 a->a_type = OSF1_AT_EXEC_LOADER_FILENAME;
191 a->a_un.a_ptr = loadernameloc;
192 a++;
193
194 a->a_type = OSF1_AT_EXEC_LOADER_FLAGS;
195 a->a_un.a_val = 0;
196 if (pack->ep_vap->va_mode & S_ISUID)
197 a->a_un.a_val |= OSF1_LDR_EXEC_SETUID_F;
198 if (pack->ep_vap->va_mode & S_ISGID)
199 a->a_un.a_val |= OSF1_LDR_EXEC_SETGID_F;
200 if (p->p_flag & P_TRACED)
201 a->a_un.a_val |= OSF1_LDR_EXEC_PTRACE_F;
202 a++;
203 }
204
205 a->a_type = OSF1_AT_NULL;
206 a->a_un.a_val = 0;
207 a++;
208
209 len = (a - ai) * sizeof(struct osf1_auxv);
210 if (copyout(ai, stack, len))
211 goto bad;
212 stack = (caddr_t)stack + len;
213
214 out:
215 free(pack->ep_emul_arg, M_TEMP);
216 pack->ep_emul_arg = NULL;
217 return stack;
218
219 bad:
220 stack = NULL;
221 goto out;
222 }
223
224 static int
225 osf1_exec_ecoff_dynamic(struct proc *p, struct exec_package *epp)
226 {
227 struct osf1_exec_emul_arg *emul_arg = epp->ep_emul_arg;
228 struct ecoff_exechdr ldr_exechdr;
229 struct nameidata nd;
230 struct vnode *ldr_vp;
231 char *pathbuf;
232 size_t resid;
233 int error;
234
235
236
237
238 error = emul_find(p, NULL, osf1_emul_path,
239 OSF1_LDR_EXEC_DEFAULT_LOADER, &pathbuf, 0);
240
241 strlcpy(emul_arg->loader_name, pathbuf, sizeof(emul_arg->loader_name));
242 emul_arg->flags |= OSF1_EXEC_EMUL_FLAGS_HAVE_LOADER;
243 if (!error)
244 free((char *)pathbuf, M_TEMP);
245
246 uprintf("loader is %s\n", emul_arg->loader_name);
247
248
249
250
251
252
253 NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE,
254 emul_arg->loader_name, p);
255 if ((error = namei(&nd)) != 0)
256 goto bad_no_vp;
257 ldr_vp = nd.ni_vp;
258
259
260
261
262
263
264
265 if (ldr_vp->v_type != VREG) {
266 error = EACCES;
267 goto badunlock;
268 }
269
270 if ((error = VOP_ACCESS(ldr_vp, VEXEC, p->p_ucred, p)) != 0)
271 goto badunlock;
272
273 if (ldr_vp->v_mount->mnt_flag & MNT_NOEXEC) {
274 error = EACCES;
275 goto badunlock;
276 }
277
278
279
280
281
282 if (ldr_vp->v_mount->mnt_flag & MNT_NOSUID)
283 epp->ep_vap->va_mode &= ~(S_ISUID | S_ISGID);
284
285 VOP_UNLOCK(ldr_vp, 0, p);
286
287
288
289
290 if ((error = vn_rdwr(UIO_READ, ldr_vp, (caddr_t)&ldr_exechdr,
291 sizeof ldr_exechdr, 0, UIO_SYSSPACE, 0, p->p_ucred,
292 &resid, p)) != 0)
293 goto bad;
294 if (resid != 0) {
295 error = ENOEXEC;
296 goto bad;
297 }
298
299
300
301
302
303
304 if (ldr_exechdr.f.f_magic != ECOFF_MAGIC_ALPHA) {
305 error = ENOEXEC;
306 goto bad;
307 }
308 switch (ldr_exechdr.f.f_flags & ECOFF_FLAG_OBJECT_TYPE_MASK) {
309 case ECOFF_OBJECT_TYPE_SHARABLE:
310 case ECOFF_OBJECT_TYPE_CALL_SHARED:
311
312 error = ENOEXEC;
313 goto bad;
314 }
315
316 switch (ldr_exechdr.a.magic) {
317 case ECOFF_OMAGIC:
318 error = exec_ecoff_prep_omagic(p, epp);
319 break;
320 case ECOFF_NMAGIC:
321 error = exec_ecoff_prep_nmagic(p, epp);
322 break;
323 case ECOFF_ZMAGIC:
324 error = exec_ecoff_prep_zmagic(p, epp);
325 break;
326 default:
327 error = ENOEXEC;
328 }
329 if (error)
330 goto bad;
331
332 vrele(ldr_vp);
333 return (0);
334
335 badunlock:
336 VOP_UNLOCK(ldr_vp, 0, p);
337 bad:
338 vrele(ldr_vp);
339 bad_no_vp:
340 return (error);
341 }