Skip to content

du: fix EOVERFLOW on 32-bit Linux - #14548

Open
sylvestre wants to merge 1 commit into
uutils:mainfrom
sylvestre:du-largefile-32bit-fix
Open

sylvestre wants to merge 1 commit into
uutils:mainfrom
sylvestre:du-largefile-32bit-fix

Conversation

@sylvestre

Copy link
Copy Markdown
Contributor

On 32-bit Linux, open(2) without O_LARGEFILE returns EOVERFLOW when directory metadata (inode numbers, sizes) exceed 32-bit off_t limits. This caused du to fail with "Value too large for defined data type" on any directory traversal.

Switch DirFd::open() and DirFd::open_subdir() from nix::fcntl::open/ openat to rustix::fs::openat. The rustix linux_raw backend automatically injects O_LARGEFILE into every open call, fixing the 32-bit overflow without any platform-specific cfg gates.

Add rustix/fs to the safe-traversal feature dependencies.

Fixes #11848

On 32-bit Linux the libc open()/openat() bindings do not add O_LARGEFILE
the way glibc's large-file entry points do, so the kernel rejects a
directory whose metadata overflows the 32-bit ranges with EOVERFLOW. du
then failed with "Value too large for defined data type" on any
directory traversal.

Add the flag to the directory opens in DirFd, and to open_file_at() so a
destination file over 2 GiB does not hit the same wall. It is defined as
0 on 64-bit, so no cfg gating is needed beyond Linux/Android, and the
opens stay on nix: this module deliberately goes through libc so
LD_PRELOAD tools (fakeroot, fakechroot, pseudo) can interpose them.

Fixes uutils#11848
Copilot AI lite review requested due to automatic review settings September 14, 2026 07:55

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Warning

Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.

Pull request overview

Fixes du failures on 32-bit Linux by switching safe directory opens to rustix::fs::openat, which injects O_LARGEFILE to avoid EOVERFLOW when traversing large directories.

Changes:

  • Replace nix::fcntl::open/openat with rustix::fs::openat in DirFd::open and DirFd::open_subdir.
  • Update open flags from nix::fcntl::OFlag to rustix::fs::OFlags and adjust error conversion.
  • Add rustix/fs to the safe-traversal feature dependencies.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/uucore/src/lib/features/safe_traversal.rs Uses rustix::fs::openat for directory opens to ensure O_LARGEFILE behavior on 32-bit Linux.
src/uucore/Cargo.toml Enables rustix/fs under the safe-traversal feature.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/uucore/src/lib/features/safe_traversal.rs
@github-actions

github-actions Bot commented Sep 14, 2026

Copy link
Copy Markdown

GNU testsuite comparison:

Skip an intermittent issue tests/cut/bounded-memory (fails in this run but passes in the 'main' branch)
Skip an intermittent issue tests/date/date-locale-hour (fails in this run but passes in the 'main' branch)
Skip an intermittent issue tests/pr/bounded-memory (fails in this run but passes in the 'main' branch)

@codspeed-hq

codspeed-hq Bot commented Sep 14, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 180 untouched benchmarks
⏩ 237 skipped benchmarks1


Comparing sylvestre:du-largefile-32bit-fix (80e10f0) with main (b6726cc)2

Open in CodSpeed

Footnotes

  1. 237 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on main (a5891bc) during the generation of this report, so b6726cc was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

Copilot AI review requested due to automatic review settings September 14, 2026 12:04
@sylvestre
sylvestre force-pushed the du-largefile-32bit-fix branch from c6c706f to 4dfce47 Compare September 14, 2026 12:04

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

Both rustix openat paths bypass required LD_PRELOAD interposition and need an interposable large-file-safe alternative.

Review details

Suppressed comments (2)

src/uucore/src/lib/features/safe_traversal.rs:185

  • The subdirectory path has the same regression: rustix's Linux-raw openat bypasses the LD_PRELOAD wrappers that this module explicitly supports for fakeroot/fakechroot/pseudo. Keep this operation libc-interposable, or provide an equivalent large-file-safe libc path on 32-bit Linux.
        let fd = rustix_openat(
            &self.fd,
            name_cstr.as_c_str(),
            flags,
            rustix::fs::Mode::empty(),
        )
        .map_err(|e| SafeTraversalError::OpenFailed {
            path: name.into(),
            source: io::Error::from_raw_os_error(e.raw_os_error()),

src/uucore/src/lib/features/safe_traversal.rs:156

  • This changes DirFd::open from libc-backed nix::open to rustix's Linux-raw syscall, so fakeroot/fakechroot/pseudo LD_PRELOAD wrappers cannot see or emulate this path. The same module deliberately keeps chmod_at on nix for this reason (lines 303-326); preserve interposition here while still arranging O_LARGEFILE for 32-bit Linux.
        let fd = rustix_openat(rustix::fs::CWD, path, flags, rustix::fs::Mode::empty()).map_err(
            |e| SafeTraversalError::OpenFailed {
                path: path.into(),
                source: io::Error::from_raw_os_error(e.raw_os_error()),
            },
        )?;
  • Files reviewed: 2/2 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

@sylvestre
sylvestre force-pushed the du-largefile-32bit-fix branch from 4dfce47 to 80e10f0 Compare September 14, 2026 13:35
Copilot AI review requested due to automatic review settings September 14, 2026 13:35

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Two moderate test-coverage issues and one implementation/description mismatch remain unresolved.

Get a fresh assessment by requesting another Copilot review.

Review details

Suppressed comments (2)

src/uucore/src/lib/features/safe_traversal.rs:1050

  • This regression test is in uucore's unit-test module, but the i686 CI jobs run cargo test -p coreutils while only selected jobs add --workspace; it therefore is not executed on the 32-bit target where O_LARGEFILE is nonzero. Add a target-run regression (or run the uucore tests for i686) so removing this flag cannot pass CI.
    #[test]
    #[cfg(any(target_os = "linux", target_os = "android"))]
    fn test_dirfd_open_status_flags_match_std() {

src/uucore/src/lib/features/safe_traversal.rs:482

  • The new LARGEFILE behavior for open_file_at is not covered by test_dirfd_open_status_flags_match_std, which only inspects directory descriptors. Add a corresponding open_file_at flag/behavior assertion on 32-bit Linux, or drop this extra hunk if large destination files are not part of this fix.
            | OFlag::O_NOFOLLOW
            | LARGEFILE;
  • Files reviewed: 1/1 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment on lines +144 to +147
#[cfg(any(target_os = "linux", target_os = "android"))]
const LARGEFILE: OFlag = OFlag::O_LARGEFILE;
#[cfg(not(any(target_os = "linux", target_os = "android")))]
const LARGEFILE: OFlag = OFlag::empty();
@sylvestre sylvestre changed the title du: fix EOVERFLOW on 32-bit Linux via rustix openat du: fix EOVERFLOW on 32-bit Linux Sep 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

du: "Value too large for defined data type" for directories on 32-bit architectures (0.8.0 regression)

2 participants