mirror of
https://github.com/torvalds/linux.git
synced 2026-05-29 17:43:52 +02:00
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: e497310b4f ("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>
This commit is contained in:
parent
1b37ac211a
commit
af4e9ef3d7
|
|
@ -647,36 +647,22 @@ static inline void user_access_restore(unsigned long flags) { }
|
|||
/* Define RW variant so the below _mode macro expansion works */
|
||||
#define masked_user_rw_access_begin(u) masked_user_access_begin(u)
|
||||
#define user_rw_access_begin(u, s) user_access_begin(u, s)
|
||||
#define user_rw_access_end() user_access_end()
|
||||
|
||||
/* Scoped user access */
|
||||
#define USER_ACCESS_GUARD(_mode) \
|
||||
static __always_inline void __user * \
|
||||
class_user_##_mode##_begin(void __user *ptr) \
|
||||
{ \
|
||||
return ptr; \
|
||||
} \
|
||||
\
|
||||
static __always_inline void \
|
||||
class_user_##_mode##_end(void __user *ptr) \
|
||||
{ \
|
||||
user_##_mode##_access_end(); \
|
||||
} \
|
||||
\
|
||||
DEFINE_CLASS(user_ ##_mode## _access, void __user *, \
|
||||
class_user_##_mode##_end(_T), \
|
||||
class_user_##_mode##_begin(ptr), void __user *ptr) \
|
||||
\
|
||||
static __always_inline class_user_##_mode##_access_t \
|
||||
class_user_##_mode##_access_ptr(void __user *scope) \
|
||||
{ \
|
||||
return scope; \
|
||||
}
|
||||
|
||||
USER_ACCESS_GUARD(read)
|
||||
USER_ACCESS_GUARD(write)
|
||||
USER_ACCESS_GUARD(rw)
|
||||
#undef USER_ACCESS_GUARD
|
||||
/* Cleanup wrapper functions */
|
||||
static __always_inline void __scoped_user_read_access_end(const void *p)
|
||||
{
|
||||
user_read_access_end();
|
||||
};
|
||||
static __always_inline void __scoped_user_write_access_end(const void *p)
|
||||
{
|
||||
user_write_access_end();
|
||||
};
|
||||
static __always_inline void __scoped_user_rw_access_end(const void *p)
|
||||
{
|
||||
user_access_end();
|
||||
};
|
||||
|
||||
/**
|
||||
* __scoped_user_access_begin - Start a scoped user access
|
||||
|
|
@ -750,13 +736,13 @@ USER_ACCESS_GUARD(rw)
|
|||
*
|
||||
* Don't use directly. Use scoped_masked_user_$MODE_access() instead.
|
||||
*/
|
||||
#define __scoped_user_access(mode, uptr, size, elbl) \
|
||||
for (bool done = false; !done; done = true) \
|
||||
for (void __user *_tmpptr = __scoped_user_access_begin(mode, uptr, size, elbl); \
|
||||
!done; done = true) \
|
||||
for (CLASS(user_##mode##_access, scope)(_tmpptr); !done; done = true) \
|
||||
/* Force modified pointer usage within the scope */ \
|
||||
for (const typeof(uptr) uptr = _tmpptr; !done; done = true)
|
||||
#define __scoped_user_access(mode, uptr, size, elbl) \
|
||||
for (bool done = false; !done; done = true) \
|
||||
for (auto _tmpptr = __scoped_user_access_begin(mode, uptr, size, elbl); \
|
||||
!done; done = true) \
|
||||
/* Force modified pointer usage within the scope */ \
|
||||
for (const auto uptr __cleanup(__scoped_user_##mode##_access_end) = \
|
||||
_tmpptr; !done; done = true)
|
||||
|
||||
/**
|
||||
* scoped_user_read_access_size - Start a scoped user read access with given size
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user