Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

uaccess: Fix scoped_user_read_access() for 'pointer to const'

If a 'const struct foo __user *ptr' is used for the address passed to
scoped_user_read_access() then you get a warning/error

uaccess.h:691:1: error: initialization discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]

for the

void __user *_tmpptr = __scoped_user_access_begin(mode, uptr, size, elbl)

assignment.

Fix by using 'auto' for both _tmpptr and the redeclaration of uptr.
Replace the CLASS() with explicit __cleanup() functions on uptr.

Fixes: e497310b4ffb ("uaccess: Provide scoped user access regions")
Signed-off-by: David Laight <david.laight.linux@gmail.com>
Reviewed-and-tested-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

David Laight and committed by
Linus Torvalds
af4e9ef3 1b37ac21

+20 -34
+20 -34
include/linux/uaccess.h
··· 647 647 /* Define RW variant so the below _mode macro expansion works */ 648 648 #define masked_user_rw_access_begin(u) masked_user_access_begin(u) 649 649 #define user_rw_access_begin(u, s) user_access_begin(u, s) 650 - #define user_rw_access_end() user_access_end() 651 650 652 651 /* Scoped user access */ 653 - #define USER_ACCESS_GUARD(_mode) \ 654 - static __always_inline void __user * \ 655 - class_user_##_mode##_begin(void __user *ptr) \ 656 - { \ 657 - return ptr; \ 658 - } \ 659 - \ 660 - static __always_inline void \ 661 - class_user_##_mode##_end(void __user *ptr) \ 662 - { \ 663 - user_##_mode##_access_end(); \ 664 - } \ 665 - \ 666 - DEFINE_CLASS(user_ ##_mode## _access, void __user *, \ 667 - class_user_##_mode##_end(_T), \ 668 - class_user_##_mode##_begin(ptr), void __user *ptr) \ 669 - \ 670 - static __always_inline class_user_##_mode##_access_t \ 671 - class_user_##_mode##_access_ptr(void __user *scope) \ 672 - { \ 673 - return scope; \ 674 - } 675 652 676 - USER_ACCESS_GUARD(read) 677 - USER_ACCESS_GUARD(write) 678 - USER_ACCESS_GUARD(rw) 679 - #undef USER_ACCESS_GUARD 653 + /* Cleanup wrapper functions */ 654 + static __always_inline void __scoped_user_read_access_end(const void *p) 655 + { 656 + user_read_access_end(); 657 + }; 658 + static __always_inline void __scoped_user_write_access_end(const void *p) 659 + { 660 + user_write_access_end(); 661 + }; 662 + static __always_inline void __scoped_user_rw_access_end(const void *p) 663 + { 664 + user_access_end(); 665 + }; 680 666 681 667 /** 682 668 * __scoped_user_access_begin - Start a scoped user access ··· 736 750 * 737 751 * Don't use directly. Use scoped_masked_user_$MODE_access() instead. 738 752 */ 739 - #define __scoped_user_access(mode, uptr, size, elbl) \ 740 - for (bool done = false; !done; done = true) \ 741 - for (void __user *_tmpptr = __scoped_user_access_begin(mode, uptr, size, elbl); \ 742 - !done; done = true) \ 743 - for (CLASS(user_##mode##_access, scope)(_tmpptr); !done; done = true) \ 744 - /* Force modified pointer usage within the scope */ \ 745 - for (const typeof(uptr) uptr = _tmpptr; !done; done = true) 753 + #define __scoped_user_access(mode, uptr, size, elbl) \ 754 + for (bool done = false; !done; done = true) \ 755 + for (auto _tmpptr = __scoped_user_access_begin(mode, uptr, size, elbl); \ 756 + !done; done = true) \ 757 + /* Force modified pointer usage within the scope */ \ 758 + for (const auto uptr __cleanup(__scoped_user_##mode##_access_end) = \ 759 + _tmpptr; !done; done = true) 746 760 747 761 /** 748 762 * scoped_user_read_access_size - Start a scoped user read access with given size