svn commit: r302962 - in stable/10/sys: amd64/linux amd64/linux32 compat/linux i386/linux
Dmitry Chagin
dchagin at FreeBSD.org
Sun Jul 17 15:07:35 UTC 2016
Author: dchagin
Date: Sun Jul 17 15:07:33 2016
New Revision: 302962
URL: https://svnweb.freebsd.org/changeset/base/302962
Log:
MFC r302515:
Implement Linux personality() system call mainly due to READ_IMPLIES_EXEC flag.
In Linux if this flag is set, PROT_READ implies PROT_EXEC for mmap().
Linux/i386 set this flag automatically if the binary requires executable stack.
READ_IMPLIES_EXEC flag will be used in the next Linux mmap() commit.
Added:
stable/10/sys/compat/linux/linux_persona.h
- copied unchanged from r302515, head/sys/compat/linux/linux_persona.h
Modified:
stable/10/sys/amd64/linux/syscalls.master
stable/10/sys/amd64/linux32/syscalls.master
stable/10/sys/compat/linux/linux_emul.c
stable/10/sys/compat/linux/linux_emul.h
stable/10/sys/compat/linux/linux_misc.c
stable/10/sys/i386/linux/syscalls.master
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/amd64/linux/syscalls.master
==============================================================================
--- stable/10/sys/amd64/linux/syscalls.master Sun Jul 17 14:45:15 2016 (r302961)
+++ stable/10/sys/amd64/linux/syscalls.master Sun Jul 17 15:07:33 2016 (r302962)
@@ -270,7 +270,7 @@
133 AUE_MKNOD STD { int linux_mknod(char *path, l_int mode, \
l_dev_t dev); }
134 AUE_USELIB UNIMPL uselib
-135 AUE_PERSONALITY STD { int linux_personality(l_ulong per); }
+135 AUE_PERSONALITY STD { int linux_personality(l_uint per); }
136 AUE_NULL STD { int linux_ustat(l_dev_t dev, \
struct l_ustat *ubuf); }
137 AUE_STATFS STD { int linux_statfs(char *path, \
Modified: stable/10/sys/amd64/linux32/syscalls.master
==============================================================================
--- stable/10/sys/amd64/linux32/syscalls.master Sun Jul 17 14:45:15 2016 (r302961)
+++ stable/10/sys/amd64/linux32/syscalls.master Sun Jul 17 15:07:33 2016 (r302962)
@@ -238,7 +238,7 @@
134 AUE_BDFLUSH STD { int linux_bdflush(void); }
135 AUE_NULL STD { int linux_sysfs(l_int option, \
l_ulong arg1, l_ulong arg2); }
-136 AUE_PERSONALITY STD { int linux_personality(l_ulong per); }
+136 AUE_PERSONALITY STD { int linux_personality(l_uint per); }
137 AUE_NULL UNIMPL afs_syscall
138 AUE_SETFSUID STD { int linux_setfsuid16(l_uid16_t uid); }
139 AUE_SETFSGID STD { int linux_setfsgid16(l_gid16_t gid); }
Modified: stable/10/sys/compat/linux/linux_emul.c
==============================================================================
--- stable/10/sys/compat/linux/linux_emul.c Sun Jul 17 14:45:15 2016 (r302961)
+++ stable/10/sys/compat/linux/linux_emul.c Sun Jul 17 15:07:33 2016 (r302962)
@@ -45,6 +45,7 @@ __FBSDID("$FreeBSD$");
#include <compat/linux/linux_emul.h>
#include <compat/linux/linux_misc.h>
+#include <compat/linux/linux_persona.h>
#include <compat/linux/linux_util.h>
@@ -127,7 +128,7 @@ linux_proc_init(struct thread *td, struc
/* epoll should be destroyed in a case of exec. */
pem = pem_find(p);
KASSERT(pem != NULL, ("proc_exit: proc emuldata not found.\n"));
-
+ pem->persona = 0;
if (pem->epoll != NULL) {
emd = pem->epoll;
pem->epoll = NULL;
@@ -220,6 +221,9 @@ linux_proc_exec(void *arg __unused, stru
{
struct thread *td = curthread;
struct thread *othertd;
+#if defined(__amd64__)
+ struct linux_pemuldata *pem;
+#endif
/*
* In a case of execing from linux binary properly detach
@@ -243,6 +247,17 @@ linux_proc_exec(void *arg __unused, stru
linux_proc_init(td, NULL, 0);
else
linux_proc_init(td, td, 0);
+#if defined(__amd64__)
+ /*
+ * An IA32 executable which has executable stack will have the
+ * READ_IMPLIES_EXEC personality flag set automatically.
+ */
+ if (SV_PROC_FLAG(td->td_proc, SV_ILP32) &&
+ imgp->stack_prot & VM_PROT_EXECUTE) {
+ pem = pem_find(p);
+ pem->persona |= LINUX_READ_IMPLIES_EXEC;
+ }
+#endif
}
}
Modified: stable/10/sys/compat/linux/linux_emul.h
==============================================================================
--- stable/10/sys/compat/linux/linux_emul.h Sun Jul 17 14:45:15 2016 (r302961)
+++ stable/10/sys/compat/linux/linux_emul.h Sun Jul 17 15:07:33 2016 (r302962)
@@ -67,6 +67,7 @@ struct linux_pemuldata {
uint32_t flags; /* process emuldata flags */
struct sx pem_sx; /* lock for this struct */
void *epoll; /* epoll data */
+ uint32_t persona; /* process execution domain */
};
#define LINUX_PEM_XLOCK(p) sx_xlock(&(p)->pem_sx)
Modified: stable/10/sys/compat/linux/linux_misc.c
==============================================================================
--- stable/10/sys/compat/linux/linux_misc.c Sun Jul 17 14:45:15 2016 (r302961)
+++ stable/10/sys/compat/linux/linux_misc.c Sun Jul 17 15:07:33 2016 (r302962)
@@ -1198,15 +1198,23 @@ linux_mknodat(struct thread *td, struct
int
linux_personality(struct thread *td, struct linux_personality_args *args)
{
+ struct linux_pemuldata *pem;
+ struct proc *p = td->td_proc;
+ uint32_t old;
+
#ifdef DEBUG
if (ldebug(personality))
- printf(ARGS(personality, "%lu"), (unsigned long)args->per);
+ printf(ARGS(personality, "%u"), args->per);
#endif
- if (args->per != 0)
- return (EINVAL);
- /* Yes Jim, it's still a Linux... */
- td->td_retval[0] = 0;
+ PROC_LOCK(p);
+ pem = pem_find(p);
+ old = pem->persona;
+ if (args->per != 0xffffffff)
+ pem->persona = args->per;
+ PROC_UNLOCK(p);
+
+ td->td_retval[0] = old;
return (0);
}
Copied: stable/10/sys/compat/linux/linux_persona.h (from r302515, head/sys/compat/linux/linux_persona.h)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ stable/10/sys/compat/linux/linux_persona.h Sun Jul 17 15:07:33 2016 (r302962, copy of r302515, head/sys/compat/linux/linux_persona.h)
@@ -0,0 +1,56 @@
+/*
+ * $FreeBSD$
+ */
+
+#ifndef LINUX_PERSONALITY_H
+#define LINUX_PERSONALITY_H
+
+/*
+ * Flags for bug emulation.
+ *
+ * These occupy the top three bytes.
+ */
+enum {
+ LINUX_UNAME26 = 0x0020000,
+ LINUX_ADDR_NO_RANDOMIZE = 0x0040000, /* disable randomization
+ * of VA space
+ */
+ LINUX_FDPIC_FUNCPTRS = 0x0080000, /* userspace function
+ * ptrs point to descriptors
+ * (signal handling)
+ */
+ LINUX_MMAP_PAGE_ZERO = 0x0100000,
+ LINUX_ADDR_COMPAT_LAYOUT = 0x0200000,
+ LINUX_READ_IMPLIES_EXEC = 0x0400000,
+ LINUX_ADDR_LIMIT_32BIT = 0x0800000,
+ LINUX_SHORT_INODE = 0x1000000,
+ LINUX_WHOLE_SECONDS = 0x2000000,
+ LINUX_STICKY_TIMEOUTS = 0x4000000,
+ LINUX_ADDR_LIMIT_3GB = 0x8000000,
+};
+
+/*
+ * Security-relevant compatibility flags that must be
+ * cleared upon setuid or setgid exec:
+ */
+#define LINUX_PER_CLEAR_ON_SETID (LINUX_READ_IMPLIES_EXEC | \
+ LINUX_ADDR_NO_RANDOMIZE | \
+ LINUX_ADDR_COMPAT_LAYOUT | \
+ LINUX_MMAP_PAGE_ZERO)
+
+/*
+ * Personality types.
+ *
+ * These go in the low byte. Avoid using the top bit, it will
+ * conflict with error returns.
+ */
+enum {
+ LINUX_PER_LINUX = 0x0000,
+ LINUX_PER_LINUX_32BIT = 0x0000 | LINUX_ADDR_LIMIT_32BIT,
+ LINUX_PER_LINUX_FDPIC = 0x0000 | LINUX_FDPIC_FUNCPTRS,
+ LINUX_PER_LINUX32 = 0x0008,
+ LINUX_PER_LINUX32_3GB = 0x0008 | LINUX_ADDR_LIMIT_3GB,
+ LINUX_PER_MASK = 0x00ff,
+};
+
+#endif /* LINUX_PERSONALITY_H */
Modified: stable/10/sys/i386/linux/syscalls.master
==============================================================================
--- stable/10/sys/i386/linux/syscalls.master Sun Jul 17 14:45:15 2016 (r302961)
+++ stable/10/sys/i386/linux/syscalls.master Sun Jul 17 15:07:33 2016 (r302962)
@@ -240,7 +240,7 @@
134 AUE_BDFLUSH STD { int linux_bdflush(void); }
135 AUE_NULL STD { int linux_sysfs(l_int option, \
l_ulong arg1, l_ulong arg2); }
-136 AUE_PERSONALITY STD { int linux_personality(l_ulong per); }
+136 AUE_PERSONALITY STD { int linux_personality(l_uint per); }
137 AUE_NULL UNIMPL afs_syscall
138 AUE_SETFSUID STD { int linux_setfsuid16(l_uid16_t uid); }
139 AUE_SETFSGID STD { int linux_setfsgid16(l_gid16_t gid); }
More information about the svn-src-stable-10
mailing list