]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/compat.c
Merge master.kernel.org:/pub/scm/linux/kernel/git/tmlind/linux-omap-upstream
[linux-2.6-omap-h63xx.git] / fs / compat.c
index a719e158e0021dd877525d2b966d458bc350aada..2468ac1df2f04cf5cfc1bde19b4924c9f135ce09 100644 (file)
@@ -168,8 +168,8 @@ asmlinkage long compat_sys_statfs(const char __user *path, struct compat_statfs
        if (!error) {
                struct kstatfs tmp;
                error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp);
-               if (!error && put_compat_statfs(buf, &tmp))
-                       error = -EFAULT;
+               if (!error)
+                       error = put_compat_statfs(buf, &tmp);
                path_release(&nd);
        }
        return error;
@@ -186,8 +186,8 @@ asmlinkage long compat_sys_fstatfs(unsigned int fd, struct compat_statfs __user
        if (!file)
                goto out;
        error = vfs_statfs(file->f_dentry->d_inode->i_sb, &tmp);
-       if (!error && put_compat_statfs(buf, &tmp))
-               error = -EFAULT;
+       if (!error)
+               error = put_compat_statfs(buf, &tmp);
        fput(file);
 out:
        return error;
@@ -236,8 +236,8 @@ asmlinkage long compat_sys_statfs64(const char __user *path, compat_size_t sz, s
        if (!error) {
                struct kstatfs tmp;
                error = vfs_statfs(nd.dentry->d_inode->i_sb, &tmp);
-               if (!error && put_compat_statfs64(buf, &tmp))
-                       error = -EFAULT;
+               if (!error)
+                       error = put_compat_statfs64(buf, &tmp);
                path_release(&nd);
        }
        return error;
@@ -257,8 +257,8 @@ asmlinkage long compat_sys_fstatfs64(unsigned int fd, compat_size_t sz, struct c
        if (!file)
                goto out;
        error = vfs_statfs(file->f_dentry->d_inode->i_sb, &tmp);
-       if (!error && put_compat_statfs64(buf, &tmp))
-               error = -EFAULT;
+       if (!error)
+               error = put_compat_statfs64(buf, &tmp);
        fput(file);
 out:
        return error;
@@ -268,7 +268,6 @@ out:
 
 #define IOCTL_HASHSIZE 256
 static struct ioctl_trans *ioctl32_hash_table[IOCTL_HASHSIZE];
-static DECLARE_RWSEM(ioctl32_sem);
 
 extern struct ioctl_trans ioctl_start[];
 extern int ioctl_table_size;
@@ -390,14 +389,10 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
                break;
        }
 
-       /* When register_ioctl32_conversion is finally gone remove
-          this lock! -AK */
-       down_read(&ioctl32_sem);
        for (t = ioctl32_hash_table[ioctl32_hash(cmd)]; t; t = t->next) {
                if (t->cmd == cmd)
                        goto found_handler;
        }
-       up_read(&ioctl32_sem);
 
        if (S_ISSOCK(filp->f_dentry->d_inode->i_mode) &&
            cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) {
@@ -417,11 +412,9 @@ asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
                lock_kernel();
                error = t->handler(fd, cmd, arg, filp);
                unlock_kernel();
-               up_read(&ioctl32_sem);
                goto out_fput;
        }
 
-       up_read(&ioctl32_sem);
  do_ioctl:
        error = vfs_ioctl(filp, fd, cmd, arg);
  out_fput:
@@ -501,9 +494,21 @@ asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd,
                ret = sys_fcntl(fd, cmd, (unsigned long)&f);
                set_fs(old_fs);
                if (cmd == F_GETLK && ret == 0) {
-                       if ((f.l_start >= COMPAT_OFF_T_MAX) ||
-                           ((f.l_start + f.l_len) > COMPAT_OFF_T_MAX))
+                       /* GETLK was successfule and we need to return the data...
+                        * but it needs to fit in the compat structure.
+                        * l_start shouldn't be too big, unless the original
+                        * start + end is greater than COMPAT_OFF_T_MAX, in which
+                        * case the app was asking for trouble, so we return
+                        * -EOVERFLOW in that case.
+                        * l_len could be too big, in which case we just truncate it,
+                        * and only allow the app to see that part of the conflicting
+                        * lock that might make sense to it anyway
+                        */
+
+                       if (f.l_start > COMPAT_OFF_T_MAX)
                                ret = -EOVERFLOW;
+                       if (f.l_len > COMPAT_OFF_T_MAX)
+                               f.l_len = COMPAT_OFF_T_MAX;
                        if (ret == 0)
                                ret = put_compat_flock(&f, compat_ptr(arg));
                }
@@ -522,9 +527,11 @@ asmlinkage long compat_sys_fcntl64(unsigned int fd, unsigned int cmd,
                                (unsigned long)&f);
                set_fs(old_fs);
                if (cmd == F_GETLK64 && ret == 0) {
-                       if ((f.l_start >= COMPAT_LOFF_T_MAX) ||
-                           ((f.l_start + f.l_len) > COMPAT_LOFF_T_MAX))
+                       /* need to return lock information - see above for commentary */
+                       if (f.l_start > COMPAT_LOFF_T_MAX)
                                ret = -EOVERFLOW;
+                       if (f.l_len > COMPAT_LOFF_T_MAX)
+                               f.l_len = COMPAT_LOFF_T_MAX;
                        if (ret == 0)
                                ret = put_compat_flock64(&f, compat_ptr(arg));
                }
@@ -1177,7 +1184,7 @@ static ssize_t compat_do_readv_writev(int type, struct file *file,
        }
 
        ret = rw_verify_area(type, file, pos, tot_len);
-       if (ret)
+       if (ret < 0)
                goto out;
 
        fnv = NULL;
@@ -1490,7 +1497,6 @@ int compat_do_execve(char * filename,
                /* execve success */
                security_bprm_free(bprm);
                acct_update_integrals(current);
-               update_mem_hiwater(current);
                kfree(bprm);
                return retval;
        }
@@ -1531,7 +1537,7 @@ out_ret:
  * Ooo, nasty.  We need here to frob 32-bit unsigned longs to
  * 64-bit unsigned longs.
  */
-static inline
+static
 int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
                        unsigned long *fdset)
 {
@@ -1564,7 +1570,7 @@ int compat_get_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
        return 0;
 }
 
-static inline
+static
 void compat_set_fd_set(unsigned long nr, compat_ulong_t __user *ufdset,
                        unsigned long *fdset)
 {