Commit 81409e9e authored by Kees Cook's avatar Kees Cook

usercopy: fold builtin_const check into inline function

Instead of having each caller of check_object_size() need to remember to
check for a const size parameter, move the check into check_object_size()
itself. This actually matches the original implementation in PaX, though
this commit cleans up the now-redundant builtin_const() calls in the
various architectures.
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
parent e6971009
...@@ -241,8 +241,7 @@ extern unsigned long __must_check __copy_user (void __user *to, const void __use ...@@ -241,8 +241,7 @@ extern unsigned long __must_check __copy_user (void __user *to, const void __use
static inline unsigned long static inline unsigned long
__copy_to_user (void __user *to, const void *from, unsigned long count) __copy_to_user (void __user *to, const void *from, unsigned long count)
{ {
if (!__builtin_constant_p(count)) check_object_size(from, count, true);
check_object_size(from, count, true);
return __copy_user(to, (__force void __user *) from, count); return __copy_user(to, (__force void __user *) from, count);
} }
...@@ -250,8 +249,7 @@ __copy_to_user (void __user *to, const void *from, unsigned long count) ...@@ -250,8 +249,7 @@ __copy_to_user (void __user *to, const void *from, unsigned long count)
static inline unsigned long static inline unsigned long
__copy_from_user (void *to, const void __user *from, unsigned long count) __copy_from_user (void *to, const void __user *from, unsigned long count)
{ {
if (!__builtin_constant_p(count)) check_object_size(to, count, false);
check_object_size(to, count, false);
return __copy_user((__force void __user *) to, from, count); return __copy_user((__force void __user *) to, from, count);
} }
...@@ -265,8 +263,7 @@ __copy_from_user (void *to, const void __user *from, unsigned long count) ...@@ -265,8 +263,7 @@ __copy_from_user (void *to, const void __user *from, unsigned long count)
long __cu_len = (n); \ long __cu_len = (n); \
\ \
if (__access_ok(__cu_to, __cu_len, get_fs())) { \ if (__access_ok(__cu_to, __cu_len, get_fs())) { \
if (!__builtin_constant_p(n)) \ check_object_size(__cu_from, __cu_len, true); \
check_object_size(__cu_from, __cu_len, true); \
__cu_len = __copy_user(__cu_to, (__force void __user *) __cu_from, __cu_len); \ __cu_len = __copy_user(__cu_to, (__force void __user *) __cu_from, __cu_len); \
} \ } \
__cu_len; \ __cu_len; \
...@@ -280,8 +277,7 @@ __copy_from_user (void *to, const void __user *from, unsigned long count) ...@@ -280,8 +277,7 @@ __copy_from_user (void *to, const void __user *from, unsigned long count)
\ \
__chk_user_ptr(__cu_from); \ __chk_user_ptr(__cu_from); \
if (__access_ok(__cu_from, __cu_len, get_fs())) { \ if (__access_ok(__cu_from, __cu_len, get_fs())) { \
if (!__builtin_constant_p(n)) \ check_object_size(__cu_to, __cu_len, false); \
check_object_size(__cu_to, __cu_len, false); \
__cu_len = __copy_user((__force void __user *) __cu_to, __cu_from, __cu_len); \ __cu_len = __copy_user((__force void __user *) __cu_to, __cu_from, __cu_len); \
} \ } \
__cu_len; \ __cu_len; \
......
...@@ -311,14 +311,12 @@ static inline unsigned long copy_from_user(void *to, ...@@ -311,14 +311,12 @@ static inline unsigned long copy_from_user(void *to,
unsigned long over; unsigned long over;
if (access_ok(VERIFY_READ, from, n)) { if (access_ok(VERIFY_READ, from, n)) {
if (!__builtin_constant_p(n)) check_object_size(to, n, false);
check_object_size(to, n, false);
return __copy_tofrom_user((__force void __user *)to, from, n); return __copy_tofrom_user((__force void __user *)to, from, n);
} }
if ((unsigned long)from < TASK_SIZE) { if ((unsigned long)from < TASK_SIZE) {
over = (unsigned long)from + n - TASK_SIZE; over = (unsigned long)from + n - TASK_SIZE;
if (!__builtin_constant_p(n - over)) check_object_size(to, n - over, false);
check_object_size(to, n - over, false);
return __copy_tofrom_user((__force void __user *)to, from, return __copy_tofrom_user((__force void __user *)to, from,
n - over) + over; n - over) + over;
} }
...@@ -331,14 +329,12 @@ static inline unsigned long copy_to_user(void __user *to, ...@@ -331,14 +329,12 @@ static inline unsigned long copy_to_user(void __user *to,
unsigned long over; unsigned long over;
if (access_ok(VERIFY_WRITE, to, n)) { if (access_ok(VERIFY_WRITE, to, n)) {
if (!__builtin_constant_p(n)) check_object_size(from, n, true);
check_object_size(from, n, true);
return __copy_tofrom_user(to, (__force void __user *)from, n); return __copy_tofrom_user(to, (__force void __user *)from, n);
} }
if ((unsigned long)to < TASK_SIZE) { if ((unsigned long)to < TASK_SIZE) {
over = (unsigned long)to + n - TASK_SIZE; over = (unsigned long)to + n - TASK_SIZE;
if (!__builtin_constant_p(n)) check_object_size(from, n - over, true);
check_object_size(from, n - over, true);
return __copy_tofrom_user(to, (__force void __user *)from, return __copy_tofrom_user(to, (__force void __user *)from,
n - over) + over; n - over) + over;
} }
...@@ -383,8 +379,7 @@ static inline unsigned long __copy_from_user_inatomic(void *to, ...@@ -383,8 +379,7 @@ static inline unsigned long __copy_from_user_inatomic(void *to,
return 0; return 0;
} }
if (!__builtin_constant_p(n)) check_object_size(to, n, false);
check_object_size(to, n, false);
return __copy_tofrom_user((__force void __user *)to, from, n); return __copy_tofrom_user((__force void __user *)to, from, n);
} }
...@@ -412,8 +407,8 @@ static inline unsigned long __copy_to_user_inatomic(void __user *to, ...@@ -412,8 +407,8 @@ static inline unsigned long __copy_to_user_inatomic(void __user *to,
if (ret == 0) if (ret == 0)
return 0; return 0;
} }
if (!__builtin_constant_p(n))
check_object_size(from, n, true); check_object_size(from, n, true);
return __copy_tofrom_user(to, (__force const void __user *)from, n); return __copy_tofrom_user(to, (__force const void __user *)from, n);
} }
......
...@@ -249,8 +249,7 @@ unsigned long __copy_user(void __user *to, const void __user *from, unsigned lon ...@@ -249,8 +249,7 @@ unsigned long __copy_user(void __user *to, const void __user *from, unsigned lon
static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n) static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
{ {
if (n && __access_ok((unsigned long) to, n)) { if (n && __access_ok((unsigned long) to, n)) {
if (!__builtin_constant_p(n)) check_object_size(from, n, true);
check_object_size(from, n, true);
return __copy_user(to, (__force void __user *) from, n); return __copy_user(to, (__force void __user *) from, n);
} else } else
return n; return n;
...@@ -258,16 +257,14 @@ static inline unsigned long copy_to_user(void __user *to, const void *from, unsi ...@@ -258,16 +257,14 @@ static inline unsigned long copy_to_user(void __user *to, const void *from, unsi
static inline unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n) static inline unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n)
{ {
if (!__builtin_constant_p(n)) check_object_size(from, n, true);
check_object_size(from, n, true);
return __copy_user(to, (__force void __user *) from, n); return __copy_user(to, (__force void __user *) from, n);
} }
static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n)
{ {
if (n && __access_ok((unsigned long) from, n)) { if (n && __access_ok((unsigned long) from, n)) {
if (!__builtin_constant_p(n)) check_object_size(to, n, false);
check_object_size(to, n, false);
return __copy_user((__force void __user *) to, from, n); return __copy_user((__force void __user *) to, from, n);
} else } else
return n; return n;
......
...@@ -212,8 +212,7 @@ copy_from_user(void *to, const void __user *from, unsigned long size) ...@@ -212,8 +212,7 @@ copy_from_user(void *to, const void __user *from, unsigned long size)
{ {
unsigned long ret; unsigned long ret;
if (!__builtin_constant_p(size)) check_object_size(to, size, false);
check_object_size(to, size, false);
ret = ___copy_from_user(to, from, size); ret = ___copy_from_user(to, from, size);
if (unlikely(ret)) if (unlikely(ret))
...@@ -233,8 +232,8 @@ copy_to_user(void __user *to, const void *from, unsigned long size) ...@@ -233,8 +232,8 @@ copy_to_user(void __user *to, const void *from, unsigned long size)
{ {
unsigned long ret; unsigned long ret;
if (!__builtin_constant_p(size)) check_object_size(from, size, true);
check_object_size(from, size, true);
ret = ___copy_to_user(to, from, size); ret = ___copy_to_user(to, from, size);
if (unlikely(ret)) if (unlikely(ret))
ret = copy_to_user_fixup(to, from, size); ret = copy_to_user_fixup(to, from, size);
......
...@@ -121,7 +121,8 @@ extern void __check_object_size(const void *ptr, unsigned long n, ...@@ -121,7 +121,8 @@ extern void __check_object_size(const void *ptr, unsigned long n,
static inline void check_object_size(const void *ptr, unsigned long n, static inline void check_object_size(const void *ptr, unsigned long n,
bool to_user) bool to_user)
{ {
__check_object_size(ptr, n, to_user); if (!__builtin_constant_p(n))
__check_object_size(ptr, n, to_user);
} }
#else #else
static inline void check_object_size(const void *ptr, unsigned long n, static inline void check_object_size(const void *ptr, unsigned long n,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment