History

Merge branch 'work.uaccess-unaligned' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull uacess-unaligned removal from Al Viro: "That stuff had just one user, and an exotic one, at that - binfmt_flat on arm and m68k" * 'work.uaccess-unaligned' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs: kill {__,}{get,put}_user_unaligned() binfmt_flat: flat_{get,put}_addr_from_rp() should be able to fail

Linus Torvalds committed 9 years ago

Commit 89cbec72 parents 2173bd0 3170d8d24 files · +168 −450Browse files

Unified · Split

24 files
  1. arch/arm/include/asm/flat.h +22 −3
  2. arch/arm/include/asm/uaccess.h +0 −7
  3. arch/arm64/include/asm/uaccess.h +0 −4
  4. arch/blackfin/include/asm/flat.h +15 −10
  5. arch/blackfin/kernel/flat.c +6 −7
  6. arch/c6x/include/asm/flat.h +13 −2
  7. arch/h8300/include/asm/flat.h +18 −6
  8. arch/ia64/include/asm/uaccess.h +0 −36
  9. arch/m32r/include/asm/flat.h +8 −11
  10. arch/m68k/include/asm/flat.h +20 −3
  11. arch/m68k/include/asm/uaccess.h +0 −7
  12. arch/microblaze/include/asm/flat.h +17 −17
  13. arch/mips/include/asm/uaccess.h +0 −277
  14. arch/parisc/include/asm/uaccess.h +0 −1
  15. arch/powerpc/include/asm/uaccess.h +0 −3
  16. arch/s390/include/asm/uaccess.h +0 −3
  17. arch/sh/include/asm/flat.h +13 −2
  18. arch/sparc/include/asm/uaccess_64.h +0 −1
  19. arch/tile/include/asm/uaccess.h +0 −1
  20. arch/x86/include/asm/uaccess.h +0 −3
  21. arch/xtensa/include/asm/flat.h +13 −2
  22. fs/binfmt_flat.c +22 −17
  23. include/asm-generic/uaccess-unaligned.h +0 −26
  24. include/linux/flat.h +1 −1
arch/arm/include/asm/flat.h+22−3
@@ -5,12 +5,31 @@ · 4 unmodified lines
55 #ifndef __ARM_FLAT_H__
66 #define __ARM_FLAT_H__
77
8+#include <linux/uaccess.h>
9+
810 #define flat_argvp_envp_on_stack() 1
911 #define flat_old_ram_flag(flags) (flags)
1012 #define flat_reloc_valid(reloc, size) ((reloc) <= (size))
11−#define flat_get_addr_from_rp(rp, relval, flags, persistent) \
12− ({ unsigned long __val; __get_user_unaligned(__val, rp); __val; })
13−#define flat_put_addr_at_rp(rp, val, relval) __put_user_unaligned(val, rp)
13+
14+static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
15+ u32 *addr, u32 *persistent)
16+{
17+#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
18+ return copy_from_user(addr, rp, 4) ? -EFAULT : 0;
19+#else
20+ return get_user(*addr, rp);
21+#endif
22+}
23+
24+static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel)
25+{
26+#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
27+ return copy_to_user(rp, &addr, 4) ? -EFAULT : 0;
28+#else
29+ return put_user(addr, rp);
30+#endif
31+}
32+
1433 #define flat_get_relocate_addr(rel) (rel)
1534 #define flat_set_persistent(relval, p) 0
1635
arch/arm/include/asm/uaccess.h+0−7
@@ -17,13 +17,6 @@ · 16 unmodified lines
1717 #include <asm/unified.h>
1818 #include <asm/compiler.h>
1919
20−#ifndef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
21−#include <asm-generic/uaccess-unaligned.h>
22−#else
23−#define __get_user_unaligned __get_user
24−#define __put_user_unaligned __put_user
25−#endif
26−
2720 #include <asm/extable.h>
2821
2922 /*
arch/arm64/include/asm/uaccess.h+0−4
@@ -254,8 +254,6 @@ do { \ · 253 unmodified lines
254254 (void)0; \
255255 })
256256
257−#define __get_user_unaligned __get_user
258−
259257 #define get_user(x, ptr) \
260258 ({ \
261259 __typeof__(*(ptr)) __user *__p = (ptr); \
@@ -320,8 +318,6 @@ do { \ · 58 unmodified lines
320318 (void)0; \
321319 })
322320
323−#define __put_user_unaligned __put_user
324−
325321 #define put_user(x, ptr) \
326322 ({ \
327323 __typeof__(*(ptr)) __user *__p = (ptr); \
arch/blackfin/include/asm/flat.h+15−10
@@ -14,23 +14,28 @@ · 13 unmodified lines
1414 #define flat_argvp_envp_on_stack() 0
1515 #define flat_old_ram_flag(flags) (flags)
1616
17−extern unsigned long bfin_get_addr_from_rp (unsigned long *ptr,
18− unsigned long relval,
19− unsigned long flags,
20− unsigned long *persistent);
17+extern unsigned long bfin_get_addr_from_rp (u32 *ptr, u32 relval,
18+ u32 flags, u32 *persistent);
2119
22−extern void bfin_put_addr_at_rp(unsigned long *ptr, unsigned long addr,
23− unsigned long relval);
20+extern void bfin_put_addr_at_rp(u32 *ptr, u32 addr, u32 relval);
2421
2522 /* The amount by which a relocation can exceed the program image limits
2623 without being regarded as an error. */
2724
2825 #define flat_reloc_valid(reloc, size) ((reloc) <= (size))
2926
30−#define flat_get_addr_from_rp(rp, relval, flags, persistent) \
31− bfin_get_addr_from_rp(rp, relval, flags, persistent)
32−#define flat_put_addr_at_rp(rp, val, relval) \
33− bfin_put_addr_at_rp(rp, val, relval)
27+static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
28+ u32 *addr, u32 *persistent)
29+{
30+ *addr = bfin_get_addr_from_rp(rp, relval, flags, persistent);
31+ return 0;
32+}
33+
34+static inline int flat_put_addr_at_rp(u32 __user *rp, u32 val, u32 relval)
35+{
36+ bfin_put_addr_at_rp(rp, val, relval);
37+ return 0;
38+}
3439
3540 /* Convert a relocation entry into an address. */
3641 static inline unsigned long
arch/blackfin/kernel/flat.c+6−7
@@ -13,14 +13,14 @@ · 12 unmodified lines
1313 #define FLAT_BFIN_RELOC_TYPE_16H_BIT 1
1414 #define FLAT_BFIN_RELOC_TYPE_32_BIT 2
1515
16−unsigned long bfin_get_addr_from_rp(unsigned long *ptr,
17− unsigned long relval,
18− unsigned long flags,
19− unsigned long *persistent)
16+unsigned long bfin_get_addr_from_rp(u32 *ptr,
17+ u32 relval,
18+ u32 flags,
19+ u32 *persistent)
2020 {
2121 unsigned short *usptr = (unsigned short *)ptr;
2222 int type = (relval >> 26) & 7;
23− unsigned long val;
23+ u32 val;
2424
2525 switch (type) {
2626 case FLAT_BFIN_RELOC_TYPE_16_BIT:
@@ -59,8 +59,7 @@ EXPORT_SYMBOL(bfin_get_addr_from_rp); · 32 unmodified lines
5959 * Insert the address ADDR into the symbol reference at RP;
6060 * RELVAL is the raw relocation-table entry from which RP is derived
6161 */
62−void bfin_put_addr_at_rp(unsigned long *ptr, unsigned long addr,
63− unsigned long relval)
62+void bfin_put_addr_at_rp(u32 *ptr, u32 addr, u32 relval)
6463 {
6564 unsigned short *usptr = (unsigned short *)ptr;
6665 int type = (relval >> 26) & 7;
arch/c6x/include/asm/flat.h+13−2
@@ -1,11 +1,22 @@
11 #ifndef __ASM_C6X_FLAT_H
22 #define __ASM_C6X_FLAT_H
33
4+#include <asm/unaligned.h>
5+
46 #define flat_argvp_envp_on_stack() 0
57 #define flat_old_ram_flag(flags) (flags)
68 #define flat_reloc_valid(reloc, size) ((reloc) <= (size))
7−#define flat_get_addr_from_rp(rp, relval, flags, p) get_unaligned(rp)
8−#define flat_put_addr_at_rp(rp, val, relval) put_unaligned(val, rp)
9+static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
10+ u32 *addr, u32 *persistent)
11+{
12+ *addr = get_unaligned((__force u32 *)rp);
13+ return 0;
14+}
15+static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel)
16+{
17+ put_unaligned(addr, (__force u32 *)rp);
18+ return 0;
19+}
920 #define flat_get_relocate_addr(rel) (rel)
1021 #define flat_set_persistent(relval, p) 0
1122
arch/h8300/include/asm/flat.h+18−6
@@ -5,6 +5,8 @@ · 4 unmodified lines
55 #ifndef __H8300_FLAT_H__
66 #define __H8300_FLAT_H__
77
8+#include <asm/unaligned.h>
9+
810 #define flat_argvp_envp_on_stack() 1
911 #define flat_old_ram_flag(flags) 1
1012 #define flat_reloc_valid(reloc, size) ((reloc) <= (size))
@@ -18,11 +20,21 @@ · 7 unmodified lines
1820 */
1921
2022 #define flat_get_relocate_addr(rel) (rel & ~0x00000001)
21−#define flat_get_addr_from_rp(rp, relval, flags, persistent) \
22− ({(void)persistent; \
23− get_unaligned(rp) & (((flags) & FLAT_FLAG_GOTPIC) ? \
24− 0xffffffff : 0x00ffffff); })
25−#define flat_put_addr_at_rp(rp, addr, rel) \
26− put_unaligned(((*(char *)(rp)) << 24) | ((addr) & 0x00ffffff), (rp))
23+static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
24+ u32 *addr, u32 *persistent)
25+{
26+ u32 val = get_unaligned((__force u32 *)rp);
27+ if (!(flags & FLAT_FLAG_GOTPIC)
28+ val &= 0x00ffffff;
29+ *addr = val;
30+ return 0;
31+}
32+
33+static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel)
34+{
35+ u32 *p = (__force u32 *)rp;
36+ put_unaligned((addr & 0x00ffffff) | (*(char *)p << 24), p);
37+ return 0;
38+}
2739
2840 #endif /* __H8300_FLAT_H__ */
arch/ia64/include/asm/uaccess.h+0−36
@@ -87,42 +87,6 @@ static inline int __access_ok(const void __user *p, unsigned long size) · 86 unmodified lines
8787 #define __put_user(x, ptr) __put_user_nocheck((__typeof__(*(ptr))) (x), (ptr), sizeof(*(ptr)))
8888 #define __get_user(x, ptr) __get_user_nocheck((x), (ptr), sizeof(*(ptr)))
8989
90−extern long __put_user_unaligned_unknown (void);
91−
92−#define __put_user_unaligned(x, ptr) \
93−({ \
94− long __ret; \
95− switch (sizeof(*(ptr))) { \
96− case 1: __ret = __put_user((x), (ptr)); break; \
97− case 2: __ret = (__put_user((x), (u8 __user *)(ptr))) \
98− | (__put_user((x) >> 8, ((u8 __user *)(ptr) + 1))); break; \
99− case 4: __ret = (__put_user((x), (u16 __user *)(ptr))) \
100− | (__put_user((x) >> 16, ((u16 __user *)(ptr) + 1))); break; \
101− case 8: __ret = (__put_user((x), (u32 __user *)(ptr))) \
102− | (__put_user((x) >> 32, ((u32 __user *)(ptr) + 1))); break; \
103− default: __ret = __put_user_unaligned_unknown(); \
104− } \
105− __ret; \
106−})
107−
108−extern long __get_user_unaligned_unknown (void);
109−
110−#define __get_user_unaligned(x, ptr) \
111−({ \
112− long __ret; \
113− switch (sizeof(*(ptr))) { \
114− case 1: __ret = __get_user((x), (ptr)); break; \
115− case 2: __ret = (__get_user((x), (u8 __user *)(ptr))) \
116− | (__get_user((x) >> 8, ((u8 __user *)(ptr) + 1))); break; \
117− case 4: __ret = (__get_user((x), (u16 __user *)(ptr))) \
118− | (__get_user((x) >> 16, ((u16 __user *)(ptr) + 1))); break; \
119− case 8: __ret = (__get_user((x), (u32 __user *)(ptr))) \
120− | (__get_user((x) >> 32, ((u32 __user *)(ptr) + 1))); break; \
121− default: __ret = __get_user_unaligned_unknown(); \
122− } \
123− __ret; \
124−})
125−
12690 #ifdef ASM_SUPPORTED
12791 struct __large_struct { unsigned long buf[100]; };
12892 # define __m(x) (*(struct __large_struct __user *)(x))
arch/m32r/include/asm/flat.h+8−11
@@ -17,11 +17,6 @@ · 16 unmodified lines
1717 #define flat_set_persistent(relval, p) 0
1818 #define flat_reloc_valid(reloc, size) \
1919 (((reloc) - textlen_for_m32r_lo16_data) <= (size))
20−#define flat_get_addr_from_rp(rp, relval, flags, persistent) \
21− m32r_flat_get_addr_from_rp(rp, relval, (text_len) )
22−
23−#define flat_put_addr_at_rp(rp, addr, relval) \
24− m32r_flat_put_addr_at_rp(rp, addr, relval)
2520
2621 /* Convert a relocation entry into an address. */
2722 static inline unsigned long
@@ -57,9 +52,9 @@ flat_get_relocate_addr (unsigned long relval) · 29 unmodified lines
5752
5853 static unsigned long textlen_for_m32r_lo16_data = 0;
5954
60−static inline unsigned long m32r_flat_get_addr_from_rp (unsigned long *rp,
61− unsigned long relval,
62− unsigned long textlen)
55+static inline unsigned long m32r_flat_get_addr_from_rp (u32 *rp,
56+ u32 relval,
57+ u32 textlen)
6358 {
6459 unsigned int reloc = flat_m32r_get_reloc_type (relval);
6560 textlen_for_m32r_lo16_data = 0;
@@ -100,9 +95,7 @@ static inline unsigned long m32r_flat_get_addr_from_rp (unsigned long *rp, · 34 unmodified lines
10095 return ~0; /* bogus value */
10196 }
10297
103−static inline void m32r_flat_put_addr_at_rp (unsigned long *rp,
104− unsigned long addr,
105− unsigned long relval)
98+static inline void flat_put_addr_at_rp(u32 *rp, u32 addr, u32 relval)
10699 {
107100 unsigned int reloc = flat_m32r_get_reloc_type (relval);
108101 if (reloc & 0xf0) {
@@ -142,4 +135,8 @@ static inline void m32r_flat_put_addr_at_rp (unsigned long *rp, · 33 unmodified lines
142135 }
143136 }
144137
138+// kludge - text_len is a local variable in the only user.
139+#define flat_get_addr_from_rp(rp, relval, flags, addr, persistent) \
140+ (m32r_flat_get_addr_from_rp(rp, relval, text_len), 0)
141+
145142 #endif /* __ASM_M32R_FLAT_H */
arch/m68k/include/asm/flat.h+20−3
@@ -5,12 +5,29 @@ · 4 unmodified lines
55 #ifndef __M68KNOMMU_FLAT_H__
66 #define __M68KNOMMU_FLAT_H__
77
8+#include <linux/uaccess.h>
9+
810 #define flat_argvp_envp_on_stack() 1
911 #define flat_old_ram_flag(flags) (flags)
1012 #define flat_reloc_valid(reloc, size) ((reloc) <= (size))
11−#define flat_get_addr_from_rp(rp, relval, flags, p) \
12− ({ unsigned long __val; __get_user_unaligned(__val, rp); __val; })
13−#define flat_put_addr_at_rp(rp, val, relval) __put_user_unaligned(val, rp)
13+static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
14+ u32 *addr, u32 *persistent)
15+{
16+#ifdef CONFIG_CPU_HAS_NO_UNALIGNED
17+ return copy_from_user(addr, rp, 4) ? -EFAULT : 0;
18+#else
19+ return get_user(*addr, rp);
20+#endif
21+}
22+
23+static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel)
24+{
25+#ifdef CONFIG_CPU_HAS_NO_UNALIGNED
26+ return copy_to_user(rp, &addr, 4) ? -EFAULT : 0;
27+#else
28+ return put_user(addr, rp);
29+#endif
30+}
1431 #define flat_get_relocate_addr(rel) (rel)
1532
1633 static inline int flat_set_persistent(unsigned long relval,
arch/m68k/include/asm/uaccess.h+0−7
@@ -3,11 +3,4 @@ · 2 unmodified lines
33 #else
44 #include <asm/uaccess_mm.h>
55 #endif
6−
76 #include <asm/extable.h>
8−#ifdef CONFIG_CPU_HAS_NO_UNALIGNED
9−#include <asm-generic/uaccess-unaligned.h>
10−#else
11−#define __get_user_unaligned(x, ptr) __get_user((x), (ptr))
12−#define __put_user_unaligned(x, ptr) __put_user((x), (ptr))
13−#endif
arch/microblaze/include/asm/flat.h+17−17
@@ -32,29 +32,27 @@ · 31 unmodified lines
3232 * reference
3333 */
3434
35−static inline unsigned long
36−flat_get_addr_from_rp(unsigned long *rp, unsigned long relval,
37− unsigned long flags, unsigned long *persistent)
35+static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
36+ u32 *addr, u32 *persistent)
3837 {
39− unsigned long addr;
40− (void)flags;
38+ u32 *p = (__force u32 *)rp;
4139
4240 /* Is it a split 64/32 reference? */
4341 if (relval & 0x80000000) {
4442 /* Grab the two halves of the reference */
45− unsigned long val_hi, val_lo;
43+ u32 val_hi, val_lo;
4644
47− val_hi = get_unaligned(rp);
48− val_lo = get_unaligned(rp+1);
45+ val_hi = get_unaligned(p);
46+ val_lo = get_unaligned(p+1);
4947
5048 /* Crack the address out */
51− addr = ((val_hi & 0xffff) << 16) + (val_lo & 0xffff);
49+ *addr = ((val_hi & 0xffff) << 16) + (val_lo & 0xffff);
5250 } else {
5351 /* Get the address straight out */
54− addr = get_unaligned(rp);
52+ *addr = get_unaligned(p);
5553 }
5654
57− return addr;
55+ return 0;
5856 }
5957
6058 /*
@@ -63,25 +61,27 @@ flat_get_addr_from_rp(unsigned long *rp, unsigned long relval, · 2 unmodified lines
6361 */
6462
6563 static inline void
66−flat_put_addr_at_rp(unsigned long *rp, unsigned long addr, unsigned long relval)
64+flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 relval)
6765 {
66+ u32 *p = (__force u32 *)rp;
6867 /* Is this a split 64/32 reloc? */
6968 if (relval & 0x80000000) {
7069 /* Get the two "halves" */
71− unsigned long val_hi = get_unaligned(rp);
72− unsigned long val_lo = get_unaligned(rp + 1);
70+ unsigned long val_hi = get_unaligned(p);
71+ unsigned long val_lo = get_unaligned(p + 1);
7372
7473 /* insert the address */
7574 val_hi = (val_hi & 0xffff0000) | addr >> 16;
7675 val_lo = (val_lo & 0xffff0000) | (addr & 0xffff);
7776
7877 /* store the two halves back into memory */
79− put_unaligned(val_hi, rp);
80− put_unaligned(val_lo, rp+1);
78+ put_unaligned(val_hi, p);
79+ put_unaligned(val_lo, p+1);
8180 } else {
8281 /* Put it straight in, no messing around */
83− put_unaligned(addr, rp);
82+ put_unaligned(addr, p);
8483 }
84+ return 0;
8585 }
8686
8787 #define flat_get_relocate_addr(rel) (rel & 0x7fffffff)
arch/mips/include/asm/uaccess.h+0−277
@@ -496,283 +496,6 @@ do { \ · 495 unmodified lines
496496
497497 extern void __put_user_unknown(void);
498498
499−/*
500− * ul{b,h,w} are macros and there are no equivalent macros for EVA.
501− * EVA unaligned access is handled in the ADE exception handler.
502− */
503−#ifndef CONFIG_EVA
504−/*
505− * put_user_unaligned: - Write a simple value into user space.
506− * @x: Value to copy to user space.
507− * @ptr: Destination address, in user space.
508− *
509− * Context: User context only. This function may sleep if pagefaults are
510− * enabled.
511− *
512− * This macro copies a single simple value from kernel space to user
513− * space. It supports simple types like char and int, but not larger
514− * data types like structures or arrays.
515− *
516− * @ptr must have pointer-to-simple-variable type, and @x must be assignable
517− * to the result of dereferencing @ptr.
518− *
519− * Returns zero on success, or -EFAULT on error.
520− */
521−#define put_user_unaligned(x,ptr) \
522− __put_user_unaligned_check((x),(ptr),sizeof(*(ptr)))
523−
524−/*
525− * get_user_unaligned: - Get a simple variable from user space.
526− * @x: Variable to store result.
527− * @ptr: Source address, in user space.
528− *
529− * Context: User context only. This function may sleep if pagefaults are
530− * enabled.
531− *
532− * This macro copies a single simple variable from user space to kernel
533− * space. It supports simple types like char and int, but not larger
534− * data types like structures or arrays.
535− *
536− * @ptr must have pointer-to-simple-variable type, and the result of
537− * dereferencing @ptr must be assignable to @x without a cast.
538− *
539− * Returns zero on success, or -EFAULT on error.
540− * On error, the variable @x is set to zero.
541− */
542−#define get_user_unaligned(x,ptr) \
543− __get_user_unaligned_check((x),(ptr),sizeof(*(ptr)))
544−
545−/*
546− * __put_user_unaligned: - Write a simple value into user space, with less checking.
547− * @x: Value to copy to user space.
548− * @ptr: Destination address, in user space.
549− *
550− * Context: User context only. This function may sleep if pagefaults are
551− * enabled.
552− *
553− * This macro copies a single simple value from kernel space to user
554− * space. It supports simple types like char and int, but not larger
555− * data types like structures or arrays.
556− *
557− * @ptr must have pointer-to-simple-variable type, and @x must be assignable
558− * to the result of dereferencing @ptr.
559− *
560− * Caller must check the pointer with access_ok() before calling this
561− * function.
562− *
563− * Returns zero on success, or -EFAULT on error.
564− */
565−#define __put_user_unaligned(x,ptr) \
566− __put_user_unaligned_nocheck((x),(ptr),sizeof(*(ptr)))
567−
568−/*
569− * __get_user_unaligned: - Get a simple variable from user space, with less checking.
570− * @x: Variable to store result.
571− * @ptr: Source address, in user space.
572− *
573− * Context: User context only. This function may sleep if pagefaults are
574− * enabled.
575− *
576− * This macro copies a single simple variable from user space to kernel
577− * space. It supports simple types like char and int, but not larger
578− * data types like structures or arrays.
579− *
580− * @ptr must have pointer-to-simple-variable type, and the result of
581− * dereferencing @ptr must be assignable to @x without a cast.
582− *
583− * Caller must check the pointer with access_ok() before calling this
584− * function.
585− *
586− * Returns zero on success, or -EFAULT on error.
587− * On error, the variable @x is set to zero.
588− */
589−#define __get_user_unaligned(x,ptr) \
590− __get_user_unaligned_nocheck((x),(ptr),sizeof(*(ptr)))
591−
592−/*
593− * Yuck. We need two variants, one for 64bit operation and one
594− * for 32 bit mode and old iron.
595− */
596−#ifdef CONFIG_32BIT
597−#define __GET_USER_UNALIGNED_DW(val, ptr) \
598− __get_user_unaligned_asm_ll32(val, ptr)
599−#endif
600−#ifdef CONFIG_64BIT
601−#define __GET_USER_UNALIGNED_DW(val, ptr) \
602− __get_user_unaligned_asm(val, "uld", ptr)
603−#endif
604−
605−extern void __get_user_unaligned_unknown(void);
606−
607−#define __get_user_unaligned_common(val, size, ptr) \
608−do { \
609− switch (size) { \
610− case 1: __get_data_asm(val, "lb", ptr); break; \
611− case 2: __get_data_unaligned_asm(val, "ulh", ptr); break; \
612− case 4: __get_data_unaligned_asm(val, "ulw", ptr); break; \
613− case 8: __GET_USER_UNALIGNED_DW(val, ptr); break; \
614− default: __get_user_unaligned_unknown(); break; \
615− } \
616−} while (0)
617−
618−#define __get_user_unaligned_nocheck(x,ptr,size) \
619−({ \
620− int __gu_err; \
621− \
622− __get_user_unaligned_common((x), size, ptr); \
623− __gu_err; \
624−})
625−
626−#define __get_user_unaligned_check(x,ptr,size) \
627−({ \
628− int __gu_err = -EFAULT; \
629− const __typeof__(*(ptr)) __user * __gu_ptr = (ptr); \
630− \
631− if (likely(access_ok(VERIFY_READ, __gu_ptr, size))) \
632− __get_user_unaligned_common((x), size, __gu_ptr); \
633− \
634− __gu_err; \
635−})
636−
637−#define __get_data_unaligned_asm(val, insn, addr) \
638−{ \
639− long __gu_tmp; \
640− \
641− __asm__ __volatile__( \
642− "1: " insn " %1, %3 \n" \
643− "2: \n" \
644− " .insn \n" \
645− " .section .fixup,\"ax\" \n" \
646− "3: li %0, %4 \n" \
647− " move %1, $0 \n" \
648− " j 2b \n" \
649− " .previous \n" \
650− " .section __ex_table,\"a\" \n" \
651− " "__UA_ADDR "\t1b, 3b \n" \
652− " "__UA_ADDR "\t1b + 4, 3b \n" \
653− " .previous \n" \
654− : "=r" (__gu_err), "=r" (__gu_tmp) \
655− : "0" (0), "o" (__m(addr)), "i" (-EFAULT)); \
656− \
657− (val) = (__typeof__(*(addr))) __gu_tmp; \
658−}
659−
660−/*
661− * Get a long long 64 using 32 bit registers.
662− */
663−#define __get_user_unaligned_asm_ll32(val, addr) \
664−{ \
665− unsigned long long __gu_tmp; \
666− \
667− __asm__ __volatile__( \
668− "1: ulw %1, (%3) \n" \
669− "2: ulw %D1, 4(%3) \n" \
670− " move %0, $0 \n" \
671− "3: \n" \
672− " .insn \n" \
673− " .section .fixup,\"ax\" \n" \
674− "4: li %0, %4 \n" \
675− " move %1, $0 \n" \
676− " move %D1, $0 \n" \
677− " j 3b \n" \
678− " .previous \n" \
679− " .section __ex_table,\"a\" \n" \
680− " " __UA_ADDR " 1b, 4b \n" \
681− " " __UA_ADDR " 1b + 4, 4b \n" \
682− " " __UA_ADDR " 2b, 4b \n" \
683− " " __UA_ADDR " 2b + 4, 4b \n" \
684− " .previous \n" \
685− : "=r" (__gu_err), "=&r" (__gu_tmp) \
686− : "0" (0), "r" (addr), "i" (-EFAULT)); \
687− (val) = (__typeof__(*(addr))) __gu_tmp; \
688−}
689−
690−/*
691− * Yuck. We need two variants, one for 64bit operation and one
692− * for 32 bit mode and old iron.
693− */
694−#ifdef CONFIG_32BIT
695−#define __PUT_USER_UNALIGNED_DW(ptr) __put_user_unaligned_asm_ll32(ptr)
696−#endif
697−#ifdef CONFIG_64BIT
698−#define __PUT_USER_UNALIGNED_DW(ptr) __put_user_unaligned_asm("usd", ptr)
699−#endif
700−
701−#define __put_user_unaligned_common(ptr, size) \
702−do { \
703− switch (size) { \
704− case 1: __put_data_asm("sb", ptr); break; \
705− case 2: __put_user_unaligned_asm("ush", ptr); break; \
706− case 4: __put_user_unaligned_asm("usw", ptr); break; \
707− case 8: __PUT_USER_UNALIGNED_DW(ptr); break; \
708− default: __put_user_unaligned_unknown(); break; \
709−} while (0)
710−
711−#define __put_user_unaligned_nocheck(x,ptr,size) \
712−({ \
713− __typeof__(*(ptr)) __pu_val; \
714− int __pu_err = 0; \
715− \
716− __pu_val = (x); \
717− __put_user_unaligned_common(ptr, size); \
718− __pu_err; \
719−})
720−
721−#define __put_user_unaligned_check(x,ptr,size) \
722−({ \
723− __typeof__(*(ptr)) __user *__pu_addr = (ptr); \
724− __typeof__(*(ptr)) __pu_val = (x); \
725− int __pu_err = -EFAULT; \
726− \
727− if (likely(access_ok(VERIFY_WRITE, __pu_addr, size))) \
728− __put_user_unaligned_common(__pu_addr, size); \
729− \
730− __pu_err; \
731−})
732−
733−#define __put_user_unaligned_asm(insn, ptr) \
734−{ \
735− __asm__ __volatile__( \
736− "1: " insn " %z2, %3 # __put_user_unaligned_asm\n" \
737− "2: \n" \
738− " .insn \n" \
739− " .section .fixup,\"ax\" \n" \
740− "3: li %0, %4 \n" \
741− " j 2b \n" \
742− " .previous \n" \
743− " .section __ex_table,\"a\" \n" \
744− " " __UA_ADDR " 1b, 3b \n" \
745− " .previous \n" \
746− : "=r" (__pu_err) \
747− : "0" (0), "Jr" (__pu_val), "o" (__m(ptr)), \
748− "i" (-EFAULT)); \
749−}
750−
751−#define __put_user_unaligned_asm_ll32(ptr) \
752−{ \
753− __asm__ __volatile__( \
754− "1: sw %2, (%3) # __put_user_unaligned_asm_ll32 \n" \
755− "2: sw %D2, 4(%3) \n" \
756− "3: \n" \
757− " .insn \n" \
758− " .section .fixup,\"ax\" \n" \
759− "4: li %0, %4 \n" \
760− " j 3b \n" \
761− " .previous \n" \
762− " .section __ex_table,\"a\" \n" \
763− " " __UA_ADDR " 1b, 4b \n" \
764− " " __UA_ADDR " 1b + 4, 4b \n" \
765− " " __UA_ADDR " 2b, 4b \n" \
766− " " __UA_ADDR " 2b + 4, 4b \n" \
767− " .previous" \
768− : "=r" (__pu_err) \
769− : "0" (0), "r" (__pu_val), "r" (ptr), \
770− "i" (-EFAULT)); \
771−}
772−
773−extern void __put_user_unaligned_unknown(void);
774−#endif
775−
776499 /*
777500 * We're generating jump to subroutines which will be outside the range of
778501 * jump instructions
arch/parisc/include/asm/uaccess.h+0−1
@@ -6,7 +6,6 @@ · 5 unmodified lines
66 */
77 #include <asm/page.h>
88 #include <asm/cache.h>
9−#include <asm-generic/uaccess-unaligned.h>
109
1110 #include <linux/bug.h>
1211 #include <linux/string.h>
arch/powerpc/include/asm/uaccess.h+0−3
@@ -90,9 +90,6 @@ · 89 unmodified lines
9090 #define __put_user_inatomic(x, ptr) \
9191 __put_user_nosleep((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
9292
93−#define __get_user_unaligned __get_user
94−#define __put_user_unaligned __put_user
95−
9693 extern long __put_user_bad(void);
9794
9895 /*
arch/s390/include/asm/uaccess.h+0−3
@@ -249,9 +249,6 @@ int __put_user_bad(void) __attribute__((noreturn)); · 248 unmodified lines
249249
250250 int __get_user_bad(void) __attribute__((noreturn));
251251
252−#define __put_user_unaligned __put_user
253−#define __get_user_unaligned __get_user
254−
255252 unsigned long __must_check
256253 raw_copy_in_user(void __user *to, const void __user *from, unsigned long n);
257254
arch/sh/include/asm/flat.h+13−2
@@ -12,11 +12,22 @@ · 11 unmodified lines
1212 #ifndef __ASM_SH_FLAT_H
1313 #define __ASM_SH_FLAT_H
1414
15+#include <asm/unaligned.h>
16+
1517 #define flat_argvp_envp_on_stack() 0
1618 #define flat_old_ram_flag(flags) (flags)
1719 #define flat_reloc_valid(reloc, size) ((reloc) <= (size))
18−#define flat_get_addr_from_rp(rp, relval, flags, p) get_unaligned(rp)
19−#define flat_put_addr_at_rp(rp, val, relval) put_unaligned(val,rp)
20+static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
21+ u32 *addr, u32 *persistent)
22+{
23+ *addr = get_unaligned((__force u32 *)rp);
24+ return 0;
25+}
26+static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel)
27+{
28+ put_unaligned(addr, (__force u32 *)rp);
29+ return 0;
30+}
2031 #define flat_get_relocate_addr(rel) (rel)
2132 #define flat_set_persistent(relval, p) ({ (void)p; 0; })
2233
arch/sparc/include/asm/uaccess_64.h+0−1
@@ -9,7 +9,6 @@ · 8 unmodified lines
99 #include <linux/string.h>
1010 #include <asm/asi.h>
1111 #include <asm/spitfire.h>
12−#include <asm-generic/uaccess-unaligned.h>
1312 #include <asm/extable_64.h>
1413
1514 #include <asm/processor.h>
arch/tile/include/asm/uaccess.h+0−1
@@ -19,7 +19,6 @@ · 18 unmodified lines
1919 * User space memory access functions
2020 */
2121 #include <linux/mm.h>
22−#include <asm-generic/uaccess-unaligned.h>
2322 #include <asm/processor.h>
2423 #include <asm/page.h>
2524
arch/x86/include/asm/uaccess.h+0−3
@@ -535,9 +535,6 @@ struct __large_struct { unsigned long buf[100]; }; · 534 unmodified lines
535535 #define __put_user(x, ptr) \
536536 __put_user_nocheck((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr)))
537537
538−#define __get_user_unaligned __get_user
539−#define __put_user_unaligned __put_user
540−
541538 /*
542539 * {get|put}_user_try and catch
543540 *
arch/xtensa/include/asm/flat.h+13−2
@@ -1,11 +1,22 @@
11 #ifndef __ASM_XTENSA_FLAT_H
22 #define __ASM_XTENSA_FLAT_H
33
4+#include <asm/unaligned.h>
5+
46 #define flat_argvp_envp_on_stack() 0
57 #define flat_old_ram_flag(flags) (flags)
68 #define flat_reloc_valid(reloc, size) ((reloc) <= (size))
7−#define flat_get_addr_from_rp(rp, relval, flags, p) get_unaligned(rp)
8−#define flat_put_addr_at_rp(rp, val, relval ) put_unaligned(val, rp)
9+static inline int flat_get_addr_from_rp(u32 __user *rp, u32 relval, u32 flags,
10+ u32 *addr, u32 *persistent)
11+{
12+ *addr = get_unaligned((__force u32 *)rp);
13+ return 0;
14+}
15+static inline int flat_put_addr_at_rp(u32 __user *rp, u32 addr, u32 rel)
16+{
17+ put_unaligned(addr, (__force u32 *)rp);
18+ return 0;
19+}
920 #define flat_get_relocate_addr(rel) (rel)
1021 #define flat_set_persistent(relval, p) 0
1122
fs/binfmt_flat.c+22−17
@@ -422,9 +422,9 @@ static int load_flat_file(struct linux_binprm *bprm, · 421 unmodified lines
422422 {
423423 struct flat_hdr *hdr;
424424 unsigned long textpos, datapos, realdatastart;
425− unsigned long text_len, data_len, bss_len, stack_len, full_data, flags;
425+ u32 text_len, data_len, bss_len, stack_len, full_data, flags;
426426 unsigned long len, memp, memp_size, extra, rlim;
427− unsigned long __user *reloc, *rp;
427+ u32 __user *reloc, *rp;
428428 struct inode *inode;
429429 int i, rev, relocs;
430430 loff_t fpos;
@@ -596,13 +596,13 @@ static int load_flat_file(struct linux_binprm *bprm, · 165 unmodified lines
596596 goto err;
597597 }
598598
599− reloc = (unsigned long __user *)
599+ reloc = (u32 __user *)
600600 (datapos + (ntohl(hdr->reloc_start) - text_len));
601601 memp = realdatastart;
602602 memp_size = len;
603603 } else {
604604
605− len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(unsigned long);
605+ len = text_len + data_len + extra + MAX_SHARED_LIBS * sizeof(u32);
606606 len = PAGE_ALIGN(len);
607607 textpos = vm_mmap(NULL, 0, len,
608608 PROT_READ | PROT_EXEC | PROT_WRITE, MAP_PRIVATE, 0);
@@ -618,10 +618,10 @@ static int load_flat_file(struct linux_binprm *bprm, · 9 unmodified lines
618618
619619 realdatastart = textpos + ntohl(hdr->data_start);
620620 datapos = ALIGN(realdatastart +
621− MAX_SHARED_LIBS * sizeof(unsigned long),
621+ MAX_SHARED_LIBS * sizeof(u32),
622622 FLAT_DATA_ALIGN);
623623
624− reloc = (unsigned long __user *)
624+ reloc = (u32 __user *)
625625 (datapos + (ntohl(hdr->reloc_start) - text_len));
626626 memp = textpos;
627627 memp_size = len;
@@ -694,7 +694,7 @@ static int load_flat_file(struct linux_binprm *bprm, · 66 unmodified lines
694694 ret = result;
695695 pr_err("Unable to read code+data+bss, errno %d\n", ret);
696696 vm_munmap(textpos, text_len + data_len + extra +
697− MAX_SHARED_LIBS * sizeof(unsigned long));
697+ MAX_SHARED_LIBS * sizeof(u32));
698698 goto err;
699699 }
700700 }
@@ -754,8 +754,8 @@ static int load_flat_file(struct linux_binprm *bprm, · 53 unmodified lines
754754 * image.
755755 */
756756 if (flags & FLAT_FLAG_GOTPIC) {
757− for (rp = (unsigned long __user *)datapos; ; rp++) {
758− unsigned long addr, rp_val;
757+ for (rp = (u32 __user *)datapos; ; rp++) {
758+ u32 addr, rp_val;
759759 if (get_user(rp_val, rp))
760760 return -EFAULT;
761761 if (rp_val == 0xffffffff)
@@ -784,9 +784,9 @@ static int load_flat_file(struct linux_binprm *bprm, · 22 unmodified lines
784784 * __start to address 4 so that is okay).
785785 */
786786 if (rev > OLD_FLAT_VERSION) {
787− unsigned long __maybe_unused persistent = 0;
787+ u32 __maybe_unused persistent = 0;
788788 for (i = 0; i < relocs; i++) {
789− unsigned long addr, relval;
789+ u32 addr, relval;
790790
791791 /*
792792 * Get the address of the pointer to be
@@ -799,15 +799,18 @@ static int load_flat_file(struct linux_binprm *bprm, · 6 unmodified lines
799799 if (flat_set_persistent(relval, &persistent))
800800 continue;
801801 addr = flat_get_relocate_addr(relval);
802− rp = (unsigned long __user *)calc_reloc(addr, libinfo, id, 1);
803− if (rp == (unsigned long __user *)RELOC_FAILED) {
802+ rp = (u32 __user *)calc_reloc(addr, libinfo, id, 1);
803+ if (rp == (u32 __user *)RELOC_FAILED) {
804804 ret = -ENOEXEC;
805805 goto err;
806806 }
807807
808808 /* Get the pointer's value. */
809− addr = flat_get_addr_from_rp(rp, relval, flags,
810− &persistent);
809+ ret = flat_get_addr_from_rp(rp, relval, flags,
810+ &addr, &persistent);
811+ if (unlikely(ret))
812+ goto err;
813+
811814 if (addr != 0) {
812815 /*
813816 * Do the relocation. PIC relocs in the data section are
@@ -822,12 +825,14 @@ static int load_flat_file(struct linux_binprm *bprm, · 8 unmodified lines
822825 }
823826
824827 /* Write back the relocated pointer. */
825− flat_put_addr_at_rp(rp, addr, relval);
828+ ret = flat_put_addr_at_rp(rp, addr, relval);
829+ if (unlikely(ret))
830+ goto err;
826831 }
827832 }
828833 } else {
829834 for (i = 0; i < relocs; i++) {
830− unsigned long relval;
835+ u32 relval;
831836 if (get_user(relval, reloc + i))
832837 return -EFAULT;
833838 relval = ntohl(relval);
include/asm-generic/uaccess-unaligned.h+0−26
@@ -1,26 +0,0 @@
1−#ifndef __ASM_GENERIC_UACCESS_UNALIGNED_H
2−#define __ASM_GENERIC_UACCESS_UNALIGNED_H
3−
4−/*
5− * This macro should be used instead of __get_user() when accessing
6− * values at locations that are not known to be aligned.
7− */
8−#define __get_user_unaligned(x, ptr) \
9−({ \
10− __typeof__ (*(ptr)) __x; \
11− __copy_from_user(&__x, (ptr), sizeof(*(ptr))) ? -EFAULT : 0; \
12− (x) = __x; \
13−})
14−
15−
16−/*
17− * This macro should be used instead of __put_user() when accessing
18− * values at locations that are not known to be aligned.
19− */
20−#define __put_user_unaligned(x, ptr) \
21−({ \
22− __typeof__ (*(ptr)) __x = (x); \
23− __copy_to_user((ptr), &__x, sizeof(*(ptr))) ? -EFAULT : 0; \
24−})
25−
26−#endif /* __ASM_GENERIC_UACCESS_UNALIGNED_H */
include/linux/flat.h+1−1
@@ -9,8 +9,8 @@ · 8 unmodified lines
99 #ifndef _LINUX_FLAT_H
1010 #define _LINUX_FLAT_H
1111
12−#include <asm/flat.h>
1312 #include <uapi/linux/flat.h>
13+#include <asm/flat.h>
1414
1515 /*
1616 * While it would be nice to keep this header clean, users of older

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t