It would be worth stating the details of a filesystem which will cause the problem, and which field is causing the overflow for the customer. From reading the attached cases I assume it's f_files / f_ffree, but please confirm.
This was essentially regressed by commit 64d2ab32efe3 viro had proposed: --- So the whole put_compat_statfs64() thing should be static int put_compat_statfs64(struct compat_statfs64 __user *ubuf, struct kstatfs *kbuf) { struct compat_statfs64 buf; if ((kbuf->f_bsize | kbuf->f_frsize) & 0xffffffff00000000ULL) return -EOVERFLOW; memset(&buf, 0, sizeof(struct compat_statfs64)); buf.f_type = kbuf->f_type; buf.f_bsize = kbuf->f_bsize; buf.f_blocks = kbuf->f_blocks; buf.f_bfree = kbuf->f_bfree; buf.f_bavail = kbuf->f_bavail; buf.f_files = kbuf->f_files; buf.f_ffree = kbuf->f_ffree; buf.f_namelen = kbuf->f_namelen; buf.f_fsid.val[0] = kbuf->f_fsid.val[0]; buf.f_fsid.val[1] = kbuf->f_fsid.val[1]; buf.f_frsize = kbuf->f_frsize; buf.f_flags = kbuf->f_flags; if (copy_to_user(ubuf, &buf, sizeof(struct compat_statfs64))) return -EFAULT; return 0; } and that's it for compat_statfs64 bug ---- but that never went anywhere. Al, did it just get lost or was there some other concern?
Just as a note, RHEL7 kernel-3.10.0-585.el7 and later (i.e. RHEL7.4+) appears to also have this flaw.
Thank you for looking at this. Here are the details I specified in the support ticket. example filesystem was created with a number of inodes that is above the 32-bit integer max...we did this with a 2TB partition created with these options (our customer NAS had a large number of inodes and we were able to reproduce the issue this way) mkfs.xfs -fn ftype=1 -b size=1024 -i maxpct=99 -i size=512 /dev/nvme0n1p3 a simple c++ program reproduces this issue // Simple C++ program to display "Hello World" // Header file for input output functions #include <iostream> #include <sys/statvfs.h> #include <errno.h> using namespace std; // main function - // where the execution of program begins int main() { // prints hello world cout<<"Hello World" << endl; struct statvfs statbuf; int ret = statvfs("/badfs",&statbuf); cout << "errno " << errno << endl; return 0; } [root@e1n1 mkderoy]# g++ test.cpp [root@e1n1 mkderoy]# ./a.out Hello World errno 0 [root@e1n1 mkderoy]# g++ -m32 test.cpp [root@e1n1 mkderoy]# ./a.out Hello World errno 75 and even with largefile support it dies [root@e1n1 mkderoy]# g++ -m32 -D_FILE_OFFSET_BITS=64 test.cpp [root@e1n1 mkderoy]# ./a.out Hello World errno 75 Compiling with -D_FILE_OFFSET_BITS=64 works on Rhel6 and not Rhel7
If the filesystem in question is XFS, and /IF/ the customer isn't actually using nearly 2^32 files, one option may be to use xfs_growfs to reduce the maximum percentage of space which is allowable for inode allocation: -m Specify a new value for the maximum percentage of space in the filesystem that can be allocated as inodes. In mkfs.xfs(8) this is specified with -i maxpct=nn. This will reduce the value reported in f_files and f_ffree, and a sufficiently small percentage value will reduce this to something that doesn't overflow.
I've sent a patch upstream: https://lkml.org/lkml/2019/10/2/891
Created attachment 1622406 [details] updated reproducer Reproducer updated: * test both statfs() and statfs64() * require expected compile-time options * verify that at least one of the 64-bit fields would have overflowed a 32-bit value * success/failure return value # mount -t tmpfs -o nr_inodes=4294967297 tmpfs /mnt # gcc compat_statfs.c -o compat_statfs -m32 -D_FILE_OFFSET_BITS=64 # ./compat_statfs /mnt
merged: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=cc3a7bfe62b947b423fcb2cfe89fcba92bf48fa3 yes, I can do a test build.
The RHEL 7 version of this bug is bz1758001
(In reply to Frank Sorenson from comment #12) > Created attachment 1622406 [details] > updated reproducer > > Reproducer updated: > * test both statfs() and statfs64() ugh. This should have been statfs() and fstatfs()
Patch(es) available on kernel-4.18.0-148.el8
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. https://access.redhat.com/errata/RHSA-2020:1769