]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/compat.c
V4L/DVB (3309): SAA7134: GPIO IRQ improvements
[linux-2.6-omap-h63xx.git] / fs / compat.c
index 0f7abf246d32c80a6f2c8525809d59082ec35f9f..271b75d1597f507bacbd78b7be31227d5492dd2e 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;
@@ -494,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));
                }
@@ -515,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));
                }
@@ -1170,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;