Re: struct statfs::f_type too small to carry magic values

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Apr 19, 2013 at 02:23:59PM +0200, Kay Sievers wrote:
> On Fri, Apr 19, 2013 at 2:16 PM, Martin Schwidefsky
> <schwidefsky@xxxxxxxxxx> wrote:
> > On Fri, 19 Apr 2013 13:44:53 +0200 Kay Sievers <kay@xxxxxxxx> wrote:
> >> It's pretty confusing to sort out such issues in userspace, and it
> >> would be nice if it could be fixed to work without weird casting.
> >
> > Well, the easiest fix seem to be to convert the "int f_type" to an
> > "unsigned int f_type".
> 
> That would be nice if that is possible, yeah.

So, I would propose the patch below for the kernel:

>From 74f0609b43b5e9bdac7f97e465a48fd3f72e6611 Mon Sep 17 00:00:00 2001
From: Heiko Carstens <heiko.carstens@xxxxxxxxxx>
Date: Mon, 22 Apr 2013 10:41:27 +0200
Subject: [PATCH] s390/uapi: change struct statfs[64] member types to unsigned
 values

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 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@xxxxxxxx>
Signed-off-by: Heiko Carstens <heiko.carstens@xxxxxxxxxx>
---
 arch/s390/include/asm/compat.h      | 37 +++++++++++++++-------
 arch/s390/include/uapi/asm/statfs.h | 63 +++++++++++++------------------------
 2 files changed, 48 insertions(+), 52 deletions(-)

diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h
index da3df9f..c1e7c64 100644
--- a/arch/s390/include/asm/compat.h
+++ b/arch/s390/include/asm/compat.h
@@ -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
diff --git a/arch/s390/include/uapi/asm/statfs.h b/arch/s390/include/uapi/asm/statfs.h
index 5acca0a..a61d538 100644
--- a/arch/s390/include/uapi/asm/statfs.h
+++ b/arch/s390/include/uapi/asm/statfs.h
@@ -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
-- 
1.7.12.4

--
To unsubscribe from this list: send the line "unsubscribe linux-s390" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Kernel Development]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Info]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Linux Media]     [Device Mapper]

  Powered by Linux