summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorPhilip Guenthe <guenther@cvs.openbsd.org>2010-01-04 19:27:22 +0000
committerPhilip Guenthe <guenther@cvs.openbsd.org>2010-01-04 19:27:22 +0000
commita26f38ecb5333a71a35ddf489a8da5ccfeba3c7c (patch)
treebf47e6c25b80e40705eb620930c68e8f232da381 /sys
parent0cd9308f43d1309399f86f68a1eb1e1957e1eb5b (diff)
Previous commit was too restrictive: just ignore the CLONE_FS flag
when not doing CLONE_THREAD, like we did before, instead of treating it as an error. This unbreaks Opera running in linux compat. Also, Linux completely ignores CLONE_DETACHED, so do that too, and consistently refer to the flags in comment via their Linux names without trying to abbreviate them further. Problem found and fix confirmed by sturm@
Diffstat (limited to 'sys')
-rw-r--r--sys/compat/linux/linux_sched.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/sys/compat/linux/linux_sched.c b/sys/compat/linux/linux_sched.c
index f2011ea95b2..7500d978231 100644
--- a/sys/compat/linux/linux_sched.c
+++ b/sys/compat/linux/linux_sched.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: linux_sched.c,v 1.7 2009/12/28 02:54:24 guenther Exp $ */
+/* $OpenBSD: linux_sched.c,v 1.8 2010/01/04 19:27:21 guenther Exp $ */
/* $NetBSD: linux_sched.c,v 1.6 2000/05/28 05:49:05 thorpej Exp $ */
/*-
@@ -73,7 +73,7 @@ linux_sys_clone(p, v, retval)
if (cflags & ~(LINUX_CLONE_CSIGNAL | LINUX_CLONE_VM | LINUX_CLONE_FS |
LINUX_CLONE_FILES | LINUX_CLONE_SIGHAND | LINUX_CLONE_VFORK |
LINUX_CLONE_PARENT | LINUX_CLONE_THREAD | LINUX_CLONE_SYSVSEM |
- LINUX_CLONE_UNTRACED))
+ LINUX_CLONE_DETACHED | LINUX_CLONE_UNTRACED))
return (EINVAL);
if (cflags & LINUX_CLONE_VM)
@@ -81,7 +81,7 @@ linux_sys_clone(p, v, retval)
if (cflags & LINUX_CLONE_FILES)
flags |= FORK_SHAREFILES;
if (cflags & LINUX_CLONE_SIGHAND) {
- /* According to Linux, SIGHAND requires VM */
+ /* According to Linux, CLONE_SIGHAND requires CLONE_VM */
if ((cflags & LINUX_CLONE_VM) == 0)
return (EINVAL);
flags |= FORK_SIGHAND;
@@ -90,10 +90,11 @@ linux_sys_clone(p, v, retval)
flags |= FORK_PPWAIT;
if (cflags & LINUX_CLONE_THREAD) {
/*
- * Linux agrees with us: THREAD requires SIGHAND.
- * Unlike Linux, we also also require FS and SYSVSEM.
- * Also, we decree it to be incompatible with VFORK, as
- * I don't want to work out whether that's 100% safe.
+ * Linux agrees with us: CLONE_THREAD requires
+ * CLONE_SIGHAND. Unlike Linux, we also also require
+ * CLONE_FS and CLONE_SYSVSEM. Also, we decree it
+ * to be incompatible with CLONE_VFORK, as I don't
+ * want to work out whether that's 100% safe.
*/
#define REQUIRED \
(LINUX_CLONE_SIGHAND | LINUX_CLONE_FS | LINUX_CLONE_SYSVSEM)
@@ -102,21 +103,36 @@ linux_sys_clone(p, v, retval)
if ((cflags & (REQUIRED | BANNED)) != REQUIRED)
return (EINVAL);
/*
- * Linux says that THREAD means no signal will be
- * sent on exit (even if a non-standard signal is
- * requested via LINUX_CLONE_CSIGNAL), so pass
+ * Linux says that CLONE_THREAD means no signal
+ * will be sent on exit (even if a non-standard
+ * signal is requested via CLONE_CSIGNAL), so pass
* FORK_NOZOMBIE too.
*/
flags |= FORK_THREAD | FORK_NOZOMBIE;
} else {
- /* only supported with THREAD */
- if (cflags & (LINUX_CLONE_FS | LINUX_CLONE_PARENT |
- LINUX_CLONE_SYSVSEM))
+ /*
+ * These are only supported with CLONE_THREAD. Arguably,
+ * CLONE_FS should be in this list, because we don't
+ * support sharing of working directory and root directory
+ * (chdir + chroot) except via threads. On the other
+ * hand, we tie the sharing of umask to the sharing of
+ * files, so a process that doesn't request CLONE_FS but
+ * does ask for CLONE_FILES is going to get some of the
+ * former's effect. Some programs (e.g., Opera) at least
+ * _seem_ to work if we let it through, so we'll just
+ * cross our fingers for now and silently ignore it if
+ * CLONE_FILES was also requested.
+ */
+ if (cflags & (LINUX_CLONE_PARENT | LINUX_CLONE_SYSVSEM))
+ return (EINVAL);
+ if ((cflags & (LINUX_CLONE_FS | LINUX_CLONE_FILES)) ==
+ LINUX_CLONE_FS)
return (EINVAL);
}
/*
* Since we don't support CLONE_PTRACE, the CLONE_UNTRACED
- * flag can be silently ignored.
+ * flag can be silently ignored. CLONE_DETACHED is always
+ * ignored by Linux.
*/
sig = cflags & LINUX_CLONE_CSIGNAL;