s390/uapi: change struct statfs[64] member types to unsigned values
authorHeiko Carstens <heiko.carstens@de.ibm.com>
Mon, 22 Apr 2013 08:41:27 +0000 (10:41 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Tue, 23 Apr 2013 08:18:18 +0000 (10:18 +0200)
Kay Sievers reported that coreutils' stat tool has a problem with
s390's statfs[64] definition:

> The definition of struct statfs::f_type needs a fix. s390 is the only
> architecture in the kernel that uses an int and expects magic
> constants lager than INT_MAX to fit into.
>
> A fix is needed to make Fedora boot on s390, it currently fails to do
> so. Userspace does not want to add code to paper-over this issue.

[...]

> Even coreutils cannot handle it:
>   #define RAMFS_MAGIC  0x858458f6
>   # stat -f -c%t /
>   ffffffff858458f6
>
>   #define BTRFS_SUPER_MAGIC 0x9123683E
>   # stat -f -c%t /mnt
>   ffffffff9123683e

The bug is caused by an implicit sign extension within the stat tool:

out_uint_x (pformat, prefix_len, statfsbuf->f_type);

where the format finally will be "%lx".
A similar problem can be found in the 'tail' tool.
s390 is the only architecture which has an int type f_type member in
struct statfs[64]. Other architectures have either unsigned ints or
long values, so that the problem doesn't occur there.

Therefore change the type of the f_type member to unsigned int, so
that we get zero extension instead of sign extension when assignment to
a long value happens.

This patch changes the s390 uapi struct stafs[64] definition in the kernel
to contain only unsigned values.
This was true for 32 bit builds anyway, since we use the generic uapi
header file in that case. So lets not include conditionally the generic
uapi header file but have the s390 implementation completely independent.

Also fix the types of struct compat_stafs to match reality and move the
definition of struct compat_statfs64 to asm/compat.h since it is not part
of the api.

Reported-by: Kay Sievers <kay@vrfy.org>
Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/include/asm/compat.h
arch/s390/include/uapi/asm/statfs.h

index da3df9f..c1e7c64 100644 (file)
@@ -140,18 +140,33 @@ struct compat_flock64 {
 };
 
 struct compat_statfs {
-       s32             f_type;
-       s32             f_bsize;
-       s32             f_blocks;
-       s32             f_bfree;
-       s32             f_bavail;
-       s32             f_files;
-       s32             f_ffree;
+       u32             f_type;
+       u32             f_bsize;
+       u32             f_blocks;
+       u32             f_bfree;
+       u32             f_bavail;
+       u32             f_files;
+       u32             f_ffree;
        compat_fsid_t   f_fsid;
-       s32             f_namelen;
-       s32             f_frsize;
-       s32             f_flags;
-       s32             f_spare[4];
+       u32             f_namelen;
+       u32             f_frsize;
+       u32             f_flags;
+       u32             f_spare[4];
+};
+
+struct compat_statfs64 {
+       u32             f_type;
+       u32             f_bsize;
+       u64             f_blocks;
+       u64             f_bfree;
+       u64             f_bavail;
+       u64             f_files;
+       u64             f_ffree;
+       compat_fsid_t   f_fsid;
+       u32             f_namelen;
+       u32             f_frsize;
+       u32             f_flags;
+       u32             f_spare[4];
 };
 
 #define COMPAT_RLIM_OLD_INFINITY       0x7fffffff
index 5acca0a..a61d538 100644 (file)
@@ -7,9 +7,6 @@
 #ifndef _S390_STATFS_H
 #define _S390_STATFS_H
 
-#ifndef __s390x__
-#include <asm-generic/statfs.h>
-#else
 /*
  * We can't use <asm-generic/statfs.h> because in 64-bit mode
  * we mix ints of different sizes in our struct statfs.
@@ -21,49 +18,33 @@ typedef __kernel_fsid_t     fsid_t;
 #endif
 
 struct statfs {
-       int  f_type;
-       int  f_bsize;
-       long f_blocks;
-       long f_bfree;
-       long f_bavail;
-       long f_files;
-       long f_ffree;
+       unsigned int    f_type;
+       unsigned int    f_bsize;
+       unsigned long   f_blocks;
+       unsigned long   f_bfree;
+       unsigned long   f_bavail;
+       unsigned long   f_files;
+       unsigned long   f_ffree;
        __kernel_fsid_t f_fsid;
-       int  f_namelen;
-       int  f_frsize;
-       int  f_flags;
-       int  f_spare[4];
+       unsigned int    f_namelen;
+       unsigned int    f_frsize;
+       unsigned int    f_flags;
+       unsigned int    f_spare[4];
 };
 
 struct statfs64 {
-       int  f_type;
-       int  f_bsize;
-       long f_blocks;
-       long f_bfree;
-       long f_bavail;
-       long f_files;
-       long f_ffree;
+       unsigned int    f_type;
+       unsigned int    f_bsize;
+       unsigned long   f_blocks;
+       unsigned long   f_bfree;
+       unsigned long   f_bavail;
+       unsigned long   f_files;
+       unsigned long   f_ffree;
        __kernel_fsid_t f_fsid;
-       int  f_namelen;
-       int  f_frsize;
-       int  f_flags;
-       int  f_spare[4];
+       unsigned int    f_namelen;
+       unsigned int    f_frsize;
+       unsigned int    f_flags;
+       unsigned int    f_spare[4];
 };
 
-struct compat_statfs64 {
-       __u32 f_type;
-       __u32 f_bsize;
-       __u64 f_blocks;
-       __u64 f_bfree;
-       __u64 f_bavail;
-       __u64 f_files;
-       __u64 f_ffree;
-       __kernel_fsid_t f_fsid;
-       __u32 f_namelen;
-       __u32 f_frsize;
-       __u32 f_flags;
-       __u32 f_spare[4];
-};
-
-#endif /* __s390x__ */
 #endif