X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fparisc%2Fkernel%2Fsys_parisc32.c;h=bca48bd52cb1937879f03b8162758efb1fcf539f;hb=16c70f8c1b54b61c3b951b6fb220df250fe09b32;hp=cd320b20c22880cc3e27326834be5189f67dd77c;hpb=9213980e6a70d8473e0ffd4b39ab5b6caaba9ff5;p=linux-2.6.git diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c index cd320b20c..bca48bd52 100644 --- a/arch/parisc/kernel/sys_parisc32.c +++ b/arch/parisc/kernel/sys_parisc32.c @@ -9,7 +9,6 @@ * environment. Based heavily on sys_ia32.c and sys_sparc32.c. */ -#include #include #include #include @@ -21,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -74,14 +72,17 @@ asmlinkage int sys32_execve(struct pt_regs *regs) char *filename; DBG(("sys32_execve(%p) r26 = 0x%lx\n", regs, regs->gr[26])); - filename = getname((char *) regs->gr[26]); + filename = getname((const char __user *) regs->gr[26]); error = PTR_ERR(filename); if (IS_ERR(filename)) goto out; error = compat_do_execve(filename, compat_ptr(regs->gr[25]), compat_ptr(regs->gr[24]), regs); - if (error == 0) + if (error == 0) { + task_lock(current); current->ptrace &= ~PT_DTRACE; + task_unlock(current); + } putname(filename); out: @@ -108,13 +109,13 @@ struct __sysctl_args32 { u32 __unused[4]; }; -asmlinkage long sys32_sysctl(struct __sysctl_args32 *args) +asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) { struct __sysctl_args32 tmp; int error; unsigned int oldlen32; size_t oldlen, *oldlenp = NULL; - unsigned long addr = (((long)&args->__unused[0]) + 7) & ~7; + unsigned long addr = (((long __force)&args->__unused[0]) + 7) & ~7; extern int do_sysctl(int *name, int nlen, void *oldval, size_t *oldlenp, void *newval, size_t newlen); @@ -156,34 +157,28 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 *args) error = -EFAULT; } } - if (copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused))) + if (copy_to_user(&args->__unused[0], tmp.__unused, sizeof(tmp.__unused))) error = -EFAULT; } return error; } -#else /* CONFIG_SYSCTL */ - -asmlinkage long sys32_sysctl(struct __sysctl_args *args) -{ - return -ENOSYS; -} #endif /* CONFIG_SYSCTL */ asmlinkage long sys32_sched_rr_get_interval(pid_t pid, - struct compat_timespec *interval) + struct compat_timespec __user *interval) { struct timespec t; int ret; - - KERNEL_SYSCALL(ret, sys_sched_rr_get_interval, pid, &t); + + KERNEL_SYSCALL(ret, sys_sched_rr_get_interval, pid, (struct timespec __user *)&t); if (put_compat_timespec(&t, interval)) return -EFAULT; return ret; } static int -put_compat_timeval(struct compat_timeval *u, struct timeval *t) +put_compat_timeval(struct compat_timeval __user *u, struct timeval *t) { struct compat_timeval t32; t32.tv_sec = t->tv_sec; @@ -191,7 +186,7 @@ put_compat_timeval(struct compat_timeval *u, struct timeval *t) return copy_to_user(u, &t32, sizeof t32); } -static inline long get_ts32(struct timespec *o, struct compat_timeval *i) +static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i) { long usec; @@ -203,22 +198,8 @@ static inline long get_ts32(struct timespec *o, struct compat_timeval *i) return 0; } -asmlinkage long sys32_time(compat_time_t *tloc) -{ - struct timeval tv; - - do_gettimeofday(&tv); - compat_time_t now32 = tv.tv_sec; - - if (tloc) - if (put_user(now32, tloc)) - now32 = -EFAULT; - - return now32; -} - asmlinkage int -sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz) +sys32_gettimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) { extern void do_gettimeofday(struct timeval *tv); @@ -237,7 +218,7 @@ sys32_gettimeofday(struct compat_timeval *tv, struct timezone *tz) } asmlinkage -int sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz) +int sys32_settimeofday(struct compat_timeval __user *tv, struct timezone __user *tz) { struct timespec kts; struct timezone ktz; @@ -254,16 +235,21 @@ int sys32_settimeofday(struct compat_timeval *tv, struct timezone *tz) return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL); } -int cp_compat_stat(struct kstat *stat, struct compat_stat *statbuf) +int cp_compat_stat(struct kstat *stat, struct compat_stat __user *statbuf) { + compat_ino_t ino; int err; if (stat->size > MAX_NON_LFS || !new_valid_dev(stat->dev) || !new_valid_dev(stat->rdev)) return -EOVERFLOW; + ino = stat->ino; + if (sizeof(ino) < sizeof(stat->ino) && ino != stat->ino) + return -EOVERFLOW; + err = put_user(new_encode_dev(stat->dev), &statbuf->st_dev); - err |= put_user(stat->ino, &statbuf->st_ino); + err |= put_user(ino, &statbuf->st_ino); err |= put_user(stat->mode, &statbuf->st_mode); err |= put_user(stat->nlink, &statbuf->st_nlink); err |= put_user(0, &statbuf->st_reserved1); @@ -311,50 +297,54 @@ struct old_linux32_dirent { }; struct getdents32_callback { - struct linux32_dirent * current_dir; - struct linux32_dirent * previous; + struct linux32_dirent __user * current_dir; + struct linux32_dirent __user * previous; int count; int error; }; struct readdir32_callback { - struct old_linux32_dirent * dirent; + struct old_linux32_dirent __user * dirent; int count; }; #define ROUND_UP(x,a) ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1))) -#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de))) +#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de))) static int filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino, unsigned int d_type) { - struct linux32_dirent * dirent; + struct linux32_dirent __user * dirent; struct getdents32_callback * buf = (struct getdents32_callback *) __buf; int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1, 4); + u32 d_ino; buf->error = -EINVAL; /* only used if we fail.. */ if (reclen > buf->count) return -EINVAL; + d_ino = ino; + if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) + return -EOVERFLOW; 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(d_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); - ((char *) dirent) += reclen; + dirent = ((void __user *)dirent) + reclen; buf->current_dir = dirent; buf->count -= reclen; return 0; } asmlinkage long -sys32_getdents (unsigned int fd, void * dirent, unsigned int count) +sys32_getdents (unsigned int fd, void __user * dirent, unsigned int count) { struct file * file; - struct linux32_dirent * lastdirent; + struct linux32_dirent __user * lastdirent; struct getdents32_callback buf; int error; @@ -363,7 +353,7 @@ sys32_getdents (unsigned int fd, void * dirent, unsigned int count) if (!file) goto out; - buf.current_dir = (struct linux32_dirent *) dirent; + buf.current_dir = (struct linux32_dirent __user *) dirent; buf.previous = NULL; buf.count = count; buf.error = 0; @@ -389,13 +379,17 @@ fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t unsigned int d_type) { struct readdir32_callback * buf = (struct readdir32_callback *) __buf; - struct old_linux32_dirent * dirent; + struct old_linux32_dirent __user * dirent; + u32 d_ino; if (buf->count) return -EINVAL; + d_ino = ino; + if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) + return -EOVERFLOW; buf->count++; dirent = buf->dirent; - put_user(ino, &dirent->d_ino); + put_user(d_ino, &dirent->d_ino); put_user(offset, &dirent->d_offset); put_user(namlen, &dirent->d_namlen); copy_to_user(dirent->d_name, name, namlen); @@ -404,7 +398,7 @@ fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t } asmlinkage long -sys32_readdir (unsigned int fd, void * dirent, unsigned int count) +sys32_readdir (unsigned int fd, void __user * dirent, unsigned int count) { int error; struct file * file; @@ -439,7 +433,7 @@ get_fd_set32(unsigned long n, u32 *ufdset, unsigned long *fdset) if (ufdset) { unsigned long odd; - if (verify_area(VERIFY_WRITE, ufdset, n*sizeof(u32))) + if (!access_ok(VERIFY_WRITE, ufdset, n*sizeof(u32))) return -EFAULT; odd = n & 1UL; @@ -494,7 +488,7 @@ struct msgbuf32 { }; asmlinkage long sys32_msgsnd(int msqid, - struct msgbuf32 *umsgp32, + struct msgbuf32 __user *umsgp32, size_t msgsz, int msgflg) { struct msgbuf *mb; @@ -511,14 +505,14 @@ asmlinkage long sys32_msgsnd(int msqid, if (err) err = -EFAULT; else - KERNEL_SYSCALL(err, sys_msgsnd, msqid, mb, msgsz, msgflg); + KERNEL_SYSCALL(err, sys_msgsnd, msqid, (struct msgbuf __user *)mb, msgsz, msgflg); kfree(mb); return err; } asmlinkage long sys32_msgrcv(int msqid, - struct msgbuf32 *umsgp32, + struct msgbuf32 __user *umsgp32, size_t msgsz, long msgtyp, int msgflg) { struct msgbuf *mb; @@ -528,7 +522,7 @@ asmlinkage long sys32_msgrcv(int msqid, if ((mb = kmalloc(msgsz + sizeof *mb + 4, GFP_KERNEL)) == NULL) return -ENOMEM; - KERNEL_SYSCALL(err, sys_msgrcv, msqid, mb, msgsz, msgtyp, msgflg); + KERNEL_SYSCALL(err, sys_msgrcv, msqid, (struct msgbuf __user *)mb, msgsz, msgtyp, msgflg); if (err >= 0) { len = err; @@ -545,7 +539,7 @@ asmlinkage long sys32_msgrcv(int msqid, return err; } -asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, s32 count) +asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, s32 count) { mm_segment_t old_fs = get_fs(); int ret; @@ -555,7 +549,7 @@ asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, s32 c 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 (offset && put_user(of, offset)) @@ -564,9 +558,7 @@ asmlinkage int sys32_sendfile(int out_fd, int in_fd, compat_off_t *offset, s32 c return ret; } -typedef long __kernel_loff_t32; /* move this to asm/posix_types.h? */ - -asmlinkage int sys32_sendfile64(int out_fd, int in_fd, __kernel_loff_t32 *offset, s32 count) +asmlinkage int sys32_sendfile64(int out_fd, int in_fd, compat_loff_t __user *offset, s32 count) { mm_segment_t old_fs = get_fs(); int ret; @@ -576,7 +568,7 @@ asmlinkage int sys32_sendfile64(int out_fd, int in_fd, __kernel_loff_t32 *offset return -EFAULT; set_fs(KERNEL_DS); - ret = sys_sendfile64(out_fd, in_fd, offset ? &lof : NULL, count); + ret = sys_sendfile64(out_fd, in_fd, offset ? (loff_t __user *)&lof : NULL, count); set_fs(old_fs); if (offset && put_user(lof, offset)) @@ -586,63 +578,6 @@ asmlinkage int sys32_sendfile64(int out_fd, int in_fd, __kernel_loff_t32 *offset } -struct timex32 { - unsigned int modes; /* mode selector */ - int offset; /* time offset (usec) */ - int freq; /* frequency offset (scaled ppm) */ - int maxerror; /* maximum error (usec) */ - int esterror; /* estimated error (usec) */ - int status; /* clock command/status */ - int constant; /* pll time constant */ - int precision; /* clock precision (usec) (read only) */ - int tolerance; /* clock frequency tolerance (ppm) - * (read only) - */ - struct compat_timeval time; /* (read only) */ - int tick; /* (modified) usecs between clock ticks */ - - int ppsfreq; /* pps frequency (scaled ppm) (ro) */ - int jitter; /* pps jitter (us) (ro) */ - int shift; /* interval duration (s) (shift) (ro) */ - int stabil; /* pps stability (scaled ppm) (ro) */ - int jitcnt; /* jitter limit exceeded (ro) */ - int calcnt; /* calibration intervals (ro) */ - int errcnt; /* calibration errors (ro) */ - int stbcnt; /* stability limit exceeded (ro) */ - - int :32; int :32; int :32; int :32; - int :32; int :32; int :32; int :32; - int :32; int :32; int :32; int :32; -}; - -asmlinkage long sys32_adjtimex(struct timex32 *txc_p32) -{ - struct timex txc; - struct timex32 t32; - int ret; - extern int do_adjtimex(struct timex *txc); - - if(copy_from_user(&t32, txc_p32, sizeof(struct timex32))) - return -EFAULT; -#undef CP -#define CP(x) txc.x = t32.x - CP(modes); CP(offset); CP(freq); CP(maxerror); CP(esterror); - CP(status); CP(constant); CP(precision); CP(tolerance); - CP(time.tv_sec); CP(time.tv_usec); CP(tick); CP(ppsfreq); CP(jitter); - CP(shift); CP(stabil); CP(jitcnt); CP(calcnt); CP(errcnt); - CP(stbcnt); - ret = do_adjtimex(&txc); -#undef CP -#define CP(x) t32.x = txc.x - CP(modes); CP(offset); CP(freq); CP(maxerror); CP(esterror); - CP(status); CP(constant); CP(precision); CP(tolerance); - CP(time.tv_sec); CP(time.tv_usec); CP(tick); CP(ppsfreq); CP(jitter); - CP(shift); CP(stabil); CP(jitcnt); CP(calcnt); CP(errcnt); - CP(stbcnt); - return copy_to_user(txc_p32, &t32, sizeof(struct timex32)) ? -EFAULT : ret; -} - - struct sysinfo32 { s32 uptime; u32 loads[3]; @@ -664,7 +599,7 @@ struct sysinfo32 { * damage, I decided to just duplicate the code from sys_sysinfo here. */ -asmlinkage int sys32_sysinfo(struct sysinfo32 *info) +asmlinkage int sys32_sysinfo(struct sysinfo32 __user *info) { struct sysinfo val; int err; @@ -676,7 +611,7 @@ asmlinkage int sys32_sysinfo(struct sysinfo32 *info) do { seq = read_seqbegin(&xtime_lock); - /* requires vx virtualization */ + /* FIXME: requires vx virtualization */ val.uptime = jiffies / HZ; val.loads[0] = avenrun[0] << (SI_LOAD_SHIFT - FSHIFT); @@ -732,7 +667,7 @@ asmlinkage long sys32_semctl(int semid, int semnum, int cmd, union semun arg) return sys_semctl (semid, semnum, cmd, arg); } -long sys32_lookup_dcookie(u32 cookie_high, u32 cookie_low, char *buf, +long sys32_lookup_dcookie(u32 cookie_high, u32 cookie_low, char __user *buf, size_t len) { return sys_lookup_dcookie((u64)cookie_high << 32 | cookie_low,