Commit 1c91d2c6 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'misc.alpha' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull alpha user access updates from Al Viro:
 "Several alpha osf_sys.c uaccess cleanups - getdomainname() had insane
  byte-by-byte copying of string to userland (instead of strnlen +
  copy_to_user) plus yet another compat variant of timeval/itimerval
  with associated copyin/copyout primitives"

* 'misc.alpha' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  osf_sigstack(): switch to put_user()
  osf_sys.c: switch handling of timeval32/itimerval32 to copy_{to,from}_user()
  osf_getdomainname(): use copy_to_user()
parents c8568639 8d2fd30e
...@@ -564,25 +564,20 @@ SYSCALL_DEFINE0(getdtablesize) ...@@ -564,25 +564,20 @@ SYSCALL_DEFINE0(getdtablesize)
*/ */
SYSCALL_DEFINE2(osf_getdomainname, char __user *, name, int, namelen) SYSCALL_DEFINE2(osf_getdomainname, char __user *, name, int, namelen)
{ {
unsigned len; int len, err = 0;
int i; char *kname;
if (!access_ok(VERIFY_WRITE, name, namelen)) if (namelen > 32)
return -EFAULT; namelen = 32;
len = namelen;
if (len > 32)
len = 32;
down_read(&uts_sem); down_read(&uts_sem);
for (i = 0; i < len; ++i) { kname = utsname()->domainname;
__put_user(utsname()->domainname[i], name + i); len = strnlen(kname, namelen);
if (utsname()->domainname[i] == '\0') if (copy_to_user(name, kname, min(len + 1, namelen)))
break; err = -EFAULT;
}
up_read(&uts_sem); up_read(&uts_sem);
return 0; return err;
} }
/* /*
...@@ -718,9 +713,8 @@ SYSCALL_DEFINE2(osf_sigstack, struct sigstack __user *, uss, ...@@ -718,9 +713,8 @@ SYSCALL_DEFINE2(osf_sigstack, struct sigstack __user *, uss,
if (uoss) { if (uoss) {
error = -EFAULT; error = -EFAULT;
if (! access_ok(VERIFY_WRITE, uoss, sizeof(*uoss)) if (put_user(oss_sp, &uoss->ss_sp) ||
|| __put_user(oss_sp, &uoss->ss_sp) put_user(oss_os, &uoss->ss_onstack))
|| __put_user(oss_os, &uoss->ss_onstack))
goto out; goto out;
} }
...@@ -957,37 +951,45 @@ struct itimerval32 ...@@ -957,37 +951,45 @@ struct itimerval32
static inline long static inline long
get_tv32(struct timeval *o, struct timeval32 __user *i) get_tv32(struct timeval *o, struct timeval32 __user *i)
{ {
return (!access_ok(VERIFY_READ, i, sizeof(*i)) || struct timeval32 tv;
(__get_user(o->tv_sec, &i->tv_sec) | if (copy_from_user(&tv, i, sizeof(struct timeval32)))
__get_user(o->tv_usec, &i->tv_usec))); return -EFAULT;
o->tv_sec = tv.tv_sec;
o->tv_usec = tv.tv_usec;
return 0;
} }
static inline long static inline long
put_tv32(struct timeval32 __user *o, struct timeval *i) put_tv32(struct timeval32 __user *o, struct timeval *i)
{ {
return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || return copy_to_user(o, &(struct timeval32){
(__put_user(i->tv_sec, &o->tv_sec) | .tv_sec = o->tv_sec,
__put_user(i->tv_usec, &o->tv_usec))); .tv_usec = o->tv_usec},
sizeof(struct timeval32));
} }
static inline long static inline long
get_it32(struct itimerval *o, struct itimerval32 __user *i) get_it32(struct itimerval *o, struct itimerval32 __user *i)
{ {
return (!access_ok(VERIFY_READ, i, sizeof(*i)) || struct itimerval32 itv;
(__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) | if (copy_from_user(&itv, i, sizeof(struct itimerval32)))
__get_user(o->it_interval.tv_usec, &i->it_interval.tv_usec) | return -EFAULT;
__get_user(o->it_value.tv_sec, &i->it_value.tv_sec) | o->it_interval.tv_sec = itv.it_interval.tv_sec;
__get_user(o->it_value.tv_usec, &i->it_value.tv_usec))); o->it_interval.tv_usec = itv.it_interval.tv_usec;
o->it_value.tv_sec = itv.it_value.tv_sec;
o->it_value.tv_usec = itv.it_value.tv_usec;
return 0;
} }
static inline long static inline long
put_it32(struct itimerval32 __user *o, struct itimerval *i) put_it32(struct itimerval32 __user *o, struct itimerval *i)
{ {
return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) || return copy_to_user(o, &(struct itimerval32){
(__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) | .it_interval.tv_sec = o->it_interval.tv_sec,
__put_user(i->it_interval.tv_usec, &o->it_interval.tv_usec) | .it_interval.tv_usec = o->it_interval.tv_usec,
__put_user(i->it_value.tv_sec, &o->it_value.tv_sec) | .it_value.tv_sec = o->it_value.tv_sec,
__put_user(i->it_value.tv_usec, &o->it_value.tv_usec))); .it_value.tv_usec = o->it_value.tv_usec},
sizeof(struct itimerval32));
} }
static inline void static inline void
...@@ -1106,20 +1108,17 @@ SYSCALL_DEFINE5(osf_select, int, n, fd_set __user *, inp, fd_set __user *, outp, ...@@ -1106,20 +1108,17 @@ SYSCALL_DEFINE5(osf_select, int, n, fd_set __user *, inp, fd_set __user *, outp,
{ {
struct timespec end_time, *to = NULL; struct timespec end_time, *to = NULL;
if (tvp) { if (tvp) {
time_t sec, usec; struct timeval tv;
to = &end_time; to = &end_time;
if (!access_ok(VERIFY_READ, tvp, sizeof(*tvp)) if (get_tv32(&tv, tvp))
|| __get_user(sec, &tvp->tv_sec)
|| __get_user(usec, &tvp->tv_usec)) {
return -EFAULT; return -EFAULT;
}
if (sec < 0 || usec < 0) if (tv.tv_sec < 0 || tv.tv_usec < 0)
return -EINVAL; return -EINVAL;
if (poll_select_set_timeout(to, sec, usec * NSEC_PER_USEC)) if (poll_select_set_timeout(to, tv.tv_sec,
tv.tv_usec * NSEC_PER_USEC))
return -EINVAL; return -EINVAL;
} }
......
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