lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:	Sun, 14 Jun 2009 02:00:01 -0400
From:	Mike Frysinger <vapier@...too.org>
To:	Arnd Bergmann <arnd@...db.de>
Cc:	linux-kernel@...r.kernel.org
Subject: [PATCH 1/4] asm-generic: uaccess: do not expand args multiple times

While it's debatable whether {get,put}_user() should be called with
arguments that have side effects, macro's should be written safely in the
first place.  In this case, a slightly off version of put_user() ended up
causing random userspace corruption and these things aren't trivial to
track down.

While some of these conversions aren't strictly necessary, I think it's
better to do all of them so as to be proactive in people accidently
screwing it up in the future.

Signed-off-by: Mike Frysinger <vapier@...too.org>
---
 include/asm-generic/uaccess.h |   49 ++++++++++++++++++++++------------------
 1 files changed, 27 insertions(+), 22 deletions(-)

diff --git a/include/asm-generic/uaccess.h b/include/asm-generic/uaccess.h
index 6d8cab2..cf3cb73 100644
--- a/include/asm-generic/uaccess.h
+++ b/include/asm-generic/uaccess.h
@@ -143,15 +143,16 @@ static inline __must_check long __copy_to_user(void __user *to,
 #define __put_user(x, ptr) \
 ({								\
 	__typeof__(*(ptr)) __x = (x);				\
+	__typeof__(*(ptr)) *__p = (ptr);			\
 	int __pu_err = -EFAULT;					\
-        __chk_user_ptr(ptr);                                    \
-	switch (sizeof (*(ptr))) {				\
+	__chk_user_ptr(__p);					\
+	switch (sizeof(*__p)) {					\
 	case 1:							\
 	case 2:							\
 	case 4:							\
 	case 8:							\
-		__pu_err = __put_user_fn(sizeof (*(ptr)),	\
-					 ptr, &__x);		\
+		__pu_err = __put_user_fn(sizeof(*__p),		\
+					 __p, &__x);		\
 		break;						\
 	default:						\
 		__put_user_bad();				\
@@ -162,9 +163,11 @@ static inline __must_check long __copy_to_user(void __user *to,
 
 #define put_user(x, ptr)					\
 ({								\
+	__typeof__(*(ptr)) _x = (x);				\
+	__typeof__(*(ptr)) *_p = (ptr);				\
 	might_sleep();						\
-	__access_ok(ptr, sizeof (*ptr)) ?			\
-		__put_user(x, ptr) :				\
+	__access_ok(_p, sizeof(*_p)) ?				\
+		__put_user(_x, _p) :				\
 		-EFAULT;					\
 })
 
@@ -178,35 +181,36 @@ extern int __put_user_bad(void) __attribute__((noreturn));
 
 #define __get_user(x, ptr)					\
 ({								\
+	__typeof__(*(ptr)) *__p = (ptr);			\
 	int __gu_err = -EFAULT;					\
-	__chk_user_ptr(ptr);					\
-	switch (sizeof(*(ptr))) {				\
+	__chk_user_ptr(__p);					\
+	switch (sizeof(*__p)) {					\
 	case 1: {						\
 		unsigned char __x;				\
-		__gu_err = __get_user_fn(sizeof (*(ptr)),	\
-					 ptr, &__x);		\
-		(x) = *(__force __typeof__(*(ptr)) *) &__x;	\
+		__gu_err = __get_user_fn(sizeof(*__p),		\
+					 __p, &__x);		\
+		(x) = *(__force __typeof__(*__p) *) &__x;	\
 		break;						\
 	};							\
 	case 2: {						\
 		unsigned short __x;				\
-		__gu_err = __get_user_fn(sizeof (*(ptr)),	\
-					 ptr, &__x);		\
-		(x) = *(__force __typeof__(*(ptr)) *) &__x;	\
+		__gu_err = __get_user_fn(sizeof(*__p),		\
+					 __p, &__x);		\
+		(x) = *(__force __typeof__(*__p) *) &__x;	\
 		break;						\
 	};							\
 	case 4: {						\
 		unsigned int __x;				\
-		__gu_err = __get_user_fn(sizeof (*(ptr)),	\
-					 ptr, &__x);		\
-		(x) = *(__force __typeof__(*(ptr)) *) &__x;	\
+		__gu_err = __get_user_fn(sizeof(*__p),		\
+					 __p, &__x);		\
+		(x) = *(__force __typeof__(*__p) *) &__x;	\
 		break;						\
 	};							\
 	case 8: {						\
 		unsigned long long __x;				\
-		__gu_err = __get_user_fn(sizeof (*(ptr)),	\
-					 ptr, &__x);		\
-		(x) = *(__force __typeof__(*(ptr)) *) &__x;	\
+		__gu_err = __get_user_fn(sizeof(*__p),		\
+					 __p, &__x);		\
+		(x) = *(__force __typeof__(*__p) *) &__x;	\
 		break;						\
 	};							\
 	default:						\
@@ -218,9 +222,10 @@ extern int __put_user_bad(void) __attribute__((noreturn));
 
 #define get_user(x, ptr)					\
 ({								\
+	__typeof__(*(ptr)) *_p = (ptr);				\
 	might_sleep();						\
-	__access_ok(ptr, sizeof (*ptr)) ?			\
-		__get_user(x, ptr) :				\
+	__access_ok(_p, sizeof(*_p)) ?				\
+		__get_user(x, _p) :				\
 		-EFAULT;					\
 })
 
-- 
1.6.3.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ