compat: sync compat_stats with statfs.
authorEric W. Biederman <ebiederm@xmission.com>
Mon, 17 Oct 2011 20:40:02 +0000 (13:40 -0700)
committerroot <root@serles.lst.de>
Fri, 28 Oct 2011 12:58:53 +0000 (14:58 +0200)
This was found by inspection while tracking a similar
bug in compat_statfs64, that has been fixed in mainline
since decemeber.

- This fixes a bug where not all of the f_spare fields
  were cleared on mips and s390.
- Add the f_flags field to struct compat_statfs
- Copy f_flags to userspace in case someone cares.
- Use __clear_user to copy the f_spare field to userspace
  to ensure that all of the elements of f_spare are cleared.
  On some architectures f_spare is has 5 ints and on some
  architectures f_spare only has 4 ints.  Which makes
  the previous technique of clearing each int individually
  broken.

I don't expect anyone actually uses the old statfs system
call anymore but if they do let them benefit from having
the compat and the native version working the same.

Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
arch/mips/include/asm/compat.h
arch/parisc/include/asm/compat.h
arch/powerpc/include/asm/compat.h
arch/s390/include/asm/compat.h
arch/sparc/include/asm/compat.h
arch/x86/include/asm/compat.h
fs/compat.c

index dbc51065df5b3fe53611ff15e9cc259188ff0dbc..b77df0366ee668296a03896e4ccd096329230dc9 100644 (file)
@@ -111,7 +111,8 @@ struct compat_statfs {
        int             f_bavail;
        compat_fsid_t   f_fsid;
        int             f_namelen;
-       int             f_spare[6];
+       int             f_flags;
+       int             f_spare[5];
 };
 
 #define COMPAT_RLIM_INFINITY   0x7fffffffUL
index efa0b60c63fe683f22629ddd540ed036495cd896..760f331d4fa3e55c70685812a802dd1d2065259c 100644 (file)
@@ -105,7 +105,8 @@ struct compat_statfs {
        __kernel_fsid_t f_fsid;
        s32             f_namelen;
        s32             f_frsize;
-       s32             f_spare[5];
+       s32             f_flags;
+       s32             f_spare[4];
 };
 
 struct compat_sigcontext {
index 91010e8f8479a13fbdf18860d8108d4ac4345379..88e602f6430d0b7575c69d2b109d003adb6d3949 100644 (file)
@@ -100,7 +100,8 @@ struct compat_statfs {
        compat_fsid_t   f_fsid;
        int             f_namelen;      /* SunOS ignores this field. */
        int             f_frsize;
-       int             f_spare[5];
+       int             f_flags;
+       int             f_spare[4];
 };
 
 #define COMPAT_RLIM_OLD_INFINITY       0x7fffffff
index da359ca6fe55efdc9e9aff257622550bf55f008c..cdb9b78f6c082e277f6726344bf8dfebc25f3fe0 100644 (file)
@@ -131,7 +131,8 @@ struct compat_statfs {
        compat_fsid_t   f_fsid;
        s32             f_namelen;
        s32             f_frsize;
-       s32             f_spare[6];
+       s32             f_flags;
+       s32             f_spare[5];
 };
 
 #define COMPAT_RLIM_OLD_INFINITY       0x7fffffff
index 6f57325bb883c5553b4781691cd699952bb90ff8..b8be20d42a0a8b89ab9d6ac261b445b64cbb8d1d 100644 (file)
@@ -134,7 +134,8 @@ struct compat_statfs {
        compat_fsid_t   f_fsid;
        int             f_namelen;      /* SunOS ignores this field. */
        int             f_frsize;
-       int             f_spare[5];
+       int             f_flags;
+       int             f_spare[4];
 };
 
 #define COMPAT_RLIM_INFINITY 0x7fffffff
index 1d9cd27c2920a326e5ac2440ebdbd998d0b925c0..30d737ef2a421e4a457597ae92e28c045f390d0c 100644 (file)
@@ -108,7 +108,8 @@ struct compat_statfs {
        compat_fsid_t   f_fsid;
        int             f_namelen;      /* SunOS ignores this field. */
        int             f_frsize;
-       int             f_spare[5];
+       int             f_flags;
+       int             f_spare[4];
 };
 
 #define COMPAT_RLIM_OLD_INFINITY       0x7fffffff
index 58b1da4598933ca9990494121234be6dcdc35bc0..0f1ab468fa2d489f1a4f67fc5460d4dee5322961 100644 (file)
@@ -247,11 +247,8 @@ static int put_compat_statfs(struct compat_statfs __user *ubuf, struct kstatfs *
            __put_user(kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]) ||
            __put_user(kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]) ||
            __put_user(kbuf->f_frsize, &ubuf->f_frsize) ||
-           __put_user(0, &ubuf->f_spare[0]) || 
-           __put_user(0, &ubuf->f_spare[1]) || 
-           __put_user(0, &ubuf->f_spare[2]) || 
-           __put_user(0, &ubuf->f_spare[3]) || 
-           __put_user(0, &ubuf->f_spare[4]))
+           __put_user(kbuf->f_flags, &ubuf->f_flags) ||
+           __clear_user(ubuf->f_spare, sizeof(ubuf->f_spare)))
                return -EFAULT;
        return 0;
 }