-
-
Notifications
You must be signed in to change notification settings - Fork 32.3k
GH-87804: Fix counter overflow in statvfs on macOS #99570
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
GH-87804: Fix counter overflow in statvfs on macOS #99570
Conversation
On macOS the statvfs interface returns block counts as 32-bit integers, and that results in bad reporting for larger disks. Therefore reimplement statvfs in terms of statfs, which does use 64-bit integers for block counts. Tested using a sparse filesystem image of 100TB.
The conversion from struct statfs to a statvfs value is based on the implementation in Apple's libc, in particular for the reported maximum filename length. I'm not entirely sure if how far back we should back port this. The patch is clean so could easily be back ported to 3.10, but is conceptually a fairly large change. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Patch LGTM. The only thing which I'm doubtful about is the f_flag
field. According to the man pages these are the original statvfs
fields:
ST_MANDLOCK Mandatory locking is permitted on the filesystem (see fcntl(2)).
ST_NOATIME Do not update access times; see mount(2).
ST_NODEV Disallow access to device special files on this filesystem.
ST_NODIRATIME Do not update directory access times; see mount(2).
ST_NOEXEC Execution of programs is disallowed on this filesystem.
ST_NOSUID The set-user-ID and set-group-ID bits are ignored by exec(3) for executable files on this filesystem
ST_RDONLY This filesystem is mounted read-only.
ST_RELATIME Update atime relative to mtime/ctime; see mount(2).
ST_SYNCHRONOUS Writes are synched to the filesystem immediately (see the description of O_SYNC in open(2)).
...and these are macOS fstatfs
's counterparts:
MNT_RDONLY A read-only filesystem
MNT_SYNCHRONOUS File system is written to synchronously
MNT_NOEXEC Can't exec from filesystem
MNT_NOSUID Setuid bits are not honored on this filesystem
MNT_NODEV Don't interpret special files
MNT_UNION Union with underlying filesysten
MNT_ASYNC File system written to asynchronously
MNT_EXPORTED File system is exported File system is stored locally
MNT_QUOTA Quotas are enabled on this file system
MNT_ROOTFS This file system is the root of the file system
MNT_DOVOLFS File system supports volfs
MNT_DONTBROWSE File system is not appropriate path to user data
MNT_UNKNOWNPERMISSIONS VFS will ignore ownership information on filesys-tem filesystem tem objects
MNT_AUTOMOUNTED File system was mounted by automounter
MNT_JOURNALED File system is journaled
MNT_DEFWRITE File system should defer writes
MNT_MULTILABEL MAC support for individual labels
In your PR you rightly map MNT_RDONLY
and MNT_NOSUID
to ST_RDONLY
and ST_NOSUID
(note: you can also map MNT_NOEXEC
to ST_NOEXEC
) , but the other ST_*
flags are lost. I'm not sure if this is appropriate, but perhaps it would make sense to call both statvfs
and fstatfs
, and use the former to fetch all flags.
} | ||
if (st.f_flags & MNT_NOSUID) { | ||
flags |= ST_NOSUID; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In addition to these, I think you can also map MNT_NOEXEC
to ST_NOEXEC
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My current implementation matches that of Apple's emulation, but I agree that it is useful to add a mapping for *_NOEXEC as well.
@ronaldoussoren Do you think you might revisit this? :) |
I am revisiting this. Finally... |
The statvfs implementation on macOS: https://github.com/apple-oss-distributions/Libc/blob/c5a3293354e22262702a3add5b2dfc9bb0b93b85/emulated/statvfs.c#L35 As you can see this implementation does not implement flags other than The current manual page, and SDK headers, only list two flags:
That's another reason to not call |
@Yhg1s and @pablogsal : What's your opinion on back porting this to 3.12 and 3.11? The PR reimplements |
I won't backport to 3.11 and 3.12, the change is too large for that (IMHO) |
Follow up: #115236 |
|
On macOS the statvfs interface returns block counts as 32-bit integers, and that results in bad reporting for larger disks. Therefore reimplement statvfs in terms of statfs, which does use 64-bit integers for block counts. Tested using a sparse filesystem image of 100TB.
On macOS the statvfs interface returns block counts as 32-bit integers, and that results in bad reporting for larger disks.
Therefore reimplement statvfs in terms of statfs, which does use 64-bit integers for block counts.
Tested using a sparse filesystem image of 100TB.