|
Kyle McMartin |
159f2cc |
From f45716729488bd8263b06e7d672c8ff8f2ded8b7 Mon Sep 17 00:00:00 2001
|
|
Kyle McMartin |
278c1a8 |
From: H. Peter Anvin <hpa@linux.intel.com>
|
|
Kyle McMartin |
278c1a8 |
Date: Tue, 7 Sep 2010 16:16:18 -0700
|
|
Kyle McMartin |
159f2cc |
Subject: [PATCH 1/4] compat: Make compat_alloc_user_space() incorporate the access_ok()
|
|
Kyle McMartin |
278c1a8 |
|
|
Kyle McMartin |
278c1a8 |
compat_alloc_user_space() expects the caller to independently call
|
|
Kyle McMartin |
278c1a8 |
access_ok() to verify the returned area. A missing call could
|
|
Kyle McMartin |
278c1a8 |
introduce problems on some architectures.
|
|
Kyle McMartin |
278c1a8 |
|
|
Kyle McMartin |
278c1a8 |
This patch incorporates the access_ok() check into
|
|
Kyle McMartin |
278c1a8 |
compat_alloc_user_space() and also adds a sanity check on the length.
|
|
Kyle McMartin |
278c1a8 |
The existing compat_alloc_user_space() implementations are renamed
|
|
Kyle McMartin |
278c1a8 |
arch_compat_alloc_user_space() and are used as part of the
|
|
Kyle McMartin |
278c1a8 |
implementation of the new global function.
|
|
Kyle McMartin |
278c1a8 |
|
|
Kyle McMartin |
278c1a8 |
This patch assumes NULL will cause __get_user()/__put_user() to either
|
|
Kyle McMartin |
278c1a8 |
fail or access userspace on all architectures. This should be
|
|
Kyle McMartin |
278c1a8 |
followed by checking the return value of compat_access_user_space()
|
|
Kyle McMartin |
278c1a8 |
for NULL in the callers, at which time the access_ok() in the callers
|
|
Kyle McMartin |
278c1a8 |
can also be removed.
|
|
Kyle McMartin |
278c1a8 |
|
|
Kyle McMartin |
278c1a8 |
Reported-by: Ben Hawkes <hawkes@sota.gen.nz>
|
|
Kyle McMartin |
278c1a8 |
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
|
|
Kyle McMartin |
278c1a8 |
Acked-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
|
Kyle McMartin |
278c1a8 |
Acked-by: Chris Metcalf <cmetcalf@tilera.com>
|
|
Kyle McMartin |
278c1a8 |
Acked-by: David S. Miller <davem@davemloft.net>
|
|
Kyle McMartin |
278c1a8 |
Acked-by: Ingo Molnar <mingo@elte.hu>
|
|
Kyle McMartin |
278c1a8 |
Acked-by: Thomas Gleixner <tglx@linutronix.de>
|
|
Kyle McMartin |
278c1a8 |
Acked-by: Tony Luck <tony.luck@intel.com>
|
|
Kyle McMartin |
278c1a8 |
Cc: Andrew Morton <akpm@linux-foundation.org>
|
|
Kyle McMartin |
278c1a8 |
Cc: Arnd Bergmann <arnd@arndb.de>
|
|
Kyle McMartin |
278c1a8 |
Cc: Fenghua Yu <fenghua.yu@intel.com>
|
|
Kyle McMartin |
278c1a8 |
Cc: H. Peter Anvin <hpa@zytor.com>
|
|
Kyle McMartin |
278c1a8 |
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
|
|
Kyle McMartin |
278c1a8 |
Cc: Helge Deller <deller@gmx.de>
|
|
Kyle McMartin |
278c1a8 |
Cc: James Bottomley <jejb@parisc-linux.org>
|
|
Kyle McMartin |
278c1a8 |
Cc: Kyle McMartin <kyle@mcmartin.ca>
|
|
Kyle McMartin |
278c1a8 |
Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
|
|
Kyle McMartin |
278c1a8 |
Cc: Paul Mackerras <paulus@samba.org>
|
|
Kyle McMartin |
278c1a8 |
Cc: Ralf Baechle <ralf@linux-mips.org>
|
|
Kyle McMartin |
278c1a8 |
Cc: <stable@kernel.org>
|
|
Kyle McMartin |
278c1a8 |
---
|
|
Kyle McMartin |
278c1a8 |
arch/ia64/include/asm/compat.h | 2 +-
|
|
Kyle McMartin |
278c1a8 |
arch/mips/include/asm/compat.h | 2 +-
|
|
Kyle McMartin |
278c1a8 |
arch/parisc/include/asm/compat.h | 2 +-
|
|
Kyle McMartin |
278c1a8 |
arch/powerpc/include/asm/compat.h | 2 +-
|
|
Kyle McMartin |
278c1a8 |
arch/s390/include/asm/compat.h | 2 +-
|
|
Kyle McMartin |
278c1a8 |
arch/sparc/include/asm/compat.h | 2 +-
|
|
Kyle McMartin |
278c1a8 |
arch/x86/include/asm/compat.h | 2 +-
|
|
Kyle McMartin |
159f2cc |
include/linux/compat.h | 2 ++
|
|
Kyle McMartin |
278c1a8 |
kernel/compat.c | 21 +++++++++++++++++++++
|
|
Kyle McMartin |
159f2cc |
9 files changed, 30 insertions(+), 7 deletions(-)
|
|
Kyle McMartin |
278c1a8 |
|
|
Kyle McMartin |
278c1a8 |
diff --git a/arch/ia64/include/asm/compat.h b/arch/ia64/include/asm/compat.h
|
|
Kyle McMartin |
159f2cc |
index dfcf75b..c8662cd 100644
|
|
Kyle McMartin |
278c1a8 |
--- a/arch/ia64/include/asm/compat.h
|
|
Kyle McMartin |
278c1a8 |
+++ b/arch/ia64/include/asm/compat.h
|
|
Kyle McMartin |
159f2cc |
@@ -198,7 +198,7 @@ ptr_to_compat(void __user *uptr)
|
|
Kyle McMartin |
278c1a8 |
}
|
|
Kyle McMartin |
278c1a8 |
|
|
Kyle McMartin |
278c1a8 |
static __inline__ void __user *
|
|
Kyle McMartin |
278c1a8 |
-compat_alloc_user_space (long len)
|
|
Kyle McMartin |
278c1a8 |
+arch_compat_alloc_user_space (long len)
|
|
Kyle McMartin |
278c1a8 |
{
|
|
Kyle McMartin |
278c1a8 |
struct pt_regs *regs = task_pt_regs(current);
|
|
Kyle McMartin |
278c1a8 |
return (void __user *) (((regs->r12 & 0xffffffff) & -16) - len);
|
|
Kyle McMartin |
278c1a8 |
diff --git a/arch/mips/include/asm/compat.h b/arch/mips/include/asm/compat.h
|
|
Kyle McMartin |
159f2cc |
index f58aed3..27505bd 100644
|
|
Kyle McMartin |
278c1a8 |
--- a/arch/mips/include/asm/compat.h
|
|
Kyle McMartin |
278c1a8 |
+++ b/arch/mips/include/asm/compat.h
|
|
Kyle McMartin |
159f2cc |
@@ -144,7 +144,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
|
|
Kyle McMartin |
278c1a8 |
return (u32)(unsigned long)uptr;
|
|
Kyle McMartin |
278c1a8 |
}
|
|
Kyle McMartin |
278c1a8 |
|
|
Kyle McMartin |
278c1a8 |
-static inline void __user *compat_alloc_user_space(long len)
|
|
Kyle McMartin |
278c1a8 |
+static inline void __user *arch_compat_alloc_user_space(long len)
|
|
Kyle McMartin |
278c1a8 |
{
|
|
Kyle McMartin |
278c1a8 |
struct pt_regs *regs = (struct pt_regs *)
|
|
Kyle McMartin |
278c1a8 |
((unsigned long) current_thread_info() + THREAD_SIZE - 32) - 1;
|
|
Kyle McMartin |
278c1a8 |
diff --git a/arch/parisc/include/asm/compat.h b/arch/parisc/include/asm/compat.h
|
|
Kyle McMartin |
159f2cc |
index 7f32611..7c77fa9 100644
|
|
Kyle McMartin |
278c1a8 |
--- a/arch/parisc/include/asm/compat.h
|
|
Kyle McMartin |
278c1a8 |
+++ b/arch/parisc/include/asm/compat.h
|
|
Kyle McMartin |
159f2cc |
@@ -146,7 +146,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
|
|
Kyle McMartin |
278c1a8 |
return (u32)(unsigned long)uptr;
|
|
Kyle McMartin |
278c1a8 |
}
|
|
Kyle McMartin |
278c1a8 |
|
|
Kyle McMartin |
278c1a8 |
-static __inline__ void __user *compat_alloc_user_space(long len)
|
|
Kyle McMartin |
278c1a8 |
+static __inline__ void __user *arch_compat_alloc_user_space(long len)
|
|
Kyle McMartin |
278c1a8 |
{
|
|
Kyle McMartin |
278c1a8 |
struct pt_regs *regs = ¤t->thread.regs;
|
|
Kyle McMartin |
278c1a8 |
return (void __user *)regs->gr[30];
|
|
Kyle McMartin |
278c1a8 |
diff --git a/arch/powerpc/include/asm/compat.h b/arch/powerpc/include/asm/compat.h
|
|
Kyle McMartin |
159f2cc |
index 4774c2f..8d0fff3 100644
|
|
Kyle McMartin |
278c1a8 |
--- a/arch/powerpc/include/asm/compat.h
|
|
Kyle McMartin |
278c1a8 |
+++ b/arch/powerpc/include/asm/compat.h
|
|
Kyle McMartin |
159f2cc |
@@ -133,7 +133,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
|
|
Kyle McMartin |
278c1a8 |
return (u32)(unsigned long)uptr;
|
|
Kyle McMartin |
278c1a8 |
}
|
|
Kyle McMartin |
278c1a8 |
|
|
Kyle McMartin |
278c1a8 |
-static inline void __user *compat_alloc_user_space(long len)
|
|
Kyle McMartin |
278c1a8 |
+static inline void __user *arch_compat_alloc_user_space(long len)
|
|
Kyle McMartin |
278c1a8 |
{
|
|
Kyle McMartin |
278c1a8 |
struct pt_regs *regs = current->thread.regs;
|
|
Kyle McMartin |
278c1a8 |
unsigned long usp = regs->gpr[1];
|
|
Kyle McMartin |
278c1a8 |
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
|
|
Kyle McMartin |
159f2cc |
index 01a0802..0c940d3 100644
|
|
Kyle McMartin |
278c1a8 |
--- a/arch/s390/include/asm/compat.h
|
|
Kyle McMartin |
278c1a8 |
+++ b/arch/s390/include/asm/compat.h
|
|
Kyle McMartin |
159f2cc |
@@ -180,7 +180,7 @@ static inline int is_compat_task(void)
|
|
Kyle McMartin |
278c1a8 |
|
|
Kyle McMartin |
278c1a8 |
#endif
|
|
Kyle McMartin |
278c1a8 |
|
|
Kyle McMartin |
278c1a8 |
-static inline void __user *compat_alloc_user_space(long len)
|
|
Kyle McMartin |
278c1a8 |
+static inline void __user *arch_compat_alloc_user_space(long len)
|
|
Kyle McMartin |
278c1a8 |
{
|
|
Kyle McMartin |
278c1a8 |
unsigned long stack;
|
|
Kyle McMartin |
278c1a8 |
|
|
Kyle McMartin |
278c1a8 |
diff --git a/arch/sparc/include/asm/compat.h b/arch/sparc/include/asm/compat.h
|
|
Kyle McMartin |
159f2cc |
index 0e70625..612bb38 100644
|
|
Kyle McMartin |
278c1a8 |
--- a/arch/sparc/include/asm/compat.h
|
|
Kyle McMartin |
278c1a8 |
+++ b/arch/sparc/include/asm/compat.h
|
|
Kyle McMartin |
159f2cc |
@@ -166,7 +166,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
|
|
Kyle McMartin |
278c1a8 |
return (u32)(unsigned long)uptr;
|
|
Kyle McMartin |
278c1a8 |
}
|
|
Kyle McMartin |
278c1a8 |
|
|
Kyle McMartin |
278c1a8 |
-static inline void __user *compat_alloc_user_space(long len)
|
|
Kyle McMartin |
278c1a8 |
+static inline void __user *arch_compat_alloc_user_space(long len)
|
|
Kyle McMartin |
278c1a8 |
{
|
|
Kyle McMartin |
278c1a8 |
struct pt_regs *regs = current_thread_info()->kregs;
|
|
Kyle McMartin |
278c1a8 |
unsigned long usp = regs->u_regs[UREG_I6];
|
|
Kyle McMartin |
278c1a8 |
diff --git a/arch/x86/include/asm/compat.h b/arch/x86/include/asm/compat.h
|
|
Kyle McMartin |
159f2cc |
index 9a9c7bd..c8c9a74 100644
|
|
Kyle McMartin |
278c1a8 |
--- a/arch/x86/include/asm/compat.h
|
|
Kyle McMartin |
278c1a8 |
+++ b/arch/x86/include/asm/compat.h
|
|
Kyle McMartin |
159f2cc |
@@ -204,7 +204,7 @@ static inline compat_uptr_t ptr_to_compat(void __user *uptr)
|
|
Kyle McMartin |
278c1a8 |
return (u32)(unsigned long)uptr;
|
|
Kyle McMartin |
278c1a8 |
}
|
|
Kyle McMartin |
278c1a8 |
|
|
Kyle McMartin |
278c1a8 |
-static inline void __user *compat_alloc_user_space(long len)
|
|
Kyle McMartin |
278c1a8 |
+static inline void __user *arch_compat_alloc_user_space(long len)
|
|
Kyle McMartin |
278c1a8 |
{
|
|
Kyle McMartin |
278c1a8 |
struct pt_regs *regs = task_pt_regs(current);
|
|
Kyle McMartin |
278c1a8 |
return (void __user *)regs->sp - len;
|
|
Kyle McMartin |
278c1a8 |
diff --git a/include/linux/compat.h b/include/linux/compat.h
|
|
Kyle McMartin |
159f2cc |
index af931ee..cab23f2 100644
|
|
Kyle McMartin |
278c1a8 |
--- a/include/linux/compat.h
|
|
Kyle McMartin |
278c1a8 |
+++ b/include/linux/compat.h
|
|
Kyle McMartin |
159f2cc |
@@ -309,5 +309,7 @@ asmlinkage long compat_sys_newfstatat(unsigned int dfd, char __user * filename,
|
|
Kyle McMartin |
159f2cc |
asmlinkage long compat_sys_openat(unsigned int dfd, const char __user *filename,
|
|
Kyle McMartin |
159f2cc |
int flags, int mode);
|
|
Kyle McMartin |
159f2cc |
|
|
Kyle McMartin |
278c1a8 |
+extern void __user *compat_alloc_user_space(unsigned long len);
|
|
Kyle McMartin |
278c1a8 |
+
|
|
Kyle McMartin |
278c1a8 |
#endif /* CONFIG_COMPAT */
|
|
Kyle McMartin |
278c1a8 |
#endif /* _LINUX_COMPAT_H */
|
|
Kyle McMartin |
278c1a8 |
diff --git a/kernel/compat.c b/kernel/compat.c
|
|
Kyle McMartin |
159f2cc |
index 180d188..61112e5 100644
|
|
Kyle McMartin |
278c1a8 |
--- a/kernel/compat.c
|
|
Kyle McMartin |
278c1a8 |
+++ b/kernel/compat.c
|
|
Kyle McMartin |
159f2cc |
@@ -1136,3 +1136,24 @@ compat_sys_sysinfo(struct compat_sysinfo __user *info)
|
|
Kyle McMartin |
278c1a8 |
|
|
Kyle McMartin |
278c1a8 |
return 0;
|
|
Kyle McMartin |
278c1a8 |
}
|
|
Kyle McMartin |
278c1a8 |
+
|
|
Kyle McMartin |
278c1a8 |
+/*
|
|
Kyle McMartin |
278c1a8 |
+ * Allocate user-space memory for the duration of a single system call,
|
|
Kyle McMartin |
278c1a8 |
+ * in order to marshall parameters inside a compat thunk.
|
|
Kyle McMartin |
278c1a8 |
+ */
|
|
Kyle McMartin |
278c1a8 |
+void __user *compat_alloc_user_space(unsigned long len)
|
|
Kyle McMartin |
278c1a8 |
+{
|
|
Kyle McMartin |
278c1a8 |
+ void __user *ptr;
|
|
Kyle McMartin |
278c1a8 |
+
|
|
Kyle McMartin |
278c1a8 |
+ /* If len would occupy more than half of the entire compat space... */
|
|
Kyle McMartin |
278c1a8 |
+ if (unlikely(len > (((compat_uptr_t)~0) >> 1)))
|
|
Kyle McMartin |
278c1a8 |
+ return NULL;
|
|
Kyle McMartin |
278c1a8 |
+
|
|
Kyle McMartin |
278c1a8 |
+ ptr = arch_compat_alloc_user_space(len);
|
|
Kyle McMartin |
278c1a8 |
+
|
|
Kyle McMartin |
278c1a8 |
+ if (unlikely(!access_ok(VERIFY_WRITE, ptr, len)))
|
|
Kyle McMartin |
278c1a8 |
+ return NULL;
|
|
Kyle McMartin |
278c1a8 |
+
|
|
Kyle McMartin |
278c1a8 |
+ return ptr;
|
|
Kyle McMartin |
278c1a8 |
+}
|
|
Kyle McMartin |
278c1a8 |
+EXPORT_SYMBOL_GPL(compat_alloc_user_space);
|
|
Kyle McMartin |
278c1a8 |
--
|
|
Kyle McMartin |
278c1a8 |
1.7.2.3
|
|
Kyle McMartin |
278c1a8 |
|