fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / arch / sparc64 / kernel / sys_sunos32.c
index 0ed11ea..2ebc2c0 100644 (file)
@@ -12,6 +12,7 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/types.h>
+#include <linux/capability.h>
 #include <linux/compat.h>
 #include <linux/mman.h>
 #include <linux/mm.h>
@@ -42,6 +43,7 @@
 #include <asm/idprom.h> /* for gethostid() */
 #include <asm/unistd.h>
 #include <asm/system.h>
+#include <asm/compat_signal.h>
 
 /* For the nfs mount emulation */
 #include <linux/socket.h>
@@ -81,7 +83,7 @@ asmlinkage u32 sunos_mmap(u32 addr, u32 len, u32 prot, u32 flags, u32 fd, u32 of
                file = fget(fd);
                if (!file)
                        goto out;
-               inode = file->f_dentry->d_inode;
+               inode = file->f_path.dentry->d_inode;
                if (imajor(inode) == MEM_MAJOR && iminor(inode) == 5) {
                        flags |= MAP_ANONYMOUS;
                        fput(file);
@@ -142,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)
@@ -154,7 +156,7 @@ asmlinkage int sunos_brk(u32 baddr)
         * simple, it hopefully works in most obvious cases.. Easy to
         * fool it, but this should catch most mistakes.
         */
-       freepages = get_page_cache_size();
+       freepages = global_page_state(NR_FILE_PAGES);
        freepages >>= 1;
        freepages += nr_free_pages();
        freepages += nr_swap_pages;
@@ -279,19 +281,24 @@ static int sunos_filldir(void * __buf, const char * name, int namlen,
        struct sunos_dirent __user *dirent;
        struct sunos_dirent_callback * buf = (struct sunos_dirent_callback *) __buf;
        int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
+       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->curr;
        buf->previous = dirent;
-       put_user(ino, &dirent->d_ino);
+       put_user(d_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 __user *) dirent + reclen;
        buf->curr = dirent;
@@ -361,17 +368,22 @@ static int sunos_filldirentry(void * __buf, const char * name, int namlen,
        struct sunos_direntry_callback * buf =
                (struct sunos_direntry_callback *) __buf;
        int reclen = ROUND_UP(NAME_OFFSET(dirent) + namlen + 1);
+       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;
        dirent = buf->curr;
        buf->previous = dirent;
-       put_user(ino, &dirent->d_ino);
+       put_user(d_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 __user *) dirent + reclen;
        buf->curr = dirent;
@@ -436,16 +448,16 @@ asmlinkage int sunos_uname(struct sunos_utsname __user *name)
        int ret;
 
        down_read(&uts_sem);
-       ret = copy_to_user(&name->sname[0], &system_utsname.sysname[0],
+       ret = copy_to_user(&name->sname[0], &utsname()->sysname[0],
                           sizeof(name->sname) - 1);
-       ret |= copy_to_user(&name->nname[0], &system_utsname.nodename[0],
+       ret |= copy_to_user(&name->nname[0], &utsname()->nodename[0],
                            sizeof(name->nname) - 1);
        ret |= put_user('\0', &name->nname[8]);
-       ret |= copy_to_user(&name->rel[0], &system_utsname.release[0],
+       ret |= copy_to_user(&name->rel[0], &utsname()->release[0],
                            sizeof(name->rel) - 1);
-       ret |= copy_to_user(&name->ver[0], &system_utsname.version[0],
+       ret |= copy_to_user(&name->ver[0], &utsname()->version[0],
                            sizeof(name->ver) - 1);
-       ret |= copy_to_user(&name->mach[0], &system_utsname.machine[0],
+       ret |= copy_to_user(&name->mach[0], &utsname()->machine[0],
                            sizeof(name->mach) - 1);
        up_read(&uts_sem);
        return (ret ? -EFAULT : 0);
@@ -465,7 +477,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) {
@@ -603,7 +615,7 @@ sunos_nfs_get_server_fd (int fd, struct sockaddr_in *addr)
        if (!file)
                return 0;
 
-       inode = file->f_dentry->d_inode;
+       inode = file->f_path.dentry->d_inode;
 
        socket = SOCKET_I(inode);
        local.sin_family = AF_INET;
@@ -852,7 +864,7 @@ 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;
@@ -1043,7 +1055,7 @@ asmlinkage int sunos_msgsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
                break;
        case 2:
                rval = -EFAULT;
-               kmbuf = (struct msgbuf *)kmalloc(sizeof(struct msgbuf) + arg3,
+               kmbuf = kmalloc(sizeof(struct msgbuf) + arg3,
                                                 GFP_KERNEL);
                if (!kmbuf)
                        break;
@@ -1066,7 +1078,7 @@ asmlinkage int sunos_msgsys(int op, u32 arg1, u32 arg2, u32 arg3, u32 arg4)
                break;
        case 3:
                rval = -EFAULT;
-               kmbuf = (struct msgbuf *)kmalloc(sizeof(struct msgbuf) + arg3,
+               kmbuf = kmalloc(sizeof(struct msgbuf) + arg3,
                                                 GFP_KERNEL);
                if (!kmbuf || sunos_msgbuf_get((struct msgbuf32 __user *)(unsigned long)arg2,
                                               kmbuf, arg3))
@@ -1175,11 +1187,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);
 }
@@ -1280,7 +1292,7 @@ asmlinkage int sunos_sigaction (int sig,
                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;
+               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;
@@ -1292,7 +1304,7 @@ asmlinkage int sunos_sigaction (int sig,
 
        if (!ret && oact) {
                old_ka.sa.sa_flags ^= SUNOS_SV_INTERRUPT;
-               if (put_user((long)old_ka.sa.sa_handler, &oact->sa_handler) ||
+               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], &oact->sa_mask);