uaccess: fix type mismatch warnings from access_ok()

On some architectures, access_ok() does not do any argument type
checking, so replacing the definition with a generic one causes
a few warnings for harmless issues that were never caught before.

Fix the ones that I found either through my own test builds or
that were reported by the 0-day bot.

Reported-by: kernel test robot <lkp@intel.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Acked-by: Dinh Nguyen <dinguyen@kernel.org>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
Arnd Bergmann 2022-02-14 20:22:10 +01:00
parent 52fe8d125c
commit 23fc539e81
10 changed files with 23 additions and 21 deletions

View file

@ -43,7 +43,7 @@ SYSCALL_DEFINE0(arc_gettls)
return task_thread_info(current)->thr_ptr; return task_thread_info(current)->thr_ptr;
} }
SYSCALL_DEFINE3(arc_usr_cmpxchg, int *, uaddr, int, expected, int, new) SYSCALL_DEFINE3(arc_usr_cmpxchg, int __user *, uaddr, int, expected, int, new)
{ {
struct pt_regs *regs = current_pt_regs(); struct pt_regs *regs = current_pt_regs();
u32 uval; u32 uval;

View file

@ -195,7 +195,7 @@ static int swp_handler(struct pt_regs *regs, unsigned int instr)
destreg, EXTRACT_REG_NUM(instr, RT2_OFFSET), data); destreg, EXTRACT_REG_NUM(instr, RT2_OFFSET), data);
/* Check access in reasonable access range for both SWP and SWPB */ /* Check access in reasonable access range for both SWP and SWPB */
if (!access_ok((address & ~3), 4)) { if (!access_ok((void __user *)(address & ~3), 4)) {
pr_debug("SWP{B} emulation: access to %p not allowed!\n", pr_debug("SWP{B} emulation: access to %p not allowed!\n",
(void *)address); (void *)address);
res = -EFAULT; res = -EFAULT;

View file

@ -576,7 +576,7 @@ do_cache_op(unsigned long start, unsigned long end, int flags)
if (end < start || flags) if (end < start || flags)
return -EINVAL; return -EINVAL;
if (!access_ok(start, end - start)) if (!access_ok((void __user *)start, end - start))
return -EFAULT; return -EFAULT;
return __do_cache_op(start, end); return __do_cache_op(start, end);

View file

@ -49,7 +49,7 @@ static unsigned long user_backtrace(struct perf_callchain_entry_ctx *entry,
{ {
struct stackframe buftail; struct stackframe buftail;
unsigned long lr = 0; unsigned long lr = 0;
unsigned long *user_frame_tail = (unsigned long *)fp; unsigned long __user *user_frame_tail = (unsigned long __user *)fp;
/* Check accessibility of one struct frame_tail beyond */ /* Check accessibility of one struct frame_tail beyond */
if (!access_ok(user_frame_tail, sizeof(buftail))) if (!access_ok(user_frame_tail, sizeof(buftail)))

View file

@ -136,7 +136,7 @@ static inline void __user *get_sigframe(struct ksignal *ksig,
static int static int
setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs) setup_rt_frame(struct ksignal *ksig, sigset_t *set, struct pt_regs *regs)
{ {
struct rt_sigframe *frame; struct rt_sigframe __user *frame;
int err = 0; int err = 0;
frame = get_sigframe(ksig, regs, sizeof(*frame)); frame = get_sigframe(ksig, regs, sizeof(*frame));

View file

@ -36,10 +36,10 @@ struct rt_sigframe {
static inline int rt_restore_ucontext(struct pt_regs *regs, static inline int rt_restore_ucontext(struct pt_regs *regs,
struct switch_stack *sw, struct switch_stack *sw,
struct ucontext *uc, int *pr2) struct ucontext __user *uc, int *pr2)
{ {
int temp; int temp;
unsigned long *gregs = uc->uc_mcontext.gregs; unsigned long __user *gregs = uc->uc_mcontext.gregs;
int err; int err;
/* Always make any pending restarted system calls return -EINTR */ /* Always make any pending restarted system calls return -EINTR */
@ -102,10 +102,11 @@ asmlinkage int do_rt_sigreturn(struct switch_stack *sw)
{ {
struct pt_regs *regs = (struct pt_regs *)(sw + 1); struct pt_regs *regs = (struct pt_regs *)(sw + 1);
/* Verify, can we follow the stack back */ /* Verify, can we follow the stack back */
struct rt_sigframe *frame = (struct rt_sigframe *) regs->sp; struct rt_sigframe __user *frame;
sigset_t set; sigset_t set;
int rval; int rval;
frame = (struct rt_sigframe __user *) regs->sp;
if (!access_ok(frame, sizeof(*frame))) if (!access_ok(frame, sizeof(*frame)))
goto badframe; goto badframe;
@ -124,10 +125,10 @@ asmlinkage int do_rt_sigreturn(struct switch_stack *sw)
return 0; return 0;
} }
static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs) static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *regs)
{ {
struct switch_stack *sw = (struct switch_stack *)regs - 1; struct switch_stack *sw = (struct switch_stack *)regs - 1;
unsigned long *gregs = uc->uc_mcontext.gregs; unsigned long __user *gregs = uc->uc_mcontext.gregs;
int err = 0; int err = 0;
err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version); err |= __put_user(MCONTEXT_VERSION, &uc->uc_mcontext.version);
@ -162,7 +163,8 @@ static inline int rt_setup_ucontext(struct ucontext *uc, struct pt_regs *regs)
return err; return err;
} }
static inline void *get_sigframe(struct ksignal *ksig, struct pt_regs *regs, static inline void __user *get_sigframe(struct ksignal *ksig,
struct pt_regs *regs,
size_t frame_size) size_t frame_size)
{ {
unsigned long usp; unsigned long usp;
@ -174,13 +176,13 @@ static inline void *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
usp = sigsp(usp, ksig); usp = sigsp(usp, ksig);
/* Verify, is it 32 or 64 bit aligned */ /* Verify, is it 32 or 64 bit aligned */
return (void *)((usp - frame_size) & -8UL); return (void __user *)((usp - frame_size) & -8UL);
} }
static int setup_rt_frame(struct ksignal *ksig, sigset_t *set, static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
struct pt_regs *regs) struct pt_regs *regs)
{ {
struct rt_sigframe *frame; struct rt_sigframe __user *frame;
int err = 0; int err = 0;
frame = get_sigframe(ksig, regs, sizeof(*frame)); frame = get_sigframe(ksig, regs, sizeof(*frame));

View file

@ -112,9 +112,9 @@ static nokprobe_inline long address_ok(struct pt_regs *regs,
{ {
if (!user_mode(regs)) if (!user_mode(regs))
return 1; return 1;
if (__access_ok(ea, nb)) if (access_ok((void __user *)ea, nb))
return 1; return 1;
if (__access_ok(ea, 1)) if (access_ok((void __user *)ea, 1))
/* Access overlaps the end of the user region */ /* Access overlaps the end of the user region */
regs->dar = TASK_SIZE_MAX - 1; regs->dar = TASK_SIZE_MAX - 1;
else else

View file

@ -15,8 +15,8 @@ static unsigned long user_backtrace(struct perf_callchain_entry_ctx *entry,
{ {
struct stackframe buftail; struct stackframe buftail;
unsigned long ra = 0; unsigned long ra = 0;
unsigned long *user_frame_tail = unsigned long __user *user_frame_tail =
(unsigned long *)(fp - sizeof(struct stackframe)); (unsigned long __user *)(fp - sizeof(struct stackframe));
/* Check accessibility of one struct frame_tail beyond */ /* Check accessibility of one struct frame_tail beyond */
if (!access_ok(user_frame_tail, sizeof(buftail))) if (!access_ok(user_frame_tail, sizeof(buftail)))

View file

@ -65,7 +65,7 @@ struct rt_signal_frame {
*/ */
static inline bool invalid_frame_pointer(void __user *fp, int fplen) static inline bool invalid_frame_pointer(void __user *fp, int fplen)
{ {
if ((((unsigned long) fp) & 15) || !__access_ok((unsigned long)fp, fplen)) if ((((unsigned long) fp) & 15) || !access_ok(fp, fplen))
return true; return true;
return false; return false;

View file

@ -417,8 +417,8 @@ static bool test_kernel_ptr(unsigned long addr, int size)
return false; return false;
/* should be at least readable kernel address */ /* should be at least readable kernel address */
if (access_ok(ptr, 1) || if (access_ok((void __user *)ptr, 1) ||
access_ok(ptr + size - 1, 1) || access_ok((void __user *)ptr + size - 1, 1) ||
get_kernel_nofault(buf, ptr) || get_kernel_nofault(buf, ptr) ||
get_kernel_nofault(buf, ptr + size - 1)) { get_kernel_nofault(buf, ptr + size - 1)) {
pr_err("invalid kernel ptr: %#lx\n", addr); pr_err("invalid kernel ptr: %#lx\n", addr);