summaryrefslogtreecommitdiff
path: root/sys/compat
diff options
context:
space:
mode:
authorRobert Nagy <robert@cvs.openbsd.org>2011-12-14 08:33:19 +0000
committerRobert Nagy <robert@cvs.openbsd.org>2011-12-14 08:33:19 +0000
commit28418b9c18a7140add5f1412afc87f068dcdfb0e (patch)
tree1bf3bb32588836160d7be4d8f7e34367970dd2fc /sys/compat
parent24411f6f435ea431230a0ce4d62b6e8c4a67208e (diff)
implement prctl() for COMPAT_LINUX
ok pirofti@
Diffstat (limited to 'sys/compat')
-rw-r--r--sys/compat/linux/linux_dummy.c3
-rw-r--r--sys/compat/linux/linux_emuldata.h3
-rw-r--r--sys/compat/linux/linux_misc.c84
-rw-r--r--sys/compat/linux/linux_misc.h15
-rw-r--r--sys/compat/linux/syscalls.master6
5 files changed, 104 insertions, 7 deletions
diff --git a/sys/compat/linux/linux_dummy.c b/sys/compat/linux/linux_dummy.c
index d77613043cd..983e76fceb2 100644
--- a/sys/compat/linux/linux_dummy.c
+++ b/sys/compat/linux/linux_dummy.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: linux_dummy.c,v 1.18 2011/11/25 10:10:05 robert Exp $ */
+/* $OpenBSD: linux_dummy.c,v 1.19 2011/12/14 08:33:18 robert Exp $ */
/*-
* Copyright (c) 1994-1995 Søren Schmidt
@@ -99,7 +99,6 @@ DUMMY(sched_rr_get_interval); /* #161 */
DUMMY(vm86); /* #166 */
DUMMY(query_module); /* #167 */
DUMMY(nfsservctl); /* #169 */
-DUMMY(prctl); /* #172 */
DUMMY(rt_sigtimedwait); /* #177 */
DUMMY(rt_queueinfo); /* #178 */
DUMMY(capget); /* #184 */
diff --git a/sys/compat/linux/linux_emuldata.h b/sys/compat/linux/linux_emuldata.h
index 63b22d1e498..783327715cb 100644
--- a/sys/compat/linux/linux_emuldata.h
+++ b/sys/compat/linux/linux_emuldata.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: linux_emuldata.h,v 1.7 2011/09/18 02:23:18 pirofti Exp $ */
+/* $OpenBSD: linux_emuldata.h,v 1.8 2011/12/14 08:33:18 robert Exp $ */
/* $NetBSD: linux_emuldata.h,v 1.4 2002/02/15 16:48:02 christos Exp $ */
/*-
* Copyright (c) 1998,2002 The NetBSD Foundation, Inc.
@@ -51,5 +51,6 @@ struct linux_emuldata {
struct linux_robust_list_head *led_robust_head;
+ int pdeath_signal; /* parent death signal */
};
#endif /* !_LINUX_EMULDATA_H_ */
diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
index 57020d126fa..ffa718dc1be 100644
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: linux_misc.c,v 1.72 2011/07/09 00:10:52 deraadt Exp $ */
+/* $OpenBSD: linux_misc.c,v 1.73 2011/12/14 08:33:18 robert Exp $ */
/* $NetBSD: linux_misc.c,v 1.27 1996/05/20 01:59:21 fvdl Exp $ */
/*-
@@ -1481,3 +1481,85 @@ linux_sys_swapon(struct proc *p, void *v, register_t *retval)
SCARG(&ua, misc) = 0; /* priority */
return (sys_swapctl(p, &ua, retval));
}
+
+int
+linux_sys_prctl(struct proc *p, void *v, register_t *retval)
+{
+ int error = 0, max_size, pdeath_signal;
+ char comm[LINUX_MAX_COMM_LEN];
+ struct linux_emuldata *ed = (struct linux_emuldata*)p->p_emuldata;
+
+ struct linux_sys_prctl_args /* {
+ int option;
+ unsigned long arg2;
+ unsigned long arg3;
+ unsigned long arg4;
+ unsigned long arg5;
+ } */ *uap = v;
+
+ switch (SCARG(uap, option)) {
+ case LINUX_PR_SET_PDEATHSIG:
+ if (SCARG(uap, arg2) < 0 || SCARG(uap, arg2) >= LINUX__NSIG)
+ return (EINVAL);
+ ed->pdeath_signal = SCARG(uap, arg2);
+ break;
+ case LINUX_PR_GET_PDEATHSIG:
+ pdeath_signal = ed->pdeath_signal;
+ error = copyout(&pdeath_signal, (void *)SCARG(uap, arg2),
+ sizeof(pdeath_signal));
+ break;
+ case LINUX_PR_GET_KEEPCAPS:
+ /*
+ * Indicate that we always clear the effective and
+ * permitted capability sets when the user id becomes
+ * non-zero (actually the capability sets are simply
+ * always zero in the current implementation).
+ */
+ *retval = 0;
+ break;
+ case LINUX_PR_SET_KEEPCAPS:
+ /* Ignore requests to keep the effective and permitted
+ * capability sets when the user id becomes non-zero.
+ */
+ break;
+ case LINUX_PR_SET_NAME:
+ /*
+ * To be on the safe side we need to make sure not to
+ * overflow the size a linux program expects. We already
+ * do this here in the copyin, so that we don't need to
+ * check on copyout.
+ */
+ max_size = MIN(sizeof(comm), sizeof(p->p_comm));
+ error = copyinstr((void *)SCARG(uap, arg2), comm,
+ max_size, NULL);
+
+ /* Linux silently truncates the name if it is too long. */
+ if (error == ENAMETOOLONG) {
+ /*
+ * XXX: copyinstr() isn't documented to populate the
+ * array completely, so do a copyin() to be on the
+ * safe side. This should be changed in case copyinstr()
+ * is changed to guarantee this.
+ */
+ error = copyin((void *)SCARG(uap, arg2), comm,
+ max_size - 1);
+ comm[max_size - 1] = '\0';
+ }
+ if (error)
+ return (error);
+ strlcpy(p->p_comm, comm, sizeof(p->p_comm));
+ break;
+ case LINUX_PR_GET_NAME:
+ strlcpy(comm, p->p_comm, sizeof(comm));
+ error = copyout(comm, (void *)SCARG(uap, arg2),
+ strlen(comm) + 1);
+ break;
+ default:
+ printf("linux_sys_prctl: unsupported option %d\n",
+ SCARG(uap, option));
+ error = EINVAL;
+ break;
+ }
+
+ return (error);
+}
diff --git a/sys/compat/linux/linux_misc.h b/sys/compat/linux/linux_misc.h
index a4fd5c17baa..a556cba3159 100644
--- a/sys/compat/linux/linux_misc.h
+++ b/sys/compat/linux/linux_misc.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: linux_misc.h,v 1.5 2011/04/05 22:54:30 pirofti Exp $ */
+/* $OpenBSD: linux_misc.h,v 1.6 2011/12/14 08:33:18 robert Exp $ */
/* $NetBSD: linux_misc.h,v 1.3 1999/05/13 00:31:57 thorpej Exp $ */
/*-
@@ -33,6 +33,19 @@
#ifndef _LINUX_MISC_H_
#define _LINUX_MISC_H_
+/* defined for prctl(2) */
+#define LINUX_PR_SET_PDEATHSIG 1 /* Second arg is signal. */
+#define LINUX_PR_GET_PDEATHSIG 2 /*
+ * Second arg is a ptr to return the
+ * signal.
+ */
+#define LINUX_PR_GET_KEEPCAPS 7 /* Get drop capabilities on setuid */
+#define LINUX_PR_SET_KEEPCAPS 8 /* Set drop capabilities on setuid */
+#define LINUX_PR_SET_NAME 15 /* Set process name. */
+#define LINUX_PR_GET_NAME 16 /* Get process name. */
+
+#define LINUX_MAX_COMM_LEN 16 /* Maximum length of process name. */
+
/* This looks very unportable to me, but this is how Linux defines it. */
struct linux_sysinfo {
long uptime;
diff --git a/sys/compat/linux/syscalls.master b/sys/compat/linux/syscalls.master
index ed1132c5358..78c776f17c0 100644
--- a/sys/compat/linux/syscalls.master
+++ b/sys/compat/linux/syscalls.master
@@ -1,4 +1,4 @@
- $OpenBSD: syscalls.master,v 1.65 2011/11/25 10:10:05 robert Exp $
+ $OpenBSD: syscalls.master,v 1.66 2011/12/14 08:33:18 robert Exp $
; $NetBSD: syscalls.master,v 1.15 1995/12/18 14:35:10 fvdl Exp $
; @(#)syscalls.master 8.1 (Berkeley) 7/19/93
@@ -286,7 +286,9 @@
u_int16_t egid, u_int16_t sgid); }
171 STD { int linux_sys_getresgid16(u_int16_t *rgid, \
u_int16_t *egid, u_int16_t *sgid); }
-172 STD { int linux_sys_prctl(void); }
+172 STD { int linux_sys_prctl(int option, unsigned long arg2, \
+ unsigned long arg3, unsigned long arg4, \
+ unsigned long arg5); }
173 STD { int linux_sys_rt_sigreturn( \
struct linux_rt_sigframe *sfp); }
174 STD { int linux_sys_rt_sigaction(int signum, \