Pull ARM fixes from Russell King: "A couple of fixes from Kees concerning problems he spotted with our user access support" * 'fixes' of git://git.armlinux.org.uk/~rmk/linux-arm: ARM: 8658/1: uaccess: fix zeroing of 64-bit get_user() ARM: 8657/1: uaccess: consistently check object sizes
Unified · Split
| @@ -478,11 +478,10 @@ extern unsigned long __must_check · 477 unmodified lines | |||
| 478 | arm_copy_from_user(void *to, const void __user *from, unsigned long n); | 478 | arm_copy_from_user(void *to, const void __user *from, unsigned long n); |
| 479 | 479 | ||
| 480 | static inline unsigned long __must_check | 480 | static inline unsigned long __must_check |
| 481 | __copy_from_user(void *to, const void __user *from, unsigned long n) | 481 | __arch_copy_from_user(void *to, const void __user *from, unsigned long n) |
| 482 | { | 482 | { |
| 483 | unsigned int __ua_flags; | 483 | unsigned int __ua_flags; |
| 484 | 484 | ||
| 485 | check_object_size(to, n, false); | ||
| 486 | __ua_flags = uaccess_save_and_enable(); | 485 | __ua_flags = uaccess_save_and_enable(); |
| 487 | n = arm_copy_from_user(to, from, n); | 486 | n = arm_copy_from_user(to, from, n); |
| 488 | uaccess_restore(__ua_flags); | 487 | uaccess_restore(__ua_flags); |
| @@ -495,18 +494,15 @@ extern unsigned long __must_check · 6 unmodified lines | |||
| 495 | __copy_to_user_std(void __user *to, const void *from, unsigned long n); | 494 | __copy_to_user_std(void __user *to, const void *from, unsigned long n); |
| 496 | 495 | ||
| 497 | static inline unsigned long __must_check | 496 | static inline unsigned long __must_check |
| 498 | __copy_to_user(void __user *to, const void *from, unsigned long n) | 497 | __arch_copy_to_user(void __user *to, const void *from, unsigned long n) |
| 499 | { | 498 | { |
| 500 | #ifndef CONFIG_UACCESS_WITH_MEMCPY | 499 | #ifndef CONFIG_UACCESS_WITH_MEMCPY |
| 501 | unsigned int __ua_flags; | 500 | unsigned int __ua_flags; |
| 502 | |||
| 503 | check_object_size(from, n, true); | ||
| 504 | __ua_flags = uaccess_save_and_enable(); | 501 | __ua_flags = uaccess_save_and_enable(); |
| 505 | n = arm_copy_to_user(to, from, n); | 502 | n = arm_copy_to_user(to, from, n); |
| 506 | uaccess_restore(__ua_flags); | 503 | uaccess_restore(__ua_flags); |
| 507 | return n; | 504 | return n; |
| 508 | #else | 505 | #else |
| 509 | check_object_size(from, n, true); | ||
| 510 | return arm_copy_to_user(to, from, n); | 506 | return arm_copy_to_user(to, from, n); |
| 511 | #endif | 507 | #endif |
| 512 | } | 508 | } |
| @@ -526,25 +522,49 @@ __clear_user(void __user *addr, unsigned long n) · 13 unmodified lines | |||
| 526 | } | 522 | } |
| 527 | 523 | ||
| 528 | #else | 524 | #else |
| 529 | #define __copy_from_user(to, from, n) (memcpy(to, (void __force *)from, n), 0) | 525 | #define __arch_copy_from_user(to, from, n) \ |
| 530 | #define __copy_to_user(to, from, n) (memcpy((void __force *)to, from, n), 0) | 526 | (memcpy(to, (void __force *)from, n), 0) |
| 527 | #define __arch_copy_to_user(to, from, n) \ | ||
| 528 | (memcpy((void __force *)to, from, n), 0) | ||
| 531 | #define __clear_user(addr, n) (memset((void __force *)addr, 0, n), 0) | 529 | #define __clear_user(addr, n) (memset((void __force *)addr, 0, n), 0) |
| 532 | #endif | 530 | #endif |
| 533 | 531 | ||
| 534 | static inline unsigned long __must_check copy_from_user(void *to, const void __user *from, unsigned long n) | 532 | static inline unsigned long __must_check |
| 533 | __copy_from_user(void *to, const void __user *from, unsigned long n) | ||
| 534 | { | ||
| 535 | check_object_size(to, n, false); | ||
| 536 | return __arch_copy_from_user(to, from, n); | ||
| 537 | } | ||
| 538 | |||
| 539 | static inline unsigned long __must_check | ||
| 540 | copy_from_user(void *to, const void __user *from, unsigned long n) | ||
| 535 | { | 541 | { |
| 536 | unsigned long res = n; | 542 | unsigned long res = n; |
| 543 | |||
| 544 | check_object_size(to, n, false); | ||
| 545 | |||
| 537 | if (likely(access_ok(VERIFY_READ, from, n))) | 546 | if (likely(access_ok(VERIFY_READ, from, n))) |
| 538 | res = __copy_from_user(to, from, n); | 547 | res = __arch_copy_from_user(to, from, n); |
| 539 | if (unlikely(res)) | 548 | if (unlikely(res)) |
| 540 | memset(to + (n - res), 0, res); | 549 | memset(to + (n - res), 0, res); |
| 541 | return res; | 550 | return res; |
| 542 | } | 551 | } |
| 543 | 552 | ||
| 544 | static inline unsigned long __must_check copy_to_user(void __user *to, const void *from, unsigned long n) | 553 | static inline unsigned long __must_check |
| 554 | __copy_to_user(void __user *to, const void *from, unsigned long n) | ||
| 545 | { | 555 | { |
| 556 | check_object_size(from, n, true); | ||
| 557 | |||
| 558 | return __arch_copy_to_user(to, from, n); | ||
| 559 | } | ||
| 560 | |||
| 561 | static inline unsigned long __must_check | ||
| 562 | copy_to_user(void __user *to, const void *from, unsigned long n) | ||
| 563 | { | ||
| 564 | check_object_size(from, n, true); | ||
| 565 | |||
| 546 | if (access_ok(VERIFY_WRITE, to, n)) | 566 | if (access_ok(VERIFY_WRITE, to, n)) |
| 547 | n = __copy_to_user(to, from, n); | 567 | n = __arch_copy_to_user(to, from, n); |
| 548 | return n; | 568 | return n; |
| 549 | } | 569 | } |
| 550 | 570 | ||
| @@ -67,7 +67,7 @@ ENTRY(__get_user_4) · 66 unmodified lines | |||
| 67 | ENDPROC(__get_user_4) | 67 | ENDPROC(__get_user_4) |
| 68 | 68 | ||
| 69 | ENTRY(__get_user_8) | 69 | ENTRY(__get_user_8) |
| 70 | check_uaccess r0, 8, r1, r2, __get_user_bad | 70 | check_uaccess r0, 8, r1, r2, __get_user_bad8 |
| 71 | #ifdef CONFIG_THUMB2_KERNEL | 71 | #ifdef CONFIG_THUMB2_KERNEL |
| 72 | 5: TUSER(ldr) r2, [r0] | 72 | 5: TUSER(ldr) r2, [r0] |
| 73 | 6: TUSER(ldr) r3, [r0, #4] | 73 | 6: TUSER(ldr) r3, [r0, #4] |