Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/compat/osf1 dynamic executable/loader handling, done right
details: https://anonhg.NetBSD.org/src/rev/989470629d00
branches: trunk
changeset: 472310:989470629d00
user: cgd <cgd%NetBSD.org@localhost>
date: Tue Apr 27 05:38:08 1999 +0000
description:
dynamic executable/loader handling, done right
diffstat:
sys/compat/osf1/osf1_exec.c | 125 ++++++++++++++++++++++++++++++++++++++++---
1 files changed, 116 insertions(+), 9 deletions(-)
diffs (172 lines):
diff -r 1f27f0f4a5de -r 989470629d00 sys/compat/osf1/osf1_exec.c
--- a/sys/compat/osf1/osf1_exec.c Tue Apr 27 05:36:43 1999 +0000
+++ b/sys/compat/osf1/osf1_exec.c Tue Apr 27 05:38:08 1999 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: osf1_exec.c,v 1.3 1999/04/27 03:19:44 cgd Exp $ */
+/* $NetBSD: osf1_exec.c,v 1.4 1999/04/27 05:38:08 cgd Exp $ */
/*
* Copyright (c) 1999 Christopher G. Demetriou. All rights reserved.
@@ -112,7 +112,7 @@
switch (execp->f.f_flags & ECOFF_FLAG_OBJECT_TYPE_MASK) {
case ECOFF_OBJECT_TYPE_SHARABLE:
/* can't exec a shared library! */
-#if 1
+#if 0
uprintf("can't execute OSF/1 shared libraries\n");
#endif
error = ENOEXEC;
@@ -127,20 +127,30 @@
error = 0;
break;
}
+
+ if (error) {
+ free(epp->ep_emul_arg, M_TEMP);
+ epp->ep_emul_arg = NULL;
+ kill_vmcmds(&epp->ep_vmcmds); /* if any */
+ }
+
return (error);
}
static int
osf1_exec_ecoff_dynamic(struct proc *p, struct exec_package *epp)
{
-#if 1
- uprintf("OSF/1 dynamically linked binaries not yet supported\n");
- return ENOEXEC;
-#else
struct osf1_exec_emul_arg *emul_arg = epp->ep_emul_arg;
+ struct ecoff_exechdr ldr_exechdr;
+ struct nameidata nd;
+ struct vnode *ldr_vp;
const char *pathbuf;
+ size_t resid;
int error;
+ /*
+ * locate the loader
+ */
error = emul_find(p, NULL, osf1_emul_path,
OSF1_LDR_EXEC_DEFAULT_LOADER, &pathbuf, 0);
/* includes /emul/osf1 if appropriate */
@@ -149,10 +159,107 @@
if (!error)
free((char *)pathbuf, M_TEMP);
+#if 0
uprintf("loader is %s\n", emul_arg->loader_name);
+#endif
+
+ /*
+ * open the loader, see if it's an ECOFF executable,
+ * make sure the object type is amenable, then arrange to
+ * load it up.
+ */
+ NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE,
+ emul_arg->loader_name, p);
+ if ((error = namei(&nd)) != 0)
+ goto bad;
+ ldr_vp = nd.ni_vp;
+
+ /*
+ * Basic access checks. Reject if:
+ * not a regular file
+ * exec not allowed on binary
+ * exec not allowed on mount point
+ */
+ if (ldr_vp->v_type != VREG) {
+ error = EACCES;
+ goto badunlock;
+ }
+
+ if ((error = VOP_ACCESS(ldr_vp, VEXEC, p->p_ucred, p)) != 0)
+ goto badunlock;
+
+ if (ldr_vp->v_mount->mnt_flag & MNT_NOEXEC) {
+ error = EACCES;
+ goto badunlock;
+ }
+
+ /*
+ * If loader's mount point disallows set-id execution,
+ * disable set-id.
+ */
+ if (ldr_vp->v_mount->mnt_flag & MNT_NOSUID)
+ epp->ep_vap->va_mode &= ~(S_ISUID | S_ISGID);
+
+ VOP_UNLOCK(ldr_vp, 0);
- return ENOEXEC;
-#endif
+ /*
+ * read the header, and make sure we got all of it.
+ */
+ if ((error = vn_rdwr(UIO_READ, ldr_vp, (caddr_t)&ldr_exechdr,
+ sizeof ldr_exechdr, 0, UIO_SYSSPACE, 0, p->p_ucred,
+ &resid, p)) != 0)
+ goto bad;
+ if (resid != 0) {
+ error = ENOEXEC;
+ goto bad;
+ }
+
+ /*
+ * Check the magic. We expect it to be the native Alpha ECOFF
+ * (Digital UNIX) magic number. Also make sure it's not a shared
+ * lib or dynamically linked executable.
+ */
+ if (ldr_exechdr.f.f_magic != ECOFF_MAGIC_ALPHA) {
+ error = ENOEXEC;
+ goto bad;
+ }
+ switch (ldr_exechdr.f.f_flags & ECOFF_FLAG_OBJECT_TYPE_MASK) {
+ case ECOFF_OBJECT_TYPE_SHARABLE:
+ case ECOFF_OBJECT_TYPE_CALL_SHARED:
+ /* can't exec shared lib or dynamically linked executable. */
+ error = ENOEXEC;
+ goto bad;
+ }
+
+ switch (ldr_exechdr.a.magic) {
+ case ECOFF_OMAGIC:
+ error = exec_ecoff_prep_omagic(p, epp, &ldr_exechdr, ldr_vp);
+ break;
+ case ECOFF_NMAGIC:
+ error = exec_ecoff_prep_nmagic(p, epp, &ldr_exechdr, ldr_vp);
+ break;
+ case ECOFF_ZMAGIC:
+ error = exec_ecoff_prep_zmagic(p, epp, &ldr_exechdr, ldr_vp);
+ break;
+ default:
+ error = ENOEXEC;
+ }
+ if (error)
+ goto bad;
+
+ /* finally, set up the stack. */
+ error = exec_ecoff_setup_stack(p, epp);
+ if (error)
+ goto bad;
+
+ vrele(ldr_vp);
+ return (0);
+
+badunlock:
+ VOP_UNLOCK(ldr_vp, 0);
+bad:
+ vrele(ldr_vp);
+ return (error);
}
/*
@@ -220,7 +327,7 @@
stack = (caddr_t)stack + len;
out:
- FREE(pack->ep_emul_arg, M_TEMP);
+ free(pack->ep_emul_arg, M_TEMP);
pack->ep_emul_arg = NULL;
return stack;
Home |
Main Index |
Thread Index |
Old Index