X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fx86_64%2Fia32%2Fsys_ia32.c;h=c8300c902d1c9f38b95c1dff9cc8cc5f59c9a533;hb=97bf2856c6014879bd04983a3e9dfcdac1e7fe85;hp=267a4a8e91c8f104490802b6f51d8f36024bf266;hpb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;p=linux-2.6.git diff --git a/arch/x86_64/ia32/sys_ia32.c b/arch/x86_64/ia32/sys_ia32.c index 267a4a8e9..c8300c902 100644 --- a/arch/x86_64/ia32/sys_ia32.c +++ b/arch/x86_64/ia32/sys_ia32.c @@ -20,7 +20,6 @@ * This should be fixed. */ -#include #include #include #include @@ -30,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -61,11 +59,12 @@ #include #include #include +#include +#include #include #include #include #include -#include #include #include @@ -73,13 +72,12 @@ #include #include -#define A(__x) ((unsigned long)(__x)) #define AA(__x) ((unsigned long)(__x)) -#define ROUND_UP(x,a) ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1))) -#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de))) int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf) { + compat_ino_t ino; + typeof(ubuf->st_uid) uid = 0; typeof(ubuf->st_gid) gid = 0; SET_UID(uid, kbuf->uid); @@ -88,9 +86,12 @@ int cp_compat_stat(struct kstat *kbuf, struct compat_stat __user *ubuf) return -EOVERFLOW; if (kbuf->size >= 0x7fffffff) return -EOVERFLOW; - if (verify_area(VERIFY_WRITE, ubuf, sizeof(struct compat_stat)) || + ino = kbuf->ino; + if (sizeof(ino) < sizeof(kbuf->ino) && ino != kbuf->ino) + return -EOVERFLOW; + if (!access_ok(VERIFY_WRITE, ubuf, sizeof(struct compat_stat)) || __put_user (old_encode_dev(kbuf->dev), &ubuf->st_dev) || - __put_user (kbuf->ino, &ubuf->st_ino) || + __put_user (ino, &ubuf->st_ino) || __put_user (kbuf->mode, &ubuf->st_mode) || __put_user (kbuf->nlink, &ubuf->st_nlink) || __put_user (uid, &ubuf->st_uid) || @@ -131,7 +132,7 @@ cp_stat64(struct stat64 __user *ubuf, struct kstat *stat) typeof(ubuf->st_gid) gid = 0; SET_UID(uid, stat->uid); SET_GID(gid, stat->gid); - if (verify_area(VERIFY_WRITE, ubuf, sizeof(struct stat64)) || + if (!access_ok(VERIFY_WRITE, ubuf, sizeof(struct stat64)) || __put_user(huge_encode_dev(stat->dev), &ubuf->st_dev) || __put_user (stat->ino, &ubuf->__st_ino) || __put_user (stat->ino, &ubuf->st_ino) || @@ -183,6 +184,28 @@ sys32_fstat64(unsigned int fd, struct stat64 __user *statbuf) return ret; } +asmlinkage long +sys32_fstatat(unsigned int dfd, char __user *filename, + struct stat64 __user* statbuf, int flag) +{ + struct kstat stat; + int error = -EINVAL; + + if ((flag & ~AT_SYMLINK_NOFOLLOW) != 0) + goto out; + + if (flag & AT_SYMLINK_NOFOLLOW) + error = vfs_lstat_fd(dfd, filename, &stat); + else + error = vfs_stat_fd(dfd, filename, &stat); + + if (!error) + error = cp_stat64(statbuf, &stat); + +out: + return error; +} + /* * Linux/i386 didn't use to be able to handle more than * 4 system call parameters, so these system calls used a memory @@ -218,9 +241,6 @@ sys32_mmap(struct mmap_arg_struct __user *arg) return -EBADF; } - if (a.prot & PROT_READ) - a.prot |= vm_force_exec32; - mm = current->mm; down_write(&mm->mmap_sem); retval = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, a.offset>>PAGE_SHIFT); @@ -235,8 +255,6 @@ sys32_mmap(struct mmap_arg_struct __user *arg) asmlinkage long sys32_mprotect(unsigned long start, size_t len, unsigned long prot) { - if (prot & PROT_READ) - prot |= vm_force_exec32; return sys_mprotect(start,len,prot); } @@ -270,7 +288,7 @@ sys32_rt_sigaction(int sig, struct sigaction32 __user *act, if (act) { compat_uptr_t handler, restorer; - if (verify_area(VERIFY_READ, act, sizeof(*act)) || + if (!access_ok(VERIFY_READ, act, sizeof(*act)) || __get_user(handler, &act->sa_handler) || __get_user(new_ka.sa.sa_flags, &act->sa_flags) || __get_user(restorer, &act->sa_restorer)|| @@ -309,9 +327,9 @@ sys32_rt_sigaction(int sig, struct sigaction32 __user *act, set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32); set32.sig[0] = old_ka.sa.sa_mask.sig[0]; } - if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) || - __put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) || - __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer) || + if (!access_ok(VERIFY_WRITE, 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), &oact->sa_restorer) || __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || __copy_to_user(&oact->sa_mask, &set32, sizeof(compat_sigset_t))) return -EFAULT; @@ -330,7 +348,7 @@ sys32_sigaction (int sig, struct old_sigaction32 __user *act, struct old_sigacti compat_old_sigset_t mask; compat_uptr_t handler, restorer; - if (verify_area(VERIFY_READ, act, sizeof(*act)) || + if (!access_ok(VERIFY_READ, act, sizeof(*act)) || __get_user(handler, &act->sa_handler) || __get_user(new_ka.sa.sa_flags, &act->sa_flags) || __get_user(restorer, &act->sa_restorer) || @@ -346,9 +364,9 @@ sys32_sigaction (int sig, struct old_sigaction32 __user *act, struct old_sigacti ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); if (!ret && oact) { - if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) || - __put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) || - __put_user((long)old_ka.sa.sa_restorer, &oact->sa_restorer) || + if (!access_ok(VERIFY_WRITE, 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), &oact->sa_restorer) || __put_user(old_ka.sa.sa_flags, &oact->sa_flags) || __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask)) return -EFAULT; @@ -377,7 +395,9 @@ sys32_rt_sigprocmask(int how, compat_sigset_t __user *set, } } set_fs (KERNEL_DS); - ret = sys_rt_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL, + ret = sys_rt_sigprocmask(how, + set ? (sigset_t __user *)&s : NULL, + oset ? (sigset_t __user *)&s : NULL, sigsetsize); set_fs (old_fs); if (ret) return ret; @@ -416,24 +436,12 @@ put_tv32(struct compat_timeval __user *o, struct timeval *i) return err; } -extern int do_setitimer(int which, struct itimerval *, struct itimerval *); +extern unsigned int alarm_setitimer(unsigned int seconds); asmlinkage long sys32_alarm(unsigned int seconds) { - struct itimerval it_new, it_old; - unsigned int oldalarm; - - it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0; - it_new.it_value.tv_sec = seconds; - it_new.it_value.tv_usec = 0; - do_setitimer(ITIMER_REAL, &it_new, &it_old); - oldalarm = it_old.it_value.tv_sec; - /* ehhh.. We can't return 0 if we have an alarm pending.. */ - /* And we'd better return too much than too little anyway */ - if (it_old.it_value.tv_usec) - oldalarm++; - return oldalarm; + return alarm_setitimer(seconds); } /* Translations due to time_t size differences. Which affects all @@ -446,7 +454,7 @@ sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) { if (tv) { struct timeval ktv; - do_gettimeofday(&ktv); + vx_gettimeofday(&ktv); if (put_tv32(tv, &ktv)) return -EFAULT; } @@ -478,134 +486,6 @@ sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); } -struct linux32_dirent { - u32 d_ino; - u32 d_off; - u16 d_reclen; - char d_name[1]; -}; - -struct old_linux32_dirent { - u32 d_ino; - u32 d_offset; - u16 d_namlen; - char d_name[1]; -}; - -struct getdents32_callback { - struct linux32_dirent __user * current_dir; - struct linux32_dirent __user * previous; - int count; - int error; -}; - -struct readdir32_callback { - struct old_linux32_dirent __user * dirent; - int count; -}; - -static int -filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino, - unsigned int d_type) -{ - struct linux32_dirent __user * dirent; - struct getdents32_callback * buf = (struct getdents32_callback *) __buf; - int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 2, 4); - - buf->error = -EINVAL; /* only used if we fail.. */ - if (reclen > buf->count) - return -EINVAL; - dirent = buf->previous; - if (dirent) - put_user(offset, &dirent->d_off); - dirent = buf->current_dir; - buf->previous = dirent; - put_user(ino, &dirent->d_ino); - put_user(reclen, &dirent->d_reclen); - copy_to_user(dirent->d_name, name, namlen); - put_user(0, dirent->d_name + namlen); - put_user(d_type, (char __user *)dirent + reclen - 1); - dirent = ((void __user *)dirent) + reclen; - buf->current_dir = dirent; - buf->count -= reclen; - return 0; -} - -asmlinkage long -sys32_getdents (unsigned int fd, void __user * dirent, unsigned int count) -{ - struct file * file; - struct linux32_dirent __user * lastdirent; - struct getdents32_callback buf; - int error; - - error = -EBADF; - file = fget(fd); - if (!file) - goto out; - - buf.current_dir = (struct linux32_dirent __user *) dirent; - buf.previous = NULL; - buf.count = count; - buf.error = 0; - - error = vfs_readdir(file, filldir32, &buf); - if (error < 0) - goto out_putf; - error = buf.error; - lastdirent = buf.previous; - if (lastdirent) { - put_user(file->f_pos, &lastdirent->d_off); - error = count - buf.count; - } - -out_putf: - fput(file); -out: - return error; -} - -static int -fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino, unsigned d_type) -{ - struct readdir32_callback * buf = (struct readdir32_callback *) __buf; - struct old_linux32_dirent __user * dirent; - - if (buf->count) - return -EINVAL; - buf->count++; - dirent = buf->dirent; - put_user(ino, &dirent->d_ino); - put_user(offset, &dirent->d_offset); - put_user(namlen, &dirent->d_namlen); - copy_to_user(dirent->d_name, name, namlen); - put_user(0, dirent->d_name + namlen); - return 0; -} - -asmlinkage long -sys32_oldreaddir (unsigned int fd, void __user * dirent, unsigned int count) -{ - int error; - struct file * file; - struct readdir32_callback buf; - - error = -EBADF; - file = fget(fd); - if (!file) - goto out; - - buf.count = 0; - buf.dirent = dirent; - - error = vfs_readdir(file, fillonedir32, &buf); - if (error >= 0) - error = buf.count; - fput(file); -out: - return error; -} - struct sel_arg_struct { unsigned int n; unsigned int inp; @@ -625,26 +505,6 @@ sys32_old_select(struct sel_arg_struct __user *arg) compat_ptr(a.exp), compat_ptr(a.tvp)); } -/* - * sys_time() can be implemented in user-level using - * sys_gettimeofday(). x86-64 did this but i386 Linux did not - * so we have to implement this system call here. - */ -asmlinkage long sys32_time(int __user * tloc) -{ - int i; - struct timeval tv; - - do_gettimeofday(&tv); - i = tv.tv_sec; - - if (tloc) { - if (put_user(i,tloc)) - i = -EFAULT; - } - return i; -} - extern asmlinkage long compat_sys_wait4(compat_pid_t pid, compat_uint_t * stat_addr, int options, struct compat_rusage *ru); @@ -655,18 +515,6 @@ sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr, int options) return compat_sys_wait4(pid, stat_addr, options, NULL); } -int sys32_ni_syscall(int call) -{ - struct task_struct *me = current; - static char lastcomm[8]; - if (strcmp(lastcomm, me->comm)) { - printk(KERN_INFO "IA32 syscall %d from %s not implemented\n", call, - current->comm); - strcpy(lastcomm, me->comm); - } - return -ENOSYS; -} - /* 32-bit timeval and related flotsam. */ asmlinkage long @@ -701,7 +549,7 @@ sys32_sysinfo(struct sysinfo32 __user *info) int bitcount = 0; set_fs (KERNEL_DS); - ret = sys_sysinfo(&s); + ret = sys_sysinfo((struct sysinfo __user *)&s); set_fs (old_fs); /* Check to see if any memory value is too large for 32-bit and scale @@ -722,7 +570,7 @@ sys32_sysinfo(struct sysinfo32 __user *info) s.freehigh >>= bitcount; } - if (verify_area(VERIFY_WRITE, info, sizeof(struct sysinfo32)) || + if (!access_ok(VERIFY_WRITE, info, sizeof(struct sysinfo32)) || __put_user (s.uptime, &info->uptime) || __put_user (s.loads[0], &info->loads[0]) || __put_user (s.loads[1], &info->loads[1]) || @@ -749,7 +597,7 @@ sys32_sched_rr_get_interval(compat_pid_t pid, struct compat_timespec __user *int mm_segment_t old_fs = get_fs (); set_fs (KERNEL_DS); - ret = sys_sched_rr_get_interval(pid, &t); + ret = sys_sched_rr_get_interval(pid, (struct timespec __user *)&t); set_fs (old_fs); if (put_compat_timespec(&t, interval)) return -EFAULT; @@ -765,7 +613,7 @@ sys32_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize) mm_segment_t old_fs = get_fs(); set_fs (KERNEL_DS); - ret = sys_rt_sigpending(&s, sigsetsize); + ret = sys_rt_sigpending((sigset_t __user *)&s, sigsetsize); set_fs (old_fs); if (!ret) { switch (_NSIG_WORDS) { @@ -780,56 +628,17 @@ sys32_rt_sigpending(compat_sigset_t __user *set, compat_size_t sigsetsize) return ret; } - asmlinkage long -sys32_rt_sigtimedwait(compat_sigset_t __user *uthese, siginfo_t32 __user *uinfo, - struct compat_timespec __user *uts, compat_size_t sigsetsize) -{ - sigset_t s; - compat_sigset_t s32; - struct timespec t; - int ret; - mm_segment_t old_fs = get_fs(); - siginfo_t info; - - if (copy_from_user (&s32, uthese, sizeof(compat_sigset_t))) - return -EFAULT; - switch (_NSIG_WORDS) { - case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32); - case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32); - case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32); - case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32); - } - if (uts && get_compat_timespec(&t, uts)) - return -EFAULT; - if (uinfo) { - /* stop data leak to user space in case of structure fill mismatch - * between sys_rt_sigtimedwait & ia32_copy_siginfo_to_user. - */ - memset(&info, 0, sizeof(info)); - } - set_fs (KERNEL_DS); - ret = sys_rt_sigtimedwait(&s, uinfo ? &info : NULL, uts ? &t : NULL, - sigsetsize); - set_fs (old_fs); - if (ret >= 0 && uinfo) { - if (ia32_copy_siginfo_to_user(uinfo, &info)) - return -EFAULT; - } - return ret; -} - -asmlinkage long -sys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 __user *uinfo) +sys32_rt_sigqueueinfo(int pid, int sig, compat_siginfo_t __user *uinfo) { siginfo_t info; int ret; mm_segment_t old_fs = get_fs(); - if (ia32_copy_siginfo_from_user(&info, uinfo)) + if (copy_siginfo_from_user32(&info, uinfo)) return -EFAULT; set_fs (KERNEL_DS); - ret = sys_rt_sigqueueinfo(pid, sig, &info); + ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *)&info); set_fs (old_fs); return ret; } @@ -844,6 +653,7 @@ sys32_pause(void) } +#ifdef CONFIG_SYSCTL_SYSCALL struct sysctl_ia32 { unsigned int name; int nlen; @@ -858,18 +668,12 @@ struct sysctl_ia32 { asmlinkage long sys32_sysctl(struct sysctl_ia32 __user *args32) { -#ifndef CONFIG_SYSCTL - return -ENOSYS; -#else struct sysctl_ia32 a32; mm_segment_t old_fs = get_fs (); - void *oldvalp, *newvalp; + void __user *oldvalp, *newvalp; size_t oldlen; - int *namep; + int __user *namep; long ret; - extern int do_sysctl(int *name, int nlen, void *oldval, size_t *oldlenp, - void *newval, size_t newlen); - if (copy_from_user(&a32, args32, sizeof (a32))) return -EFAULT; @@ -881,9 +685,9 @@ sys32_sysctl(struct sysctl_ia32 __user *args32) * addresses, we KNOW that access_ok() will always succeed, so this is an * expensive NOP, but so what... */ - namep = (int *) A(a32.name); - oldvalp = (void *) A(a32.oldval); - newvalp = (void *) A(a32.newval); + namep = compat_ptr(a32.name); + oldvalp = compat_ptr(a32.oldval); + newvalp = compat_ptr(a32.newval); if ((oldvalp && get_user(oldlen, (int __user *)compat_ptr(a32.oldlenp))) || !access_ok(VERIFY_WRITE, namep, 0) @@ -893,7 +697,8 @@ sys32_sysctl(struct sysctl_ia32 __user *args32) set_fs(KERNEL_DS); lock_kernel(); - ret = do_sysctl(namep, a32.nlen, oldvalp, &oldlen, newvalp, (size_t) a32.newlen); + ret = do_sysctl(namep, a32.nlen, oldvalp, (size_t __user *)&oldlen, + newvalp, (size_t) a32.newlen); unlock_kernel(); set_fs(old_fs); @@ -901,8 +706,8 @@ sys32_sysctl(struct sysctl_ia32 __user *args32) return -EFAULT; return ret; -#endif } +#endif /* warning: next two assume little endian */ asmlinkage long @@ -944,91 +749,16 @@ sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, s32 count) return -EFAULT; set_fs(KERNEL_DS); - ret = sys_sendfile(out_fd, in_fd, offset ? &of : NULL, count); + ret = sys_sendfile(out_fd, in_fd, offset ? (off_t __user *)&of : NULL, + count); set_fs(old_fs); - if (!ret && offset && put_user(of, offset)) + if (offset && put_user(of, offset)) return -EFAULT; return ret; } -/* Handle adjtimex compatibility. */ - -struct timex32 { - u32 modes; - s32 offset, freq, maxerror, esterror; - s32 status, constant, precision, tolerance; - struct compat_timeval time; - s32 tick; - s32 ppsfreq, jitter, shift, stabil; - s32 jitcnt, calcnt, errcnt, stbcnt; - s32 :32; s32 :32; s32 :32; s32 :32; - s32 :32; s32 :32; s32 :32; s32 :32; - s32 :32; s32 :32; s32 :32; s32 :32; -}; - -extern int do_adjtimex(struct timex *); - -asmlinkage long -sys32_adjtimex(struct timex32 __user *utp) -{ - struct timex txc; - int ret; - - memset(&txc, 0, sizeof(struct timex)); - - if(verify_area(VERIFY_READ, utp, sizeof(struct timex32)) || - __get_user(txc.modes, &utp->modes) || - __get_user(txc.offset, &utp->offset) || - __get_user(txc.freq, &utp->freq) || - __get_user(txc.maxerror, &utp->maxerror) || - __get_user(txc.esterror, &utp->esterror) || - __get_user(txc.status, &utp->status) || - __get_user(txc.constant, &utp->constant) || - __get_user(txc.precision, &utp->precision) || - __get_user(txc.tolerance, &utp->tolerance) || - __get_user(txc.time.tv_sec, &utp->time.tv_sec) || - __get_user(txc.time.tv_usec, &utp->time.tv_usec) || - __get_user(txc.tick, &utp->tick) || - __get_user(txc.ppsfreq, &utp->ppsfreq) || - __get_user(txc.jitter, &utp->jitter) || - __get_user(txc.shift, &utp->shift) || - __get_user(txc.stabil, &utp->stabil) || - __get_user(txc.jitcnt, &utp->jitcnt) || - __get_user(txc.calcnt, &utp->calcnt) || - __get_user(txc.errcnt, &utp->errcnt) || - __get_user(txc.stbcnt, &utp->stbcnt)) - return -EFAULT; - - ret = do_adjtimex(&txc); - - if(verify_area(VERIFY_WRITE, utp, sizeof(struct timex32)) || - __put_user(txc.modes, &utp->modes) || - __put_user(txc.offset, &utp->offset) || - __put_user(txc.freq, &utp->freq) || - __put_user(txc.maxerror, &utp->maxerror) || - __put_user(txc.esterror, &utp->esterror) || - __put_user(txc.status, &utp->status) || - __put_user(txc.constant, &utp->constant) || - __put_user(txc.precision, &utp->precision) || - __put_user(txc.tolerance, &utp->tolerance) || - __put_user(txc.time.tv_sec, &utp->time.tv_sec) || - __put_user(txc.time.tv_usec, &utp->time.tv_usec) || - __put_user(txc.tick, &utp->tick) || - __put_user(txc.ppsfreq, &utp->ppsfreq) || - __put_user(txc.jitter, &utp->jitter) || - __put_user(txc.shift, &utp->shift) || - __put_user(txc.stabil, &utp->stabil) || - __put_user(txc.jitcnt, &utp->jitcnt) || - __put_user(txc.calcnt, &utp->calcnt) || - __put_user(txc.errcnt, &utp->errcnt) || - __put_user(txc.stbcnt, &utp->stbcnt)) - ret = -EFAULT; - - return ret; -} - asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len, unsigned long prot, unsigned long flags, unsigned long fd, unsigned long pgoff) @@ -1044,9 +774,6 @@ asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len, return -EBADF; } - if (prot & PROT_READ) - prot |= vm_force_exec32; - down_write(&mm->mmap_sem); error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); up_write(&mm->mmap_sem); @@ -1058,38 +785,40 @@ asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len, asmlinkage long sys32_olduname(struct oldold_utsname __user * name) { - int error; - struct new_utsname *ptr; + int err; if (!name) return -EFAULT; - if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) + if (!access_ok(VERIFY_WRITE, name, sizeof(struct oldold_utsname))) return -EFAULT; down_read(&uts_sem); - - ptr = vx_new_utsname(); - error = __copy_to_user(&name->sysname,ptr->sysname,__OLD_UTS_LEN); - __put_user(0,name->sysname+__OLD_UTS_LEN); - __copy_to_user(&name->nodename,ptr->nodename,__OLD_UTS_LEN); - __put_user(0,name->nodename+__OLD_UTS_LEN); - __copy_to_user(&name->release,ptr->release,__OLD_UTS_LEN); - __put_user(0,name->release+__OLD_UTS_LEN); - __copy_to_user(&name->version,ptr->version,__OLD_UTS_LEN); - __put_user(0,name->version+__OLD_UTS_LEN); - { - char *arch = "x86_64"; - if (personality(current->personality) == PER_LINUX32) - arch = "i686"; + + err = __copy_to_user(&name->sysname,&utsname()->sysname, + __OLD_UTS_LEN); + err |= __put_user(0,name->sysname+__OLD_UTS_LEN); + err |= __copy_to_user(&name->nodename,&utsname()->nodename, + __OLD_UTS_LEN); + err |= __put_user(0,name->nodename+__OLD_UTS_LEN); + err |= __copy_to_user(&name->release,&utsname()->release, + __OLD_UTS_LEN); + err |= __put_user(0,name->release+__OLD_UTS_LEN); + err |= __copy_to_user(&name->version,&utsname()->version, + __OLD_UTS_LEN); + err |= __put_user(0,name->version+__OLD_UTS_LEN); + { + char *arch = "x86_64"; + if (personality(current->personality) == PER_LINUX32) + arch = "i686"; - __copy_to_user(&name->machine,arch,strlen(arch)+1); - } - - up_read(&uts_sem); - - error = error ? -EFAULT : 0; - - return error; + err |= __copy_to_user(&name->machine, arch, strlen(arch)+1); + } + + up_read(&uts_sem); + + err = err ? -EFAULT : 0; + + return err; } long sys32_uname(struct old_utsname __user * name) @@ -1098,7 +827,7 @@ long sys32_uname(struct old_utsname __user * name) if (!name) return -EFAULT; down_read(&uts_sem); - err=copy_to_user(name, vx_new_utsname(), sizeof (*name)); + err = copy_to_user(name, utsname(), sizeof (*name)); up_read(&uts_sem); if (personality(current->personality) == PER_LINUX32) err |= copy_to_user(&name->machine, "i686", 5); @@ -1113,7 +842,7 @@ long sys32_ustat(unsigned dev, struct ustat32 __user *u32p) seg = get_fs(); set_fs(KERNEL_DS); - ret = sys_ustat(dev,&u); + ret = sys_ustat(dev, (struct ustat __user *)&u); set_fs(seg); if (ret >= 0) { if (!access_ok(VERIFY_WRITE,u32p,sizeof(struct ustat32)) || @@ -1137,8 +866,6 @@ asmlinkage long sys32_execve(char __user *name, compat_uptr_t __user *argv, if (IS_ERR(filename)) return error; error = compat_do_execve(filename, argv, envp, regs); - if (error == 0) - current->ptrace &= ~PT_DTRACE; putname(filename); return error; } @@ -1153,32 +880,6 @@ asmlinkage long sys32_clone(unsigned int clone_flags, unsigned int newsp, return do_fork(clone_flags, newsp, regs, 0, parent_tid, child_tid); } -asmlinkage long sys32_waitid(int which, compat_pid_t pid, - siginfo_t32 __user *uinfo, int options, - struct compat_rusage __user *uru) -{ - siginfo_t info; - struct rusage ru; - long ret; - mm_segment_t old_fs = get_fs(); - - info.si_signo = 0; - set_fs (KERNEL_DS); - ret = sys_waitid(which, pid, (siginfo_t __user *) &info, options, - uru ? &ru : NULL); - set_fs (old_fs); - - if (ret < 0 || info.si_signo == 0) - return ret; - - if (uru && (ret = put_compat_rusage(&ru, uru))) - return ret; - - BUG_ON(info.si_code & __SI_MASK); - info.si_code |= __SI_CHLD; - return ia32_copy_siginfo_to_user(uinfo, &info); -} - /* * Some system calls that need sign extended arguments. This could be done by a generic wrapper. */ @@ -1193,145 +894,6 @@ long sys32_kill(int pid, int sig) return sys_kill(pid, sig); } - -long sys32_io_setup(unsigned nr_reqs, u32 __user *ctx32p) -{ - long ret; - aio_context_t ctx64; - mm_segment_t oldfs = get_fs(); - set_fs(KERNEL_DS); - ret = sys_io_setup(nr_reqs, &ctx64); - set_fs(oldfs); - /* truncating is ok because it's a user address */ - if (!ret) - ret = put_user((u32)ctx64, ctx32p); - return ret; -} - -asmlinkage long sys32_io_submit(aio_context_t ctx_id, int nr, - compat_uptr_t __user *iocbpp) -{ - struct kioctx *ctx; - long ret = 0; - int i; - - if (unlikely(nr < 0)) - return -EINVAL; - - if (unlikely(!access_ok(VERIFY_READ, iocbpp, (nr*sizeof(*iocbpp))))) - return -EFAULT; - - ctx = lookup_ioctx(ctx_id); - if (unlikely(!ctx)) { - pr_debug("EINVAL: io_submit: invalid context id\n"); - return -EINVAL; - } - - for (i=0; i= 0xffffffff || - !access_ok(VERIFY_WRITE, events, nr * sizeof(struct io_event))) - return -EFAULT; - if (timeout && get_compat_timespec(&t, timeout)) - return -EFAULT; - oldfs = get_fs(); - set_fs(KERNEL_DS); - ret = sys_io_getevents(ctx_id,min_nr,nr,events,timeout ? &t : NULL); - set_fs(oldfs); - if (!ret && timeout && put_compat_timespec(&t, timeout)) - return -EFAULT; - return ret; -} - -asmlinkage long sys32_open(const char __user * filename, int flags, int mode) -{ - char * tmp; - int fd, error; - - /* don't force O_LARGEFILE */ - tmp = getname(filename); - fd = PTR_ERR(tmp); - if (!IS_ERR(tmp)) { - fd = get_unused_fd(); - if (fd >= 0) { - struct file *f = filp_open(tmp, flags, mode); - error = PTR_ERR(f); - if (IS_ERR(f)) { - put_unused_fd(fd); - fd = error; - } else - fd_install(fd, f); - } - putname(tmp); - } - return fd; -} - -struct sigevent32 { - u32 sigev_value; - u32 sigev_signo; - u32 sigev_notify; - u32 payload[(64 / 4) - 3]; -}; - -extern asmlinkage long -sys_timer_create(clockid_t which_clock, - struct sigevent __user *timer_event_spec, - timer_t __user * created_timer_id); - -long -sys32_timer_create(u32 clock, struct sigevent32 __user *se32, timer_t __user *timer_id) -{ - struct sigevent __user *p = NULL; - if (se32) { - struct sigevent se; - p = compat_alloc_user_space(sizeof(struct sigevent)); - memset(&se, 0, sizeof(struct sigevent)); - if (get_user(se.sigev_value.sival_int, &se32->sigev_value) || - __get_user(se.sigev_signo, &se32->sigev_signo) || - __get_user(se.sigev_notify, &se32->sigev_notify) || - __copy_from_user(&se._sigev_un._pad, &se32->payload, - sizeof(se32->payload)) || - copy_to_user(p, &se, sizeof(se))) - return -EFAULT; - } - return sys_timer_create(clock, p, timer_id); -} - long sys32_fadvise64_64(int fd, __u32 offset_low, __u32 offset_high, __u32 len_low, __u32 len_high, int advice) { @@ -1344,23 +906,11 @@ long sys32_fadvise64_64(int fd, __u32 offset_low, __u32 offset_high, long sys32_vm86_warning(void) { struct task_struct *me = current; - static char lastcomm[8]; - if (strcmp(lastcomm, me->comm)) { - printk(KERN_INFO "%s: vm86 mode not supported on 64 bit kernel\n", + static char lastcomm[sizeof(me->comm)]; + if (strncmp(lastcomm, me->comm, sizeof(lastcomm))) { + compat_printk(KERN_INFO "%s: vm86 mode not supported on 64 bit kernel\n", me->comm); - strcpy(lastcomm, me->comm); - } - return -ENOSYS; -} - -long sys32_quotactl(void) -{ - struct task_struct *me = current; - static char lastcomm[8]; - if (strcmp(lastcomm, me->comm)) { - printk(KERN_INFO "%s: 32bit quotactl not supported on 64 bit kernel\n", - me->comm); - strcpy(lastcomm, me->comm); + strncpy(lastcomm, me->comm, sizeof(lastcomm)); } return -ENOSYS; } @@ -1371,15 +921,3 @@ long sys32_lookup_dcookie(u32 addr_low, u32 addr_high, return sys_lookup_dcookie(((u64)addr_high << 32) | addr_low, buf, len); } -cond_syscall(sys32_ipc) - -static int __init ia32_init (void) -{ - printk("IA32 emulation $Id: sys_ia32.c,v 1.32 2002/03/24 13:02:28 ak Exp $\n"); - return 0; -} - -__initcall(ia32_init); - -extern unsigned long ia32_sys_call_table[]; -EXPORT_SYMBOL(ia32_sys_call_table);