Remove 'type' argument from access_ok() function
Nobody has actually used the type (VERIFY_READ vs VERIFY_WRITE) argument of the user address range verification function since we got rid of the old racy i386-only code to walk page tables by hand. It existed because the original 80386 would not honor the write protect bit when in kernel mode, so you had to do COW by hand before doing any user access. But we haven't supported that in a long time, and these days the 'type' argument is a purely historical artifact. A discussion about extending 'user_access_begin()' to do the range checking resulted this patch, because there is no way we're going to move the old VERIFY_xyz interface to that model. And it's best done at the end of the merge window when I've done most of my merges, so let's just get this done once and for all. This patch was mostly done with a sed-script, with manual fix-ups for the cases that weren't of the trivial 'access_ok(VERIFY_xyz' form. There were a couple of notable cases: - csky still had the old "verify_area()" name as an alias. - the iter_iov code had magical hardcoded knowledge of the actual values of VERIFY_{READ,WRITE} (not that they mattered, since nothing really used it) - microblaze used the type argument for a debug printout but other than those oddities this should be a total no-op patch. I tried to fix up all architectures, did fairly extensive grepping for access_ok() uses, and the changes are trivial, but I may have missed something. Any missed conversion should be trivially fixable, though. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
@@ -79,7 +79,7 @@ int bpf_check_uarg_tail_zero(void __user *uaddr,
|
||||
if (unlikely(actual_size > PAGE_SIZE)) /* silly large */
|
||||
return -E2BIG;
|
||||
|
||||
if (unlikely(!access_ok(VERIFY_READ, uaddr, actual_size)))
|
||||
if (unlikely(!access_ok(uaddr, actual_size)))
|
||||
return -EFAULT;
|
||||
|
||||
if (actual_size <= expected_size)
|
||||
|
@@ -95,28 +95,28 @@ int compat_put_timex(struct compat_timex __user *utp, const struct timex *txc)
|
||||
|
||||
static int __compat_get_timeval(struct timeval *tv, const struct old_timeval32 __user *ctv)
|
||||
{
|
||||
return (!access_ok(VERIFY_READ, ctv, sizeof(*ctv)) ||
|
||||
return (!access_ok(ctv, sizeof(*ctv)) ||
|
||||
__get_user(tv->tv_sec, &ctv->tv_sec) ||
|
||||
__get_user(tv->tv_usec, &ctv->tv_usec)) ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
static int __compat_put_timeval(const struct timeval *tv, struct old_timeval32 __user *ctv)
|
||||
{
|
||||
return (!access_ok(VERIFY_WRITE, ctv, sizeof(*ctv)) ||
|
||||
return (!access_ok(ctv, sizeof(*ctv)) ||
|
||||
__put_user(tv->tv_sec, &ctv->tv_sec) ||
|
||||
__put_user(tv->tv_usec, &ctv->tv_usec)) ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
static int __compat_get_timespec(struct timespec *ts, const struct old_timespec32 __user *cts)
|
||||
{
|
||||
return (!access_ok(VERIFY_READ, cts, sizeof(*cts)) ||
|
||||
return (!access_ok(cts, sizeof(*cts)) ||
|
||||
__get_user(ts->tv_sec, &cts->tv_sec) ||
|
||||
__get_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
|
||||
}
|
||||
|
||||
static int __compat_put_timespec(const struct timespec *ts, struct old_timespec32 __user *cts)
|
||||
{
|
||||
return (!access_ok(VERIFY_WRITE, cts, sizeof(*cts)) ||
|
||||
return (!access_ok(cts, sizeof(*cts)) ||
|
||||
__put_user(ts->tv_sec, &cts->tv_sec) ||
|
||||
__put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
|
||||
}
|
||||
@@ -335,7 +335,7 @@ int get_compat_sigevent(struct sigevent *event,
|
||||
const struct compat_sigevent __user *u_event)
|
||||
{
|
||||
memset(event, 0, sizeof(*event));
|
||||
return (!access_ok(VERIFY_READ, u_event, sizeof(*u_event)) ||
|
||||
return (!access_ok(u_event, sizeof(*u_event)) ||
|
||||
__get_user(event->sigev_value.sival_int,
|
||||
&u_event->sigev_value.sival_int) ||
|
||||
__get_user(event->sigev_signo, &u_event->sigev_signo) ||
|
||||
@@ -354,7 +354,7 @@ long compat_get_bitmap(unsigned long *mask, const compat_ulong_t __user *umask,
|
||||
bitmap_size = ALIGN(bitmap_size, BITS_PER_COMPAT_LONG);
|
||||
nr_compat_longs = BITS_TO_COMPAT_LONGS(bitmap_size);
|
||||
|
||||
if (!access_ok(VERIFY_READ, umask, bitmap_size / 8))
|
||||
if (!access_ok(umask, bitmap_size / 8))
|
||||
return -EFAULT;
|
||||
|
||||
user_access_begin();
|
||||
@@ -384,7 +384,7 @@ long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask,
|
||||
bitmap_size = ALIGN(bitmap_size, BITS_PER_COMPAT_LONG);
|
||||
nr_compat_longs = BITS_TO_COMPAT_LONGS(bitmap_size);
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, umask, bitmap_size / 8))
|
||||
if (!access_ok(umask, bitmap_size / 8))
|
||||
return -EFAULT;
|
||||
|
||||
user_access_begin();
|
||||
@@ -438,7 +438,7 @@ void __user *compat_alloc_user_space(unsigned long len)
|
||||
|
||||
ptr = arch_compat_alloc_user_space(len);
|
||||
|
||||
if (unlikely(!access_ok(VERIFY_WRITE, ptr, len)))
|
||||
if (unlikely(!access_ok(ptr, len)))
|
||||
return NULL;
|
||||
|
||||
return ptr;
|
||||
|
@@ -10135,7 +10135,7 @@ static int perf_copy_attr(struct perf_event_attr __user *uattr,
|
||||
u32 size;
|
||||
int ret;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uattr, PERF_ATTR_SIZE_VER0))
|
||||
if (!access_ok(uattr, PERF_ATTR_SIZE_VER0))
|
||||
return -EFAULT;
|
||||
|
||||
/*
|
||||
|
@@ -1604,7 +1604,7 @@ SYSCALL_DEFINE5(waitid, int, which, pid_t, upid, struct siginfo __user *,
|
||||
if (!infop)
|
||||
return err;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, infop, sizeof(*infop)))
|
||||
if (!access_ok(infop, sizeof(*infop)))
|
||||
return -EFAULT;
|
||||
|
||||
user_access_begin();
|
||||
@@ -1732,7 +1732,7 @@ COMPAT_SYSCALL_DEFINE5(waitid,
|
||||
if (!infop)
|
||||
return err;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, infop, sizeof(*infop)))
|
||||
if (!access_ok(infop, sizeof(*infop)))
|
||||
return -EFAULT;
|
||||
|
||||
user_access_begin();
|
||||
|
@@ -481,13 +481,18 @@ static void drop_futex_key_refs(union futex_key *key)
|
||||
}
|
||||
}
|
||||
|
||||
enum futex_access {
|
||||
FUTEX_READ,
|
||||
FUTEX_WRITE
|
||||
};
|
||||
|
||||
/**
|
||||
* get_futex_key() - Get parameters which are the keys for a futex
|
||||
* @uaddr: virtual address of the futex
|
||||
* @fshared: 0 for a PROCESS_PRIVATE futex, 1 for PROCESS_SHARED
|
||||
* @key: address where result is stored.
|
||||
* @rw: mapping needs to be read/write (values: VERIFY_READ,
|
||||
* VERIFY_WRITE)
|
||||
* @rw: mapping needs to be read/write (values: FUTEX_READ,
|
||||
* FUTEX_WRITE)
|
||||
*
|
||||
* Return: a negative error code or 0
|
||||
*
|
||||
@@ -500,7 +505,7 @@ static void drop_futex_key_refs(union futex_key *key)
|
||||
* lock_page() might sleep, the caller should not hold a spinlock.
|
||||
*/
|
||||
static int
|
||||
get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw)
|
||||
get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, enum futex_access rw)
|
||||
{
|
||||
unsigned long address = (unsigned long)uaddr;
|
||||
struct mm_struct *mm = current->mm;
|
||||
@@ -516,7 +521,7 @@ get_futex_key(u32 __user *uaddr, int fshared, union futex_key *key, int rw)
|
||||
return -EINVAL;
|
||||
address -= key->both.offset;
|
||||
|
||||
if (unlikely(!access_ok(rw, uaddr, sizeof(u32))))
|
||||
if (unlikely(!access_ok(uaddr, sizeof(u32))))
|
||||
return -EFAULT;
|
||||
|
||||
if (unlikely(should_fail_futex(fshared)))
|
||||
@@ -546,7 +551,7 @@ again:
|
||||
* If write access is not required (eg. FUTEX_WAIT), try
|
||||
* and get read-only access.
|
||||
*/
|
||||
if (err == -EFAULT && rw == VERIFY_READ) {
|
||||
if (err == -EFAULT && rw == FUTEX_READ) {
|
||||
err = get_user_pages_fast(address, 1, 0, &page);
|
||||
ro = 1;
|
||||
}
|
||||
@@ -1583,7 +1588,7 @@ futex_wake(u32 __user *uaddr, unsigned int flags, int nr_wake, u32 bitset)
|
||||
if (!bitset)
|
||||
return -EINVAL;
|
||||
|
||||
ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &key, VERIFY_READ);
|
||||
ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &key, FUTEX_READ);
|
||||
if (unlikely(ret != 0))
|
||||
goto out;
|
||||
|
||||
@@ -1642,7 +1647,7 @@ static int futex_atomic_op_inuser(unsigned int encoded_op, u32 __user *uaddr)
|
||||
oparg = 1 << oparg;
|
||||
}
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uaddr, sizeof(u32)))
|
||||
if (!access_ok(uaddr, sizeof(u32)))
|
||||
return -EFAULT;
|
||||
|
||||
ret = arch_futex_atomic_op_inuser(op, oparg, &oldval, uaddr);
|
||||
@@ -1682,10 +1687,10 @@ futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2,
|
||||
DEFINE_WAKE_Q(wake_q);
|
||||
|
||||
retry:
|
||||
ret = get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1, VERIFY_READ);
|
||||
ret = get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1, FUTEX_READ);
|
||||
if (unlikely(ret != 0))
|
||||
goto out;
|
||||
ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2, VERIFY_WRITE);
|
||||
ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2, FUTEX_WRITE);
|
||||
if (unlikely(ret != 0))
|
||||
goto out_put_key1;
|
||||
|
||||
@@ -1961,11 +1966,11 @@ static int futex_requeue(u32 __user *uaddr1, unsigned int flags,
|
||||
}
|
||||
|
||||
retry:
|
||||
ret = get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1, VERIFY_READ);
|
||||
ret = get_futex_key(uaddr1, flags & FLAGS_SHARED, &key1, FUTEX_READ);
|
||||
if (unlikely(ret != 0))
|
||||
goto out;
|
||||
ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2,
|
||||
requeue_pi ? VERIFY_WRITE : VERIFY_READ);
|
||||
requeue_pi ? FUTEX_WRITE : FUTEX_READ);
|
||||
if (unlikely(ret != 0))
|
||||
goto out_put_key1;
|
||||
|
||||
@@ -2634,7 +2639,7 @@ static int futex_wait_setup(u32 __user *uaddr, u32 val, unsigned int flags,
|
||||
* while the syscall executes.
|
||||
*/
|
||||
retry:
|
||||
ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q->key, VERIFY_READ);
|
||||
ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q->key, FUTEX_READ);
|
||||
if (unlikely(ret != 0))
|
||||
return ret;
|
||||
|
||||
@@ -2793,7 +2798,7 @@ static int futex_lock_pi(u32 __user *uaddr, unsigned int flags,
|
||||
}
|
||||
|
||||
retry:
|
||||
ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q.key, VERIFY_WRITE);
|
||||
ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &q.key, FUTEX_WRITE);
|
||||
if (unlikely(ret != 0))
|
||||
goto out;
|
||||
|
||||
@@ -2972,7 +2977,7 @@ retry:
|
||||
if ((uval & FUTEX_TID_MASK) != vpid)
|
||||
return -EPERM;
|
||||
|
||||
ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &key, VERIFY_WRITE);
|
||||
ret = get_futex_key(uaddr, flags & FLAGS_SHARED, &key, FUTEX_WRITE);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@@ -3199,7 +3204,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags,
|
||||
*/
|
||||
rt_mutex_init_waiter(&rt_waiter);
|
||||
|
||||
ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2, VERIFY_WRITE);
|
||||
ret = get_futex_key(uaddr2, flags & FLAGS_SHARED, &key2, FUTEX_WRITE);
|
||||
if (unlikely(ret != 0))
|
||||
goto out;
|
||||
|
||||
|
@@ -1466,7 +1466,7 @@ int do_syslog(int type, char __user *buf, int len, int source)
|
||||
return -EINVAL;
|
||||
if (!len)
|
||||
return 0;
|
||||
if (!access_ok(VERIFY_WRITE, buf, len))
|
||||
if (!access_ok(buf, len))
|
||||
return -EFAULT;
|
||||
error = wait_event_interruptible(log_wait,
|
||||
syslog_seq != log_next_seq);
|
||||
@@ -1484,7 +1484,7 @@ int do_syslog(int type, char __user *buf, int len, int source)
|
||||
return -EINVAL;
|
||||
if (!len)
|
||||
return 0;
|
||||
if (!access_ok(VERIFY_WRITE, buf, len))
|
||||
if (!access_ok(buf, len))
|
||||
return -EFAULT;
|
||||
error = syslog_print_all(buf, len, clear);
|
||||
break;
|
||||
|
@@ -1073,7 +1073,7 @@ int ptrace_request(struct task_struct *child, long request,
|
||||
struct iovec kiov;
|
||||
struct iovec __user *uiov = datavp;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uiov, sizeof(*uiov)))
|
||||
if (!access_ok(uiov, sizeof(*uiov)))
|
||||
return -EFAULT;
|
||||
|
||||
if (__get_user(kiov.iov_base, &uiov->iov_base) ||
|
||||
@@ -1229,7 +1229,7 @@ int compat_ptrace_request(struct task_struct *child, compat_long_t request,
|
||||
compat_uptr_t ptr;
|
||||
compat_size_t len;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uiov, sizeof(*uiov)))
|
||||
if (!access_ok(uiov, sizeof(*uiov)))
|
||||
return -EFAULT;
|
||||
|
||||
if (__get_user(ptr, &uiov->iov_base) ||
|
||||
|
@@ -267,7 +267,7 @@ void __rseq_handle_notify_resume(struct ksignal *ksig, struct pt_regs *regs)
|
||||
|
||||
if (unlikely(t->flags & PF_EXITING))
|
||||
return;
|
||||
if (unlikely(!access_ok(VERIFY_WRITE, t->rseq, sizeof(*t->rseq))))
|
||||
if (unlikely(!access_ok(t->rseq, sizeof(*t->rseq))))
|
||||
goto error;
|
||||
ret = rseq_ip_fixup(regs);
|
||||
if (unlikely(ret < 0))
|
||||
@@ -295,7 +295,7 @@ void rseq_syscall(struct pt_regs *regs)
|
||||
|
||||
if (!t->rseq)
|
||||
return;
|
||||
if (!access_ok(VERIFY_READ, t->rseq, sizeof(*t->rseq)) ||
|
||||
if (!access_ok(t->rseq, sizeof(*t->rseq)) ||
|
||||
rseq_get_rseq_cs(t, &rseq_cs) || in_rseq_cs(ip, &rseq_cs))
|
||||
force_sig(SIGSEGV, t);
|
||||
}
|
||||
@@ -351,7 +351,7 @@ SYSCALL_DEFINE4(rseq, struct rseq __user *, rseq, u32, rseq_len,
|
||||
if (!IS_ALIGNED((unsigned long)rseq, __alignof__(*rseq)) ||
|
||||
rseq_len != sizeof(*rseq))
|
||||
return -EINVAL;
|
||||
if (!access_ok(VERIFY_WRITE, rseq, rseq_len))
|
||||
if (!access_ok(rseq, rseq_len))
|
||||
return -EFAULT;
|
||||
current->rseq = rseq;
|
||||
current->rseq_len = rseq_len;
|
||||
|
@@ -4450,7 +4450,7 @@ static int sched_copy_attr(struct sched_attr __user *uattr, struct sched_attr *a
|
||||
u32 size;
|
||||
int ret;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uattr, SCHED_ATTR_SIZE_VER0))
|
||||
if (!access_ok(uattr, SCHED_ATTR_SIZE_VER0))
|
||||
return -EFAULT;
|
||||
|
||||
/* Zero the full structure, so that a short copy will be nice: */
|
||||
@@ -4650,7 +4650,7 @@ static int sched_read_attr(struct sched_attr __user *uattr,
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, uattr, usize))
|
||||
if (!access_ok(uattr, usize))
|
||||
return -EFAULT;
|
||||
|
||||
/*
|
||||
|
@@ -3997,7 +3997,7 @@ SYSCALL_DEFINE3(sigaction, int, sig,
|
||||
|
||||
if (act) {
|
||||
old_sigset_t mask;
|
||||
if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
|
||||
if (!access_ok(act, sizeof(*act)) ||
|
||||
__get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
|
||||
__get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
|
||||
__get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
|
||||
@@ -4012,7 +4012,7 @@ SYSCALL_DEFINE3(sigaction, int, sig,
|
||||
ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
|
||||
|
||||
if (!ret && oact) {
|
||||
if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
|
||||
if (!access_ok(oact, sizeof(*oact)) ||
|
||||
__put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
|
||||
__put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
|
||||
__put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
|
||||
@@ -4034,7 +4034,7 @@ COMPAT_SYSCALL_DEFINE3(sigaction, int, sig,
|
||||
compat_uptr_t handler, restorer;
|
||||
|
||||
if (act) {
|
||||
if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
|
||||
if (!access_ok(act, sizeof(*act)) ||
|
||||
__get_user(handler, &act->sa_handler) ||
|
||||
__get_user(restorer, &act->sa_restorer) ||
|
||||
__get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
|
||||
@@ -4052,7 +4052,7 @@ COMPAT_SYSCALL_DEFINE3(sigaction, int, sig,
|
||||
ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
|
||||
|
||||
if (!ret && oact) {
|
||||
if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
|
||||
if (!access_ok(oact, sizeof(*oact)) ||
|
||||
__put_user(ptr_to_compat(old_ka.sa.sa_handler),
|
||||
&oact->sa_handler) ||
|
||||
__put_user(ptr_to_compat(old_ka.sa.sa_restorer),
|
||||
|
@@ -2627,7 +2627,7 @@ COMPAT_SYSCALL_DEFINE1(sysinfo, struct compat_sysinfo __user *, info)
|
||||
s.freehigh >>= bitcount;
|
||||
}
|
||||
|
||||
if (!access_ok(VERIFY_WRITE, info, sizeof(struct compat_sysinfo)) ||
|
||||
if (!access_ok(info, sizeof(struct compat_sysinfo)) ||
|
||||
__put_user(s.uptime, &info->uptime) ||
|
||||
__put_user(s.loads[0], &info->loads[0]) ||
|
||||
__put_user(s.loads[1], &info->loads[1]) ||
|
||||
|
@@ -170,7 +170,7 @@ BPF_CALL_3(bpf_probe_write_user, void *, unsafe_ptr, const void *, src,
|
||||
return -EPERM;
|
||||
if (unlikely(uaccess_kernel()))
|
||||
return -EPERM;
|
||||
if (!access_ok(VERIFY_WRITE, unsafe_ptr, size))
|
||||
if (!access_ok(unsafe_ptr, size))
|
||||
return -EPERM;
|
||||
|
||||
return probe_kernel_write(unsafe_ptr, src, size);
|
||||
|
Reference in New Issue
Block a user