Commit 4b8e0729 authored by Jesper Juhl's avatar Jesper Juhl Committed by Linus Torvalds

[PATCH] verify_area cleanup : i386 and misc.

This patch converts verify_area to access_ok in arch/i386, fs/, kernel/ and a
few other bits that didn't fit in the other patches or that I actually was
able to test on my hardware - this is by far the best tested of all the
patches.
Signed-off-by: default avatarJesper Juhl <juhl-lkml@dif.dk>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 6ca2ea5b
......@@ -93,7 +93,7 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
if (act) {
old_sigset_t mask;
if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
if (!access_ok(VERIFY_READ, act, sizeof(*act)) ||
__get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
__get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
return -EFAULT;
......@@ -105,7 +105,7 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
if (!ret && oact) {
if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) ||
__put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
__put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
return -EFAULT;
......@@ -187,7 +187,7 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, int *peax
struct _fpstate __user * buf;
err |= __get_user(buf, &sc->fpstate);
if (buf) {
if (verify_area(VERIFY_READ, buf, sizeof(*buf)))
if (!access_ok(VERIFY_READ, buf, sizeof(*buf)))
goto badframe;
err |= restore_i387(buf);
} else {
......@@ -213,7 +213,7 @@ asmlinkage int sys_sigreturn(unsigned long __unused)
sigset_t set;
int eax;
if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
goto badframe;
if (__get_user(set.sig[0], &frame->sc.oldmask)
|| (_NSIG_WORDS > 1
......@@ -243,7 +243,7 @@ asmlinkage int sys_rt_sigreturn(unsigned long __unused)
sigset_t set;
int eax;
if (verify_area(VERIFY_READ, frame, sizeof(*frame)))
if (!access_ok(VERIFY_READ, frame, sizeof(*frame)))
goto badframe;
if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set)))
goto badframe;
......
......@@ -40,7 +40,7 @@ void Un_impl(void)
unsigned long address = FPU_ORIG_EIP;
RE_ENTRANT_CHECK_OFF;
/* No need to verify_area(), we have previously fetched these bytes. */
/* No need to check access_ok(), we have previously fetched these bytes. */
printk("Unimplemented FPU Opcode at eip=%p : ", (void __user *) address);
if ( FPU_CS == __USER_CS )
{
......@@ -91,7 +91,7 @@ void FPU_printall(void)
unsigned long address = FPU_ORIG_EIP;
RE_ENTRANT_CHECK_OFF;
/* No need to verify_area(), we have previously fetched these bytes. */
/* No need to check access_ok(), we have previously fetched these bytes. */
printk("At %p:", (void *) address);
if ( FPU_CS == __USER_CS )
{
......
......@@ -66,18 +66,18 @@
#define instruction_address (*(struct address *)&I387.soft.fip)
#define operand_address (*(struct address *)&I387.soft.foo)
#define FPU_verify_area(x,y,z) if ( verify_area(x,y,z) ) \
#define FPU_verify_area(x,y,z) if ( !access_ok(x,y,z) ) \
math_abort(FPU_info,SIGSEGV)
#undef FPU_IGNORE_CODE_SEGV
#ifdef FPU_IGNORE_CODE_SEGV
/* verify_area() is very expensive, and causes the emulator to run
/* access_ok() is very expensive, and causes the emulator to run
about 20% slower if applied to the code. Anyway, errors due to bad
code addresses should be much rarer than errors due to bad data
addresses. */
#define FPU_code_verify_area(z)
#else
/* A simpler test than verify_area() can probably be done for
/* A simpler test than access_ok() can probably be done for
FPU_code_verify_area() because the only possible error is to step
past the upper boundary of a legal code area. */
#define FPU_code_verify_area(z) FPU_verify_area(VERIFY_READ,(void __user *)FPU_EIP,z)
......
......@@ -262,9 +262,8 @@ int con_set_trans_old(unsigned char __user * arg)
int i;
unsigned short *p = translations[USER_MAP];
i = verify_area(VERIFY_READ, arg, E_TABSZ);
if (i)
return i;
if (!access_ok(VERIFY_READ, arg, E_TABSZ))
return -EFAULT;
for (i=0; i<E_TABSZ ; i++) {
unsigned char uc;
......@@ -281,9 +280,8 @@ int con_get_trans_old(unsigned char __user * arg)
int i, ch;
unsigned short *p = translations[USER_MAP];
i = verify_area(VERIFY_WRITE, arg, E_TABSZ);
if (i)
return i;
if (!access_ok(VERIFY_WRITE, arg, E_TABSZ))
return -EFAULT;
for (i=0; i<E_TABSZ ; i++)
{
......@@ -298,9 +296,8 @@ int con_set_trans_new(ushort __user * arg)
int i;
unsigned short *p = translations[USER_MAP];
i = verify_area(VERIFY_READ, arg, E_TABSZ*sizeof(unsigned short));
if (i)
return i;
if (!access_ok(VERIFY_READ, arg, E_TABSZ*sizeof(unsigned short)))
return -EFAULT;
for (i=0; i<E_TABSZ ; i++) {
unsigned short us;
......@@ -317,9 +314,8 @@ int con_get_trans_new(ushort __user * arg)
int i;
unsigned short *p = translations[USER_MAP];
i = verify_area(VERIFY_WRITE, arg, E_TABSZ*sizeof(unsigned short));
if (i)
return i;
if (!access_ok(VERIFY_WRITE, arg, E_TABSZ*sizeof(unsigned short)))
return -EFAULT;
for (i=0; i<E_TABSZ ; i++)
__put_user(p[i], arg+i);
......
......@@ -474,7 +474,7 @@ static ssize_t read_port(struct file * file, char __user * buf,
unsigned long i = *ppos;
char __user *tmp = buf;
if (verify_area(VERIFY_WRITE,buf,count))
if (!access_ok(VERIFY_WRITE, buf, count))
return -EFAULT;
while (count-- > 0 && i < 65536) {
if (__put_user(inb(i),tmp) < 0)
......@@ -492,7 +492,7 @@ static ssize_t write_port(struct file * file, const char __user * buf,
unsigned long i = *ppos;
const char __user * tmp = buf;
if (verify_area(VERIFY_READ,buf,count))
if (!access_ok(VERIFY_READ,buf,count))
return -EFAULT;
while (count-- > 0 && i < 65536) {
char c;
......
......@@ -148,14 +148,14 @@ static int aout_core_dump(long signr, struct pt_regs * regs, struct file *file)
/* make sure we actually have a data and stack area to dump */
set_fs(USER_DS);
#ifdef __sparc__
if (verify_area(VERIFY_READ, (void __user *)START_DATA(dump), dump.u_dsize))
if (!access_ok(VERIFY_READ, (void __user *)START_DATA(dump), dump.u_dsize))
dump.u_dsize = 0;
if (verify_area(VERIFY_READ, (void __user *)START_STACK(dump), dump.u_ssize))
if (!access_ok(VERIFY_READ, (void __user *)START_STACK(dump), dump.u_ssize))
dump.u_ssize = 0;
#else
if (verify_area(VERIFY_READ, (void __user *)START_DATA(dump), dump.u_dsize << PAGE_SHIFT))
if (!access_ok(VERIFY_READ, (void __user *)START_DATA(dump), dump.u_dsize << PAGE_SHIFT))
dump.u_dsize = 0;
if (verify_area(VERIFY_READ, (void __user *)START_STACK(dump), dump.u_ssize << PAGE_SHIFT))
if (!access_ok(VERIFY_READ, (void __user *)START_STACK(dump), dump.u_ssize << PAGE_SHIFT))
dump.u_ssize = 0;
#endif
......
......@@ -131,7 +131,7 @@ static int put_compat_statfs(struct compat_statfs __user *ubuf, struct kstatfs *
&& (kbuf->f_ffree & 0xffffffff00000000ULL))
return -EOVERFLOW;
}
if (verify_area(VERIFY_WRITE, ubuf, sizeof(*ubuf)) ||
if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)) ||
__put_user(kbuf->f_type, &ubuf->f_type) ||
__put_user(kbuf->f_bsize, &ubuf->f_bsize) ||
__put_user(kbuf->f_blocks, &ubuf->f_blocks) ||
......@@ -205,7 +205,7 @@ static int put_compat_statfs64(struct compat_statfs64 __user *ubuf, struct kstat
&& (kbuf->f_ffree & 0xffffffff00000000ULL))
return -EOVERFLOW;
}
if (verify_area(VERIFY_WRITE, ubuf, sizeof(*ubuf)) ||
if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)) ||
__put_user(kbuf->f_type, &ubuf->f_type) ||
__put_user(kbuf->f_bsize, &ubuf->f_bsize) ||
__put_user(kbuf->f_blocks, &ubuf->f_blocks) ||
......@@ -1152,7 +1152,7 @@ static ssize_t compat_do_readv_writev(int type, struct file *file,
goto out;
}
ret = -EFAULT;
if (verify_area(VERIFY_READ, uvector, nr_segs*sizeof(*uvector)))
if (!access_ok(VERIFY_READ, uvector, nr_segs*sizeof(*uvector)))
goto out;
/*
......@@ -1537,7 +1537,7 @@ int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
if (ufdset) {
unsigned long odd;
if (verify_area(VERIFY_WRITE, ufdset, nr*sizeof(compat_ulong_t)))
if (!access_ok(VERIFY_WRITE, ufdset, nr*sizeof(compat_ulong_t)))
return -EFAULT;
odd = nr & 1UL;
......@@ -1626,10 +1626,12 @@ compat_sys_select(int n, compat_ulong_t __user *inp, compat_ulong_t __user *outp
if (tvp) {
time_t sec, usec;
if ((ret = verify_area(VERIFY_READ, tvp, sizeof(*tvp)))
|| (ret = __get_user(sec, &tvp->tv_sec))
|| (ret = __get_user(usec, &tvp->tv_usec)))
if (!access_ok(VERIFY_READ, tvp, sizeof(*tvp))
|| __get_user(sec, &tvp->tv_sec)
|| __get_user(usec, &tvp->tv_usec)) {
ret = -EFAULT;
goto out_nofds;
}
ret = -EINVAL;
if (sec < 0 || usec < 0)
......
......@@ -2282,11 +2282,8 @@ static int mtd_rw_oob(unsigned int fd, unsigned int cmd, unsigned long arg)
static long
put_dirent32 (struct dirent *d, struct compat_dirent __user *d32)
{
int ret;
if ((ret = verify_area(VERIFY_WRITE, d32,
sizeof(struct compat_dirent))))
return ret;
if (!access_ok(VERIFY_WRITE, d32, sizeof(struct compat_dirent)))
return -EFAULT;
__put_user(d->d_ino, &d32->d_ino);
__put_user(d->d_off, &d32->d_off);
......@@ -2294,7 +2291,7 @@ put_dirent32 (struct dirent *d, struct compat_dirent __user *d32)
if (__copy_to_user(d32->d_name, d->d_name, d->d_reclen))
return -EFAULT;
return ret;
return 0;
}
static int vfat_ioctl32(unsigned fd, unsigned cmd, unsigned long arg)
......@@ -2345,9 +2342,8 @@ static int get_raw32_request(struct raw_config_request *req, struct raw32_config
{
int ret;
if ((ret = verify_area(VERIFY_READ, user_req,
sizeof(struct raw32_config_request))))
return ret;
if (!access_ok(VERIFY_READ, user_req, sizeof(struct raw32_config_request)))
return -EFAULT;
ret = __get_user(req->raw_minor, &user_req->raw_minor);
ret |= __get_user(req->block_major, &user_req->block_major);
......@@ -2360,9 +2356,8 @@ static int set_raw32_request(struct raw_config_request *req, struct raw32_config
{
int ret;
if ((ret = verify_area(VERIFY_WRITE, user_req,
sizeof(struct raw32_config_request))))
return ret;
if (!access_ok(VERIFY_WRITE, user_req, sizeof(struct raw32_config_request)))
return -EFAULT;
ret = __put_user(req->raw_minor, &user_req->raw_minor);
ret |= __put_user(req->block_major, &user_req->block_major);
......@@ -2434,7 +2429,7 @@ static int serial_struct_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
__u32 udata;
if (cmd == TIOCSSERIAL) {
if (verify_area(VERIFY_READ, ss32, sizeof(SS32)))
if (!access_ok(VERIFY_READ, ss32, sizeof(SS32)))
return -EFAULT;
if (__copy_from_user(&ss, ss32, offsetof(SS32, iomem_base)))
return -EFAULT;
......@@ -2448,7 +2443,7 @@ static int serial_struct_ioctl(unsigned fd, unsigned cmd, unsigned long arg)
err = sys_ioctl(fd,cmd,(unsigned long)(&ss));
set_fs(oldseg);
if (cmd == TIOCGSERIAL && err >= 0) {
if (verify_area(VERIFY_WRITE, ss32, sizeof(SS32)))
if (!access_ok(VERIFY_WRITE, ss32, sizeof(SS32)))
return -EFAULT;
if (__copy_to_user(ss32,&ss,offsetof(SS32,iomem_base)))
return -EFAULT;
......@@ -2625,11 +2620,11 @@ static int do_i2c_smbus_ioctl(unsigned int fd, unsigned int cmd, unsigned long a
tdata = compat_alloc_user_space(sizeof(*tdata));
if (tdata == NULL)
return -ENOMEM;
if (verify_area(VERIFY_WRITE, tdata, sizeof(*tdata)))
if (!access_ok(VERIFY_WRITE, tdata, sizeof(*tdata)))
return -EFAULT;
udata = compat_ptr(arg);
if (verify_area(VERIFY_READ, udata, sizeof(*udata)))
if (!access_ok(VERIFY_READ, udata, sizeof(*udata)))
return -EFAULT;
if (__copy_in_user(&tdata->read_write, &udata->read_write, 2 * sizeof(u8)))
......@@ -2666,7 +2661,7 @@ static int do_wireless_ioctl(unsigned int fd, unsigned int cmd, unsigned long ar
iwp = &iwr->u.data;
if (verify_area(VERIFY_WRITE, iwr, sizeof(*iwr)))
if (!access_ok(VERIFY_WRITE, iwr, sizeof(*iwr)))
return -EFAULT;
if (__copy_in_user(&iwr->ifr_ifrn.ifrn_name[0],
......
......@@ -640,8 +640,10 @@ asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events,
return -EINVAL;
/* Verify that the area passed by the user is writeable */
if ((error = verify_area(VERIFY_WRITE, events, maxevents * sizeof(struct epoll_event))))
if (!access_ok(VERIFY_WRITE, events, maxevents * sizeof(struct epoll_event))) {
error = -EFAULT;
goto eexit_1;
}
/* Get the "struct file *" for the eventpoll file */
error = -EBADF;
......
......@@ -302,10 +302,12 @@ sys_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp, s
if (tvp) {
time_t sec, usec;
if ((ret = verify_area(VERIFY_READ, tvp, sizeof(*tvp)))
|| (ret = __get_user(sec, &tvp->tv_sec))
|| (ret = __get_user(usec, &tvp->tv_usec)))
if (!access_ok(VERIFY_READ, tvp, sizeof(*tvp))
|| __get_user(sec, &tvp->tv_sec)
|| __get_user(usec, &tvp->tv_usec)) {
ret = -EFAULT;
goto out_nofds;
}
ret = -EINVAL;
if (sec < 0 || usec < 0)
......
......@@ -71,13 +71,9 @@ static inline
int get_fd_set(unsigned long nr, void __user *ufdset, unsigned long *fdset)
{
nr = FDS_BYTES(nr);
if (ufdset) {
int error;
error = verify_area(VERIFY_WRITE, ufdset, nr);
if (!error && __copy_from_user(fdset, ufdset, nr))
error = -EFAULT;
return error;
}
if (ufdset)
return copy_from_user(fdset, ufdset, nr) ? -EFAULT : 0;
memset(fdset, 0, nr);
return 0;
}
......
......@@ -30,7 +30,7 @@ static inline
unsigned int csum_and_copy_from_user (const unsigned char __user *src, unsigned char *dst,
int len, int sum, int *err_ptr)
{
if (verify_area(VERIFY_READ, src, len) == 0)
if (access_ok(VERIFY_READ, src, len))
return csum_partial_copy_from_user(src, dst, len, sum, err_ptr);
if (len)
......
......@@ -25,7 +25,7 @@ struct compat_mq_attr {
static inline int get_compat_mq_attr(struct mq_attr *attr,
const struct compat_mq_attr __user *uattr)
{
if (verify_area(VERIFY_READ, uattr, sizeof *uattr))
if (!access_ok(VERIFY_READ, uattr, sizeof *uattr))
return -EFAULT;
return __get_user(attr->mq_flags, &uattr->mq_flags)
......
......@@ -27,14 +27,14 @@
int get_compat_timespec(struct timespec *ts, const struct compat_timespec __user *cts)
{
return (verify_area(VERIFY_READ, cts, sizeof(*cts)) ||
return (!access_ok(VERIFY_READ, cts, sizeof(*cts)) ||
__get_user(ts->tv_sec, &cts->tv_sec) ||
__get_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
}
int put_compat_timespec(const struct timespec *ts, struct compat_timespec __user *cts)
{
return (verify_area(VERIFY_WRITE, cts, sizeof(*cts)) ||
return (!access_ok(VERIFY_WRITE, cts, sizeof(*cts)) ||
__put_user(ts->tv_sec, &cts->tv_sec) ||
__put_user(ts->tv_nsec, &cts->tv_nsec)) ? -EFAULT : 0;
}
......@@ -664,7 +664,7 @@ long compat_get_bitmap(unsigned long *mask, compat_ulong_t __user *umask,
/* align bitmap up to nearest compat_long_t boundary */
bitmap_size = ALIGN(bitmap_size, BITS_PER_COMPAT_LONG);
if (verify_area(VERIFY_READ, umask, bitmap_size / 8))
if (!access_ok(VERIFY_READ, umask, bitmap_size / 8))
return -EFAULT;
nr_compat_longs = BITS_TO_COMPAT_LONGS(bitmap_size);
......@@ -705,7 +705,7 @@ long compat_put_bitmap(compat_ulong_t __user *umask, unsigned long *mask,
/* align bitmap up to nearest compat_long_t boundary */
bitmap_size = ALIGN(bitmap_size, BITS_PER_COMPAT_LONG);
if (verify_area(VERIFY_WRITE, umask, bitmap_size / 8))
if (!access_ok(VERIFY_WRITE, umask, bitmap_size / 8))
return -EFAULT;
nr_compat_longs = BITS_TO_COMPAT_LONGS(bitmap_size);
......
......@@ -269,9 +269,10 @@ int do_syslog(int type, char __user * buf, int len)
error = 0;
if (!len)
goto out;
error = verify_area(VERIFY_WRITE,buf,len);
if (error)
if (!access_ok(VERIFY_WRITE, buf, len)) {
error = -EFAULT;
goto out;
}
error = wait_event_interruptible(log_wait, (log_start - log_end));
if (error)
goto out;
......@@ -301,9 +302,10 @@ int do_syslog(int type, char __user * buf, int len)
error = 0;
if (!len)
goto out;
error = verify_area(VERIFY_WRITE,buf,len);
if (error)
if (!access_ok(VERIFY_WRITE, buf, len)) {
error = -EFAULT;
goto out;
}
count = len;
if (count > log_buf_len)
count = log_buf_len;
......
......@@ -2449,7 +2449,7 @@ do_sigaltstack (const stack_t __user *uss, stack_t __user *uoss, unsigned long s
int ss_flags;
error = -EFAULT;
if (verify_area(VERIFY_READ, uss, sizeof(*uss))
if (!access_ok(VERIFY_READ, uss, sizeof(*uss))
|| __get_user(ss_sp, &uss->ss_sp)
|| __get_user(ss_flags, &uss->ss_flags)
|| __get_user(ss_size, &uss->ss_size))
......
......@@ -437,8 +437,8 @@ static int econet_sendmsg(struct kiocb *iocb, struct socket *sock,
void __user *base = msg->msg_iov[i].iov_base;
size_t len = msg->msg_iov[i].iov_len;
/* Check it now since we switch to KERNEL_DS later. */
if ((err = verify_area(VERIFY_READ, base, len)) < 0)
return err;
if (!access_ok(VERIFY_READ, base, len))
return -EFAULT;
iov[i+1].iov_base = base;
iov[i+1].iov_len = len;
size += len;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment