Skip to content

Commit 8044aad

Browse files
author
Greg Ungerer
committed
m68knommu: fix memcpy() out of bounds warning in get_user()
Newer versions of gcc are giving warnings in the non-MMU m68k version of the get_user() macro: ./arch/m68k/include/asm/string.h:72:25: warning: ‘__builtin_memcpy’ forming offset [3, 4] is out of the bounds [0, 2] of object ‘__gu_val’ with type ‘short unsigned int’ [-Warray-bounds] The warnings are generated when smaller sized variables are used as the result of user space pointers to larger values. For example a short/2-byte variable stores the result of a user space int (4-byte) pointer. The warning is in the 8-byte branch of get_user() - even though that branch is not the taken branch in the warning cases. Refactor the 8-byte branch of get_user() so that it uses a correctly formed union type to read and write the source and destination objects. Keep using the memcpy() just in case the user space pointer is not naturaly aligned (not required for ColdFire, but needed for early 68000). Signed-off-by: Greg Ungerer <[email protected]>
1 parent d5fae24 commit 8044aad

File tree

1 file changed

+11
-8
lines changed

1 file changed

+11
-8
lines changed

arch/m68k/include/asm/uaccess_no.h

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -71,26 +71,29 @@ extern int __put_user_bad(void);
7171
#define get_user(x, ptr) \
7272
({ \
7373
int __gu_err = 0; \
74-
typeof(x) __gu_val = 0; \
7574
switch (sizeof(*(ptr))) { \
7675
case 1: \
77-
__get_user_asm(__gu_err, __gu_val, ptr, b, "=d"); \
76+
__get_user_asm(__gu_err, x, ptr, b, "=d"); \
7877
break; \
7978
case 2: \
80-
__get_user_asm(__gu_err, __gu_val, ptr, w, "=r"); \
79+
__get_user_asm(__gu_err, x, ptr, w, "=r"); \
8180
break; \
8281
case 4: \
83-
__get_user_asm(__gu_err, __gu_val, ptr, l, "=r"); \
82+
__get_user_asm(__gu_err, x, ptr, l, "=r"); \
8483
break; \
85-
case 8: \
86-
memcpy((void *) &__gu_val, ptr, sizeof (*(ptr))); \
84+
case 8: { \
85+
union { \
86+
u64 l; \
87+
__typeof__(*(ptr)) t; \
88+
} __gu_val; \
89+
memcpy(&__gu_val.l, ptr, sizeof(__gu_val.l)); \
90+
(x) = __gu_val.t; \
8791
break; \
92+
} \
8893
default: \
89-
__gu_val = 0; \
9094
__gu_err = __get_user_bad(); \
9195
break; \
9296
} \
93-
(x) = (typeof(*(ptr))) __gu_val; \
9497
__gu_err; \
9598
})
9699
#define __get_user(x, ptr) get_user(x, ptr)

0 commit comments

Comments
 (0)