Hello, I have investigated this issue and verified it on Ubuntu Resolute.
Root cause: The crash happens because safe_du in du, safe_traverse_dir in chmod, and safe_traverse_dir in perms (for chown and chgrp) were using recursive function calls. Each recursive call allocates stack frames with directory descriptors, metadata, and path buffers. On deep directory structures (depths > 2000), the thread stack exceeds the default 8MB limit (ulimit -s 8192), causing an immediate segmentation fault. Fix: I replaced the recursive calls with an iterative heap-allocated stack traversal across all four utilities (du, chmod, chown, chgrp). This changes call stack usage from O(N) to O(1) and prevents stack exhaustion. Testing: I verified the fix on trees with depths of 2000 and 4000 levels. Unpatched binaries crash with SIGSEGV; patched binaries complete with exit code 0. Existing test suites for uu_du, uu_chmod, uu_chown, and uu_chgrp pass without regressions. Upstream pull request submitted for review: https://github.com/uutils/coreutils/pull/14887 I have attached a debdiff for resolute (0.10.0-1ubuntu2~26.04.2) and updated the bug description with the full SRU justification. ** Description changed: + [ Impact ] + In Ubuntu Resolute and Stonking, rust-coreutils provides the core utilities du, chmod, chown, and chgrp. When operating on deeply nested directory trees (depths of ~2000 levels or more), all four utilities crash with Segmentation fault (core dumped) (SIGSEGV). + + The root cause is that directory traversal in du (safe_du), chmod + (safe_traverse_dir), and perms (safe_traverse_dir for chown and chgrp) + was implemented using recursive function calls. Because each stack frame + holds directory descriptors, stat structures, path buffers, and entry + lists, deep trees quickly exceed the Linux default thread stack limit of + 8MB (ulimit -s 8192). + + This is a functional regression compared to GNU coreutils, which + processes deep directory hierarchies without crashing. Any automated + build system, cache tree, or container environment with deep directory + structures triggers this crash. + + [ Fix ] + Replace recursive directory traversal with an iterative heap-allocated stack across all four affected utilities: + - src/uu/du/src/du.rs: Replaced recursive safe_du with an iterative traversal using a heap-allocated Vec<DuFrame> stack (post-order DFS to correctly aggregate subdirectory sizes). + - src/uu/chmod/src/chmod.rs: Replaced recursive safe_traverse_dir in Chmoder with an iterative traversal using a heap-allocated Vec<ChmodFrame> stack (pre-order DFS, preserving cycle detection via ancestors set). + - src/uucore/src/lib/features/perms.rs: Replaced recursive safe_traverse_dir in PerRequest with an iterative traversal using a heap-allocated Vec<PermsFrame> stack (pre-order DFS, preserving cycle detection via ancestors set). + + This keeps CPU call stack usage strictly O(1) regardless of directory + depth, avoiding stack exhaustion. + + [ Test Plan ] + 1. Reproduce on unpatched rust-coreutils (0.10.0-1ubuntu2~26.04.1): + Create a deep directory tree (depth 2000 or more) using openat/mkdirat helpers or gnumkdir: + $ du a + Segmentation fault (core dumped) + $ chmod -R 777 a + Segmentation fault (core dumped) + $ chown -R root:root a + Segmentation fault (core dumped) + $ chgrp -R root a + Segmentation fault (core dumped) + + 2. Verify with patched rust-coreutils (0.10.0-1ubuntu2~26.04.2): + Run the same commands on deep directory trees (tested up to depth 4000): + $ du a + (prints size and directory entries without crash, exit code 0) + $ chmod -R 777 a + (completes without crash, exit code 0) + $ chown -R root:root a + (completes without crash, exit code 0) + $ chgrp -R root a + (completes without crash, exit code 0) + + 3. Run package test suites: + cargo test -p uu_du + cargo test -p uu_chmod + cargo test -p uu_chown + cargo test -p uu_chgrp + All tests pass with 0 regressions. + + [ Where problems could occur ] + The change replaces the call stack with a heap stack for directory traversal. + - File descriptor leaks: Each directory frame maintains its DirFd and closes it when popped from the heap stack. + - Infinite loops / symlink loops: Cycle detection in chmod and perms (chown/chgrp) uses ancestors tracking (HashSet<FileInformation>), which is preserved across push and pop operations on the stack. + - Traversal order: du maintains post-order traversal (children before parents) to aggregate block sizes correctly; chmod and chown/chgrp maintain pre-order traversal (parents before children). + + [ Other Info ] + - Upstream PR: https://github.com/uutils/coreutils/pull/14887 (fixes upstream issue #10173). Pre-commit CI is passing. + - Development branch: Resolute (resolute) is the active development target for rust-coreutils. Target debdiff package version is 0.10.0-1ubuntu2~26.04.2. + - Full test suites pass with 0 regressions. + + --- [ Original Report ] ``` $ podman run --rm -it ubuntu:26.04 $ apt update -y; apt upgrade -y $ ulimit -n 1048576 $ gnumkdir -p $(yes a/ | head -n $((32 * 1024)) | tr -d '\n') $ chown -R root:root a Segmentation fault (core dumped) chown -R root:root a $ chmod -R 777 a Segmentation fault (core dumped) chmod -R 777 a $ chgrp -R root a Segmentation fault (core dumped) chgrp -R root a $ du a Segmentation fault (core dumped) du a ```` All of the GNU programs work fine: ``` $ gnuchown -R root:root a; echo $? 0 $ gnuchmod -R 777 a; echo $? 0 $ gnuchgrp -R 777 a; echo $? 0 $ gnudu a | wc -l 32768 ``` ** Tags added: crash patch regression ** Patch added: "Debdiff for Resolute (0.10.0-1ubuntu2~26.04.2) fixing deep directory traversal stack overflow" https://bugs.launchpad.net/ubuntu/+source/rust-coreutils/+bug/2167204/+attachment/6003084/+files/rust-coreutils_0.10.0-1ubuntu2~26.04.2.debdiff -- You received this bug notification because you are a member of Ubuntu Bugs, which is subscribed to Ubuntu. https://bugs.launchpad.net/bugs/2167204 Title: chown, chmod, chgrp, and du segfault due to recursive calls To manage notifications about this bug go to: https://bugs.launchpad.net/ubuntu/+source/rust-coreutils/+bug/2167204/+subscriptions -- ubuntu-bugs mailing list [email protected] https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs
