X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fsparc64%2Fkernel%2Fsys_sunos32.c;h=058a6a70974ebaed7919f5f5b37cea19e164ce18;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=2c963a35f58f38e9f0943884873908e01dd47dff;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/arch/sparc64/kernel/sys_sunos32.c b/arch/sparc64/kernel/sys_sunos32.c index 2c963a35f..058a6a709 100644 --- a/arch/sparc64/kernel/sys_sunos32.c +++ b/arch/sparc64/kernel/sys_sunos32.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -34,6 +35,7 @@ #include #include #include +#include #include #include @@ -59,15 +61,6 @@ #include #include -/* Use this to get at 32-bit user passed pointers. */ -#define A(__x) \ -({ unsigned long __ret; \ - __asm__ ("srl %0, 0, %0" \ - : "=r" (__ret) \ - : "0" (__x)); \ - __ret; \ -}) - #define SUNOS_NR_OPEN 256 asmlinkage u32 sunos_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 off) @@ -151,7 +144,7 @@ asmlinkage int sunos_brk(u32 baddr) } /* Check against rlimit and stack.. */ retval = -ENOMEM; - rlim = current->rlim[RLIMIT_DATA].rlim_cur; + rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; if (rlim >= RLIM_INFINITY) rlim = ~0; if (brk - current->mm->end_code > rlim) @@ -187,7 +180,7 @@ asmlinkage u32 sunos_sbrk(int increment) /* This should do it hopefully... */ oldbrk = (int)current->mm->brk; error = sunos_brk(((int) current->mm->brk) + increment); - if(!error) + if (!error) error = oldbrk; return error; } @@ -273,19 +266,19 @@ struct sunos_dirent { }; struct sunos_dirent_callback { - struct sunos_dirent *curr; - struct sunos_dirent *previous; + struct sunos_dirent __user *curr; + struct sunos_dirent __user *previous; int count; int error; }; -#define NAME_OFFSET(de) ((int) ((de)->d_name - (char *) (de))) +#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de))) #define ROUND_UP(x) (((x)+sizeof(s32)-1) & ~(sizeof(s32)-1)) static int sunos_filldir(void * __buf, const char * name, int namlen, loff_t offset, ino_t ino, unsigned int d_type) { - struct sunos_dirent * dirent; + struct sunos_dirent __user *dirent; struct sunos_dirent_callback * buf = (struct sunos_dirent_callback *) __buf; int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); @@ -300,34 +293,34 @@ static int sunos_filldir(void * __buf, const char * name, int namlen, put_user(ino, &dirent->d_ino); put_user(namlen, &dirent->d_namlen); put_user(reclen, &dirent->d_reclen); - copy_to_user(dirent->d_name, name, namlen); + if (copy_to_user(dirent->d_name, name, namlen)) + return -EFAULT; put_user(0, dirent->d_name + namlen); - dirent = (void *) dirent + reclen; + dirent = (void __user *) dirent + reclen; buf->curr = dirent; buf->count -= reclen; return 0; } -asmlinkage int sunos_getdents(unsigned int fd, u32 u_dirent, int cnt) +asmlinkage int sunos_getdents(unsigned int fd, void __user *dirent, int cnt) { struct file * file; - struct sunos_dirent * lastdirent; + struct sunos_dirent __user *lastdirent; struct sunos_dirent_callback buf; int error = -EBADF; - void *dirent = (void *)A(u_dirent); - if(fd >= SUNOS_NR_OPEN) + if (fd >= SUNOS_NR_OPEN) goto out; file = fget(fd); - if(!file) + if (!file) goto out; error = -EINVAL; - if(cnt < (sizeof(struct sunos_dirent) + 255)) + if (cnt < (sizeof(struct sunos_dirent) + 255)) goto out_putf; - buf.curr = (struct sunos_dirent *) dirent; + buf.curr = (struct sunos_dirent __user *) dirent; buf.previous = NULL; buf.count = cnt; buf.error = 0; @@ -358,8 +351,8 @@ struct sunos_direntry { }; struct sunos_direntry_callback { - struct sunos_direntry *curr; - struct sunos_direntry *previous; + struct sunos_direntry __user *curr; + struct sunos_direntry __user *previous; int count; int error; }; @@ -367,8 +360,9 @@ struct sunos_direntry_callback { static int sunos_filldirentry(void * __buf, const char * name, int namlen, loff_t offset, ino_t ino, unsigned int d_type) { - struct sunos_direntry * dirent; - struct sunos_direntry_callback * buf = (struct sunos_direntry_callback *) __buf; + struct sunos_direntry __user *dirent; + struct sunos_direntry_callback * buf = + (struct sunos_direntry_callback *) __buf; int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1); buf->error = -EINVAL; /* only used if we fail.. */ @@ -380,36 +374,37 @@ static int sunos_filldirentry(void * __buf, const char * name, int namlen, put_user(ino, &dirent->d_ino); put_user(namlen, &dirent->d_namlen); put_user(reclen, &dirent->d_reclen); - copy_to_user(dirent->d_name, name, namlen); + if (copy_to_user(dirent->d_name, name, namlen)) + return -EFAULT; put_user(0, dirent->d_name + namlen); - dirent = (void *) dirent + reclen; + dirent = (void __user *) dirent + reclen; buf->curr = dirent; buf->count -= reclen; return 0; } -asmlinkage int sunos_getdirentries(unsigned int fd, u32 u_dirent, - int cnt, u32 u_basep) +asmlinkage int sunos_getdirentries(unsigned int fd, + void __user *dirent, + int cnt, + unsigned int __user *basep) { - void *dirent = (void *) A(u_dirent); - unsigned int *basep = (unsigned int *)A(u_basep); struct file * file; - struct sunos_direntry * lastdirent; + struct sunos_direntry __user *lastdirent; int error = -EBADF; struct sunos_direntry_callback buf; - if(fd >= SUNOS_NR_OPEN) + if (fd >= SUNOS_NR_OPEN) goto out; file = fget(fd); - if(!file) + if (!file) goto out; error = -EINVAL; - if(cnt < (sizeof(struct sunos_direntry) + 255)) + if (cnt < (sizeof(struct sunos_direntry) + 255)) goto out_putf; - buf.curr = (struct sunos_direntry *) dirent; + buf.curr = (struct sunos_direntry __user *) dirent; buf.previous = NULL; buf.count = cnt; buf.error = 0; @@ -440,17 +435,24 @@ struct sunos_utsname { char mach[9]; }; -asmlinkage int sunos_uname(struct sunos_utsname *name) +asmlinkage int sunos_uname(struct sunos_utsname __user *name) { int ret; + struct new_utsname *ptr; down_read(&uts_sem); - ret = copy_to_user(&name->sname[0], &system_utsname.sysname[0], sizeof(name->sname) - 1); - ret |= copy_to_user(&name->nname[0], &system_utsname.nodename[0], sizeof(name->nname) - 1); + ptr = vx_new_utsname(); + ret = copy_to_user(&name->sname[0], ptr->sysname, + sizeof(name->sname) - 1); + ret |= copy_to_user(&name->nname[0], ptr->nodename, + sizeof(name->nname) - 1); ret |= put_user('\0', &name->nname[8]); - ret |= copy_to_user(&name->rel[0], &system_utsname.release[0], sizeof(name->rel) - 1); - ret |= copy_to_user(&name->ver[0], &system_utsname.version[0], sizeof(name->ver) - 1); - ret |= copy_to_user(&name->mach[0], &system_utsname.machine[0], sizeof(name->mach) - 1); + ret |= copy_to_user(&name->rel[0], ptr->release, + sizeof(name->rel) - 1); + ret |= copy_to_user(&name->ver[0], ptr->version, + sizeof(name->ver) - 1); + ret |= copy_to_user(&name->mach[0], ptr->machine, + sizeof(name->mach) - 1); up_read(&uts_sem); return (ret ? -EFAULT : 0); } @@ -469,7 +471,7 @@ asmlinkage int sunos_nosys(void) info.si_signo = SIGSYS; info.si_errno = 0; info.si_code = __SI_FAULT|0x100; - info.si_addr = (void *)regs->tpc; + info.si_addr = (void __user *)regs->tpc; info.si_trapno = regs->u_regs[UREG_G1]; send_sig_info(SIGSYS, &info, current); if (cnt++ < 4) { @@ -528,18 +530,15 @@ asmlinkage int sunos_pathconf(u32 u_path, int name) return ret; } -/* SunOS mount system call emulation */ -extern asmlinkage int -sys32_select(int n, u32 inp, u32 outp, u32 exp, u32 tvp); - asmlinkage int sunos_select(int width, u32 inp, u32 outp, u32 exp, u32 tvp_x) { int ret; /* SunOS binaries expect that select won't change the tvp contents */ - ret = sys32_select (width, inp, outp, exp, tvp_x); + ret = compat_sys_select(width, compat_ptr(inp), compat_ptr(outp), + compat_ptr(exp), compat_ptr(tvp_x)); if (ret == -EINTR && tvp_x) { - struct compat_timeval *tvp = (struct compat_timeval *)A(tvp_x); + struct compat_timeval __user *tvp = compat_ptr(tvp_x); time_t sec, usec; __get_user(sec, &tvp->tv_sec); @@ -555,6 +554,10 @@ asmlinkage void sunos_nop(void) return; } +#if 0 /* This code doesn't translate user pointers correctly, + * disable for now. -DaveM + */ + /* XXXXXXXXXX SunOS mount/umount. XXXXXXXXXXX */ #define SMNT_RDONLY 1 #define SMNT_NOSUID 2 @@ -603,7 +606,7 @@ sunos_nfs_get_server_fd (int fd, struct sockaddr_in *addr) struct file *file; file = fget(fd); - if(!file) + if (!file) return 0; inode = file->f_dentry->d_inode; @@ -648,7 +651,7 @@ static int get_default (int value, int def_value) } /* XXXXXXXXXXXXXXXXXXXX */ -static int sunos_nfs_mount(char *dir_name, int linux_flags, void *data) +static int sunos_nfs_mount(char *dir_name, int linux_flags, void __user *data) { int server_fd, err; char *the_name, *mount_page; @@ -668,10 +671,10 @@ static int sunos_nfs_mount(char *dir_name, int linux_flags, void *data) if (server_fd < 0) return -ENXIO; - if (copy_from_user(&linux_nfs_mount.addr,sunos_mount.addr, - sizeof(*sunos_mount.addr)) || - copy_from_user(&linux_nfs_mount.root,sunos_mount.fh, - sizeof(*sunos_mount.fh))) { + if (copy_from_user(&linux_nfs_mount.addr, sunos_mount.addr, + sizeof(*sunos_mount.addr)) || + copy_from_user(&linux_nfs_mount.root, sunos_mount.fh, + sizeof(*sunos_mount.fh))) { sys_close (server_fd); return -EFAULT; } @@ -697,7 +700,7 @@ static int sunos_nfs_mount(char *dir_name, int linux_flags, void *data) linux_nfs_mount.acdirmax = sunos_mount.acdirmax; the_name = getname(sunos_mount.hostname); - if(IS_ERR(the_name)) + if (IS_ERR(the_name)) return PTR_ERR(the_name); strlcpy(linux_nfs_mount.hostname, the_name, @@ -736,11 +739,11 @@ sunos_mount(char *type, char *dir, int flags, void *data) if (flags & (SMNT_GRPID|SMNT_NOSUB|SMNT_MULTI|SMNT_SYS5)) goto out; - if(flags & SMNT_REMOUNT) + if (flags & SMNT_REMOUNT) linux_flags |= MS_REMOUNT; - if(flags & SMNT_RDONLY) + if (flags & SMNT_RDONLY) linux_flags |= MS_RDONLY; - if(flags & SMNT_NOSUID) + if (flags & SMNT_NOSUID) linux_flags |= MS_NOSUID; dir_page = getname(dir); @@ -753,20 +756,20 @@ sunos_mount(char *type, char *dir, int flags, void *data) if (IS_ERR(type_page)) goto out1; - if(strcmp(type_page, "ext2") == 0) { + if (strcmp(type_page, "ext2") == 0) { dev_fname = getname(data); - } else if(strcmp(type_page, "iso9660") == 0) { + } else if (strcmp(type_page, "iso9660") == 0) { dev_fname = getname(data); - } else if(strcmp(type_page, "minix") == 0) { + } else if (strcmp(type_page, "minix") == 0) { dev_fname = getname(data); - } else if(strcmp(type_page, "nfs") == 0) { + } else if (strcmp(type_page, "nfs") == 0) { ret = sunos_nfs_mount (dir_page, flags, data); goto out2; - } else if(strcmp(type_page, "ufs") == 0) { + } else if (strcmp(type_page, "ufs") == 0) { printk("Warning: UFS filesystem mounts unsupported.\n"); ret = -ENODEV; goto out2; - } else if(strcmp(type_page, "proc")) { + } else if (strcmp(type_page, "proc")) { ret = -ENODEV; goto out2; } @@ -785,15 +788,15 @@ out1: out: return ret; } - +#endif asmlinkage int sunos_setpgrp(pid_t pid, pid_t pgid) { int ret; /* So stupid... */ - if((!pid || pid == current->pid) && - !pgid) { + if ((!pid || pid == current->pid) && + !pgid) { sys_setsid(); ret = 0; } else { @@ -803,16 +806,15 @@ asmlinkage int sunos_setpgrp(pid_t pid, pid_t pgid) } /* So stupid... */ -extern long compat_sys_wait4(compat_pid_t, compat_uint_t *, int, - struct compat_rusage *); +extern long compat_sys_wait4(compat_pid_t, compat_uint_t __user *, int, + struct compat_rusage __user *); -asmlinkage int sunos_wait4(compat_pid_t pid, u32 stat_addr, int options, u32 ru) +asmlinkage int sunos_wait4(compat_pid_t pid, compat_uint_t __user *stat_addr, int options, struct compat_rusage __user *ru) { int ret; ret = compat_sys_wait4((pid ? pid : ((compat_pid_t)-1)), - (compat_uint_t *)A(stat_addr), options, - (struct compat_rusage *)A(ru)); + stat_addr, options, ru); return ret; } @@ -828,7 +830,7 @@ asmlinkage int sunos_audit(void) return -1; } -extern asmlinkage u32 sunos_gethostid(void) +asmlinkage u32 sunos_gethostid(void) { u32 ret; @@ -847,7 +849,7 @@ extern asmlinkage u32 sunos_gethostid(void) #define _SC_SAVED_IDS 7 #define _SC_VERSION 8 -extern asmlinkage s32 sunos_sysconf (int name) +asmlinkage s32 sunos_sysconf (int name) { s32 ret; @@ -856,7 +858,7 @@ extern asmlinkage s32 sunos_sysconf (int name) ret = ARG_MAX; break; case _SC_CHILD_MAX: - ret = CHILD_MAX; + ret = -1; /* no limit */ break; case _SC_CLK_TCK: ret = HZ; @@ -886,7 +888,7 @@ extern asmlinkage s32 sunos_sysconf (int name) return ret; } -asmlinkage int sunos_semsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 ptr) +asmlinkage int sunos_semsys(int op, u32 arg1, u32 arg2, u32 arg3, void __user *ptr) { union semun arg4; int ret; @@ -911,7 +913,8 @@ asmlinkage int sunos_semsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 ptr) arg3=SETALL; break; } /* sys_semctl(): */ - arg4.__pad=(void *)A(ptr); /* value to modify semaphore to */ + /* value to modify semaphore to */ + arg4.__pad = ptr; ret = sys_semctl((int)arg1, (int)arg2, (int)arg3, arg4); break; case 1: @@ -920,7 +923,8 @@ asmlinkage int sunos_semsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 ptr) break; case 2: /* sys_semop(): */ - ret = sys_semop((int)arg1, (struct sembuf *)A(arg2), (unsigned)arg3); + ret = sys_semop((int)arg1, (struct sembuf __user *)(unsigned long)arg2, + (unsigned int) arg3); break; default: ret = -EINVAL; @@ -962,65 +966,65 @@ struct msqid_ds32 compat_ipc_pid_t msg_lrpid; }; -static inline int sunos_msqid_get(struct msqid_ds32 *user, +static inline int sunos_msqid_get(struct msqid_ds32 __user *user, struct msqid_ds *kern) { - if(get_user(kern->msg_perm.key, &user->msg_perm.key) || - __get_user(kern->msg_perm.uid, &user->msg_perm.uid) || - __get_user(kern->msg_perm.gid, &user->msg_perm.gid) || - __get_user(kern->msg_perm.cuid, &user->msg_perm.cuid) || - __get_user(kern->msg_perm.cgid, &user->msg_perm.cgid) || - __get_user(kern->msg_stime, &user->msg_stime) || - __get_user(kern->msg_rtime, &user->msg_rtime) || - __get_user(kern->msg_ctime, &user->msg_ctime) || - __get_user(kern->msg_ctime, &user->msg_cbytes) || - __get_user(kern->msg_ctime, &user->msg_qnum) || - __get_user(kern->msg_ctime, &user->msg_qbytes) || - __get_user(kern->msg_ctime, &user->msg_lspid) || - __get_user(kern->msg_ctime, &user->msg_lrpid)) + if (get_user(kern->msg_perm.key, &user->msg_perm.key) || + __get_user(kern->msg_perm.uid, &user->msg_perm.uid) || + __get_user(kern->msg_perm.gid, &user->msg_perm.gid) || + __get_user(kern->msg_perm.cuid, &user->msg_perm.cuid) || + __get_user(kern->msg_perm.cgid, &user->msg_perm.cgid) || + __get_user(kern->msg_stime, &user->msg_stime) || + __get_user(kern->msg_rtime, &user->msg_rtime) || + __get_user(kern->msg_ctime, &user->msg_ctime) || + __get_user(kern->msg_ctime, &user->msg_cbytes) || + __get_user(kern->msg_ctime, &user->msg_qnum) || + __get_user(kern->msg_ctime, &user->msg_qbytes) || + __get_user(kern->msg_ctime, &user->msg_lspid) || + __get_user(kern->msg_ctime, &user->msg_lrpid)) return -EFAULT; return 0; } -static inline int sunos_msqid_put(struct msqid_ds32 *user, +static inline int sunos_msqid_put(struct msqid_ds32 __user *user, struct msqid_ds *kern) { - if(put_user(kern->msg_perm.key, &user->msg_perm.key) || - __put_user(kern->msg_perm.uid, &user->msg_perm.uid) || - __put_user(kern->msg_perm.gid, &user->msg_perm.gid) || - __put_user(kern->msg_perm.cuid, &user->msg_perm.cuid) || - __put_user(kern->msg_perm.cgid, &user->msg_perm.cgid) || - __put_user(kern->msg_stime, &user->msg_stime) || - __put_user(kern->msg_rtime, &user->msg_rtime) || - __put_user(kern->msg_ctime, &user->msg_ctime) || - __put_user(kern->msg_ctime, &user->msg_cbytes) || - __put_user(kern->msg_ctime, &user->msg_qnum) || - __put_user(kern->msg_ctime, &user->msg_qbytes) || - __put_user(kern->msg_ctime, &user->msg_lspid) || - __put_user(kern->msg_ctime, &user->msg_lrpid)) + if (put_user(kern->msg_perm.key, &user->msg_perm.key) || + __put_user(kern->msg_perm.uid, &user->msg_perm.uid) || + __put_user(kern->msg_perm.gid, &user->msg_perm.gid) || + __put_user(kern->msg_perm.cuid, &user->msg_perm.cuid) || + __put_user(kern->msg_perm.cgid, &user->msg_perm.cgid) || + __put_user(kern->msg_stime, &user->msg_stime) || + __put_user(kern->msg_rtime, &user->msg_rtime) || + __put_user(kern->msg_ctime, &user->msg_ctime) || + __put_user(kern->msg_ctime, &user->msg_cbytes) || + __put_user(kern->msg_ctime, &user->msg_qnum) || + __put_user(kern->msg_ctime, &user->msg_qbytes) || + __put_user(kern->msg_ctime, &user->msg_lspid) || + __put_user(kern->msg_ctime, &user->msg_lrpid)) return -EFAULT; return 0; } -static inline int sunos_msgbuf_get(struct msgbuf32 *user, struct msgbuf *kern, int len) +static inline int sunos_msgbuf_get(struct msgbuf32 __user *user, struct msgbuf *kern, int len) { - if(get_user(kern->mtype, &user->mtype) || - __copy_from_user(kern->mtext, &user->mtext, len)) + if (get_user(kern->mtype, &user->mtype) || + __copy_from_user(kern->mtext, &user->mtext, len)) return -EFAULT; return 0; } -static inline int sunos_msgbuf_put(struct msgbuf32 *user, struct msgbuf *kern, int len) +static inline int sunos_msgbuf_put(struct msgbuf32 __user *user, struct msgbuf *kern, int len) { - if(put_user(kern->mtype, &user->mtype) || - __copy_to_user(user->mtext, kern->mtext, len)) + if (put_user(kern->mtype, &user->mtype) || + __copy_to_user(user->mtext, kern->mtext, len)) return -EFAULT; return 0; } asmlinkage int sunos_msgsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 arg4) { - struct sparc_stackf32 *sp; + struct sparc_stackf32 __user *sp; struct msqid_ds kds; struct msgbuf *kmbuf; mm_segment_t old_fs = get_fs(); @@ -1032,13 +1036,13 @@ asmlinkage int sunos_msgsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 arg4) rval = sys_msgget((key_t)arg1, (int)arg2); break; case 1: - if(!sunos_msqid_get((struct msqid_ds32 *)A(arg3), &kds)) { + if (!sunos_msqid_get((struct msqid_ds32 __user *)(unsigned long)arg3, &kds)) { set_fs(KERNEL_DS); rval = sys_msgctl((int)arg1, (int)arg2, - (struct msqid_ds *)A(arg3)); + (struct msqid_ds __user *)(unsigned long)arg3); set_fs(old_fs); - if(!rval) - rval = sunos_msqid_put((struct msqid_ds32 *)A(arg3), + if (!rval) + rval = sunos_msqid_put((struct msqid_ds32 __user *)(unsigned long)arg3, &kds); } else rval = -EFAULT; @@ -1047,21 +1051,22 @@ asmlinkage int sunos_msgsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 arg4) rval = -EFAULT; kmbuf = (struct msgbuf *)kmalloc(sizeof(struct msgbuf) + arg3, GFP_KERNEL); - if(!kmbuf) + if (!kmbuf) break; - sp = (struct sparc_stackf32 *) + sp = (struct sparc_stackf32 __user *) (current_thread_info()->kregs->u_regs[UREG_FP] & 0xffffffffUL); - if(get_user(arg5, &sp->xxargs[0])) { + if (get_user(arg5, &sp->xxargs[0])) { rval = -EFAULT; kfree(kmbuf); break; } set_fs(KERNEL_DS); - rval = sys_msgrcv((int)arg1, kmbuf, (size_t)arg3, + rval = sys_msgrcv((int)arg1, (struct msgbuf __user *) kmbuf, + (size_t)arg3, (long)arg4, (int)arg5); set_fs(old_fs); - if(!rval) - rval = sunos_msgbuf_put((struct msgbuf32 *)A(arg2), + if (!rval) + rval = sunos_msgbuf_put((struct msgbuf32 __user *)(unsigned long)arg2, kmbuf, arg3); kfree(kmbuf); break; @@ -1069,11 +1074,12 @@ asmlinkage int sunos_msgsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 arg4) rval = -EFAULT; kmbuf = (struct msgbuf *)kmalloc(sizeof(struct msgbuf) + arg3, GFP_KERNEL); - if(!kmbuf || sunos_msgbuf_get((struct msgbuf32 *)A(arg2), - kmbuf, arg3)) + if (!kmbuf || sunos_msgbuf_get((struct msgbuf32 __user *)(unsigned long)arg2, + kmbuf, arg3)) break; set_fs(KERNEL_DS); - rval = sys_msgsnd((int)arg1, kmbuf, (size_t)arg3, (int)arg4); + rval = sys_msgsnd((int)arg1, (struct msgbuf __user *) kmbuf, + (size_t)arg3, (int)arg4); set_fs(old_fs); kfree(kmbuf); break; @@ -1095,40 +1101,40 @@ struct shmid_ds32 { unsigned short shm_nattch; }; -static inline int sunos_shmid_get(struct shmid_ds32 *user, +static inline int sunos_shmid_get(struct shmid_ds32 __user *user, struct shmid_ds *kern) { - if(get_user(kern->shm_perm.key, &user->shm_perm.key) || - __get_user(kern->shm_perm.uid, &user->shm_perm.uid) || - __get_user(kern->shm_perm.gid, &user->shm_perm.gid) || - __get_user(kern->shm_perm.cuid, &user->shm_perm.cuid) || - __get_user(kern->shm_perm.cgid, &user->shm_perm.cgid) || - __get_user(kern->shm_segsz, &user->shm_segsz) || - __get_user(kern->shm_atime, &user->shm_atime) || - __get_user(kern->shm_dtime, &user->shm_dtime) || - __get_user(kern->shm_ctime, &user->shm_ctime) || - __get_user(kern->shm_cpid, &user->shm_cpid) || - __get_user(kern->shm_lpid, &user->shm_lpid) || - __get_user(kern->shm_nattch, &user->shm_nattch)) + if (get_user(kern->shm_perm.key, &user->shm_perm.key) || + __get_user(kern->shm_perm.uid, &user->shm_perm.uid) || + __get_user(kern->shm_perm.gid, &user->shm_perm.gid) || + __get_user(kern->shm_perm.cuid, &user->shm_perm.cuid) || + __get_user(kern->shm_perm.cgid, &user->shm_perm.cgid) || + __get_user(kern->shm_segsz, &user->shm_segsz) || + __get_user(kern->shm_atime, &user->shm_atime) || + __get_user(kern->shm_dtime, &user->shm_dtime) || + __get_user(kern->shm_ctime, &user->shm_ctime) || + __get_user(kern->shm_cpid, &user->shm_cpid) || + __get_user(kern->shm_lpid, &user->shm_lpid) || + __get_user(kern->shm_nattch, &user->shm_nattch)) return -EFAULT; return 0; } -static inline int sunos_shmid_put(struct shmid_ds32 *user, +static inline int sunos_shmid_put(struct shmid_ds32 __user *user, struct shmid_ds *kern) { - if(put_user(kern->shm_perm.key, &user->shm_perm.key) || - __put_user(kern->shm_perm.uid, &user->shm_perm.uid) || - __put_user(kern->shm_perm.gid, &user->shm_perm.gid) || - __put_user(kern->shm_perm.cuid, &user->shm_perm.cuid) || - __put_user(kern->shm_perm.cgid, &user->shm_perm.cgid) || - __put_user(kern->shm_segsz, &user->shm_segsz) || - __put_user(kern->shm_atime, &user->shm_atime) || - __put_user(kern->shm_dtime, &user->shm_dtime) || - __put_user(kern->shm_ctime, &user->shm_ctime) || - __put_user(kern->shm_cpid, &user->shm_cpid) || - __put_user(kern->shm_lpid, &user->shm_lpid) || - __put_user(kern->shm_nattch, &user->shm_nattch)) + if (put_user(kern->shm_perm.key, &user->shm_perm.key) || + __put_user(kern->shm_perm.uid, &user->shm_perm.uid) || + __put_user(kern->shm_perm.gid, &user->shm_perm.gid) || + __put_user(kern->shm_perm.cuid, &user->shm_perm.cuid) || + __put_user(kern->shm_perm.cgid, &user->shm_perm.cgid) || + __put_user(kern->shm_segsz, &user->shm_segsz) || + __put_user(kern->shm_atime, &user->shm_atime) || + __put_user(kern->shm_dtime, &user->shm_dtime) || + __put_user(kern->shm_ctime, &user->shm_ctime) || + __put_user(kern->shm_cpid, &user->shm_cpid) || + __put_user(kern->shm_lpid, &user->shm_lpid) || + __put_user(kern->shm_nattch, &user->shm_nattch)) return -EFAULT; return 0; } @@ -1143,25 +1149,26 @@ asmlinkage int sunos_shmsys(int op, u32 arg1, u32 arg2, u32 arg3) switch(op) { case 0: /* do_shmat(): attach a shared memory area */ - rval = do_shmat((int)arg1,(char *)A(arg2),(int)arg3,&raddr); - if(!rval) + rval = do_shmat((int)arg1,(char __user *)(unsigned long)arg2,(int)arg3,&raddr); + if (!rval) rval = (int) raddr; break; case 1: /* sys_shmctl(): modify shared memory area attr. */ - if(!sunos_shmid_get((struct shmid_ds32 *)A(arg3), &ksds)) { + if (!sunos_shmid_get((struct shmid_ds32 __user *)(unsigned long)arg3, &ksds)) { set_fs(KERNEL_DS); - rval = sys_shmctl((int)arg1,(int)arg2, &ksds); + rval = sys_shmctl((int) arg1,(int) arg2, + (struct shmid_ds __user *) &ksds); set_fs(old_fs); - if(!rval) - rval = sunos_shmid_put((struct shmid_ds32 *)A(arg3), + if (!rval) + rval = sunos_shmid_put((struct shmid_ds32 __user *)(unsigned long)arg3, &ksds); } else rval = -EFAULT; break; case 2: /* sys_shmdt(): detach a shared memory area */ - rval = sys_shmdt((char *)A(arg1)); + rval = sys_shmdt((char __user *)(unsigned long)arg1); break; case 3: /* sys_shmget(): get a shared memory area */ @@ -1174,11 +1181,11 @@ asmlinkage int sunos_shmsys(int op, u32 arg1, u32 arg2, u32 arg3) return rval; } -extern asmlinkage long sparc32_open(const char * filename, int flags, int mode); +extern asmlinkage long sparc32_open(const char __user * filename, int flags, int mode); asmlinkage int sunos_open(u32 fname, int flags, int mode) { - const char *filename = (const char *)(long)fname; + const char __user *filename = compat_ptr(fname); return sparc32_open(filename, flags, mode); } @@ -1203,64 +1210,60 @@ static inline int check_nonblock(int ret, int fd) return ret; } -extern asmlinkage int sys32_readv(u32 fd, u32 vector, s32 count); -extern asmlinkage int sys32_writev(u32 fd, u32 vector, s32 count); - -asmlinkage int sunos_read(unsigned int fd, u32 buf, u32 count) +asmlinkage int sunos_read(unsigned int fd, char __user *buf, u32 count) { int ret; - ret = check_nonblock(sys_read(fd, (char *)A(buf), count), fd); + ret = check_nonblock(sys_read(fd, buf, count), fd); return ret; } -asmlinkage int sunos_readv(u32 fd, u32 vector, s32 count) +asmlinkage int sunos_readv(u32 fd, void __user *vector, s32 count) { int ret; - ret = check_nonblock(sys32_readv(fd, vector, count), fd); + ret = check_nonblock(compat_sys_readv(fd, vector, count), fd); return ret; } -asmlinkage int sunos_write(unsigned int fd, u32 buf, u32 count) +asmlinkage int sunos_write(unsigned int fd, char __user *buf, u32 count) { int ret; - ret = check_nonblock(sys_write(fd, (char *)A(buf), count), fd); + ret = check_nonblock(sys_write(fd, buf, count), fd); return ret; } -asmlinkage int sunos_writev(u32 fd, u32 vector, s32 count) +asmlinkage int sunos_writev(u32 fd, void __user *vector, s32 count) { int ret; - ret = check_nonblock(sys32_writev(fd, vector, count), fd); + ret = check_nonblock(compat_sys_writev(fd, vector, count), fd); return ret; } -asmlinkage int sunos_recv(int fd, u32 ubuf, int size, unsigned flags) +asmlinkage int sunos_recv(u32 __fd, void __user *ubuf, int size, unsigned flags) { - int ret; + int ret, fd = (int) __fd; - ret = check_nonblock(sys_recv(fd, (void *)A(ubuf), size, flags), fd); + ret = check_nonblock(sys_recv(fd, ubuf, size, flags), fd); return ret; } -asmlinkage int sunos_send(int fd, u32 buff, int len, unsigned flags) +asmlinkage int sunos_send(u32 __fd, void __user *buff, int len, unsigned flags) { - int ret; + int ret, fd = (int) __fd; - ret = check_nonblock(sys_send(fd, (void *)A(buff), len, flags), fd); + ret = check_nonblock(sys_send(fd, buff, len, flags), fd); return ret; } -asmlinkage int sunos_accept(int fd, u32 sa, u32 addrlen) +asmlinkage int sunos_accept(u32 __fd, struct sockaddr __user *sa, int __user *addrlen) { - int ret; + int ret, fd = (int) __fd; while (1) { - ret = check_nonblock(sys_accept(fd, (struct sockaddr *)A(sa), - (int *)A(addrlen)), fd); + ret = check_nonblock(sys_accept(fd, sa, addrlen), fd); if (ret != -ENETUNREACH && ret != -EHOSTUNREACH) break; } @@ -1269,7 +1272,9 @@ asmlinkage int sunos_accept(int fd, u32 sa, u32 addrlen) #define SUNOS_SV_INTERRUPT 2 -asmlinkage int sunos_sigaction (int sig, u32 act, u32 oact) +asmlinkage int sunos_sigaction (int sig, + struct old_sigaction32 __user *act, + struct old_sigaction32 __user *oact) { struct k_sigaction new_ka, old_ka; int ret; @@ -1278,11 +1283,11 @@ asmlinkage int sunos_sigaction (int sig, u32 act, u32 oact) compat_old_sigset_t mask; u32 u_handler; - if (get_user(u_handler, &((struct old_sigaction32 *)A(act))->sa_handler) || - __get_user(new_ka.sa.sa_flags, &((struct old_sigaction32 *)A(act))->sa_flags)) + if (get_user(u_handler, &act->sa_handler) || + __get_user(new_ka.sa.sa_flags, &act->sa_flags)) return -EFAULT; - new_ka.sa.sa_handler = (void *) (long) u_handler; - __get_user(mask, &((struct old_sigaction32 *)A(act))->sa_mask); + new_ka.sa.sa_handler = compat_ptr(u_handler); + __get_user(mask, &act->sa_mask); new_ka.sa.sa_restorer = NULL; new_ka.ka_restorer = NULL; siginitset(&new_ka.sa.sa_mask, mask); @@ -1293,18 +1298,22 @@ asmlinkage int sunos_sigaction (int sig, u32 act, u32 oact) if (!ret && oact) { old_ka.sa.sa_flags ^= SUNOS_SV_INTERRUPT; - if (put_user((long)old_ka.sa.sa_handler, &((struct old_sigaction32 *)A(oact))->sa_handler) || - __put_user(old_ka.sa.sa_flags, &((struct old_sigaction32 *)A(oact))->sa_flags)) + if (put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler) || + __put_user(old_ka.sa.sa_flags, &oact->sa_flags)) return -EFAULT; - __put_user(old_ka.sa.sa_mask.sig[0], &((struct old_sigaction32 *)A(oact))->sa_mask); + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); } return ret; } -asmlinkage int sunos_setsockopt(int fd, int level, int optname, u32 optval, - int optlen) +asmlinkage int sunos_setsockopt(u32 __fd, u32 __level, u32 __optname, + char __user *optval, u32 __optlen) { + int fd = (int) __fd; + int level = (int) __level; + int optname = (int) __optname; + int optlen = (int) __optlen; int tr_opt = optname; int ret; @@ -1313,13 +1322,17 @@ asmlinkage int sunos_setsockopt(int fd, int level, int optname, u32 optval, if (tr_opt >=2 && tr_opt <= 6) tr_opt += 30; } - ret = sys_setsockopt(fd, level, tr_opt, (char *)A(optval), optlen); + ret = sys_setsockopt(fd, level, tr_opt, + optval, optlen); return ret; } -asmlinkage int sunos_getsockopt(int fd, int level, int optname, - u32 optval, u32 optlen) +asmlinkage int sunos_getsockopt(u32 __fd, u32 __level, u32 __optname, + char __user *optval, int __user *optlen) { + int fd = (int) __fd; + int level = (int) __level; + int optname = (int) __optname; int tr_opt = optname; int ret; @@ -1328,6 +1341,7 @@ asmlinkage int sunos_getsockopt(int fd, int level, int optname, if (tr_opt >=2 && tr_opt <= 6) tr_opt += 30; } - ret = compat_sys_getsockopt(fd, level, tr_opt, (void*)(unsigned long)optval, (void*)(unsigned long)optlen); + ret = compat_sys_getsockopt(fd, level, tr_opt, + optval, optlen); return ret; }