summaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2010-03-10 15:21:19 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2010-03-12 15:52:32 -0800
commite28cbf22933d0c0ccaf3c4c27a1a263b41f73859 (patch)
treea93ff48cfd97766a23b2c4f3ea86fccfc9c51d3f /kernel/sys.c
parentbaed7fc9b580bd3fb8252ff1d9b36eaf1f86b670 (diff)
downloadlinux-e28cbf22933d0c0ccaf3c4c27a1a263b41f73859.tar.gz
linux-e28cbf22933d0c0ccaf3c4c27a1a263b41f73859.tar.bz2
linux-e28cbf22933d0c0ccaf3c4c27a1a263b41f73859.zip
improve sys_newuname() for compat architectures
On an architecture that supports 32-bit compat we need to override the reported machine in uname with the 32-bit value. Instead of doing this separately in every architecture introduce a COMPAT_UTS_MACHINE define in <asm/compat.h> and apply it directly in sys_newuname(). Signed-off-by: Christoph Hellwig <hch@lst.de> Cc: Ralf Baechle <ralf@linux-mips.org> Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org> Cc: Paul Mundt <lethal@linux-sh.org> Cc: Jeff Dike <jdike@addtoit.com> Cc: Hirokazu Takata <takata@linux-m32r.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@elte.hu> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Arnd Bergmann <arnd@arndb.de> Cc: Heiko Carstens <heiko.carstens@de.ibm.com> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com> Cc: "Luck, Tony" <tony.luck@intel.com> Cc: James Morris <jmorris@namei.org> Cc: Andreas Schwab <schwab@linux-m68k.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'kernel/sys.c')
-rw-r--r--kernel/sys.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index 9814e43fb23b..e483eb5530e4 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -33,6 +33,7 @@
#include <linux/task_io_accounting_ops.h>
#include <linux/seccomp.h>
#include <linux/cpu.h>
+#include <linux/personality.h>
#include <linux/ptrace.h>
#include <linux/fs_struct.h>
@@ -1114,6 +1115,15 @@ out:
DECLARE_RWSEM(uts_sem);
+#ifdef COMPAT_UTS_MACHINE
+#define override_architecture(name) \
+ (current->personality == PER_LINUX32 && \
+ copy_to_user(name->machine, COMPAT_UTS_MACHINE, \
+ sizeof(COMPAT_UTS_MACHINE)))
+#else
+#define override_architecture(name) 0
+#endif
+
SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name)
{
int errno = 0;
@@ -1122,6 +1132,9 @@ SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name)
if (copy_to_user(name, utsname(), sizeof *name))
errno = -EFAULT;
up_read(&uts_sem);
+
+ if (!errno && override_architecture(name))
+ errno = -EFAULT;
return errno;
}