Skip to content

id: rustix crate bypasses libc breaking LD_PRELOAD based tools #13399

Open

Description

@BAMF0

Problem

  • 37c42a2 replaced the nix crate with rustix for id.
  • rustix uses raw syscalls for functions such as getuid(), rather than the libc wrapper.
  • Tools like fakeroot rely on the libc wrapper to intercept function calls using LD_PRELOAD in order to return fake values.

Reproduce

  1. Build uutils/coreutils version 0.9.0 using the release profile
  2. Install fakeroot:
# Debian / Ubuntu 
sudo apt install fakeroot

# Fedora / RHEL
sudo dnf install fakeroot

# Arch Linux
sudo pacman -S fakeroot
  1. Run the built id:
id

Output:

1000
  1. Run fakeroot against the built id:
fakeroot ./target/release/coreutils id -u

Output:

1000

Expected behavior

fakeroot should be able to intercept the id command and instead print:

0

as if it were root.

Activity

  1. oech3 commented on Jul 14, 2026

    @oech3
    Contributor

    Build with --cfg=use-libc as a workaround. I don't want to do that at upstream for performance if possible.
    I think it is fakeroot's bug (lacking support for static musl binary). Is there any chance for fixing fakeroot to use ptrace?

  2. BAMF0 commented on Jul 14, 2026

    @BAMF0
    ContributorAuthor

    Build with --cfg=use-libc as a workaround. I don't want to do that at upstream for performance if possible.
    I think it is fakeroot's bug (lacking support for static musi binary). Is there any chance for fixing fakeroot to use ptrace?

    Thanks for the tip! I think that's reasonable – it's a bit of an unnecessary overhead yeah.

    I kind of agree that it's fakeroot's bug. I'll check whether we can ergonomically use something like ptrace() instead.

  3. xtqqczze commented on Jul 14, 2026

    @xtqqczze
    Collaborator

    Build with --cfg=use-libc as a workaround. I don't want to do that at upstream for performance if possible.

    I think we should build with use-libc by default unless we can demonstrate a measurable performance benefit from using the linux_raw backend.

  4. oech3 commented on Jul 14, 2026

    @oech3
    Contributor
  5. xtqqczze commented on Jul 16, 2026

    @xtqqczze
    Collaborator

    I kind of agree that it's fakeroot's bug. I'll check whether we can ergonomically use something like ptrace() instead.

    fakeroot-ng uses ptrace(2) instead of LD_PRELOAD.

  6. BAMF0 commented on Jul 16, 2026

    @BAMF0
    ContributorAuthor

    I kind of agree that it's fakeroot's bug. I'll check whether we can ergonomically use something like ptrace() instead.

    fakeroot-ng uses ptrace(2) instead of LD_PRELOAD.

    Interesting! I was not aware that fakeroot had an -ng version. Sadly it seems like it has been removed from the Debian archive.

  7. oech3 commented on Jul 16, 2026

    @oech3
    Contributor

    fakeroot is actively maintained while -ng is not. I think we should just fix fakeroot in the case.

  8. BAMF0 commented on Jul 17, 2026

    @BAMF0
    ContributorAuthor

    For the time being, we will use rustix with the libc backend on Ubuntu as that currently provides the easiest compatibility for the current tooling. I think we can feel free to close this issue since that is a solution to the problem.

    It might be worth to document somewhere for future reference that the migrations to rustix and its linux_raw backend will prevent things like function interposition with libc for uutils coreutils. However I would expect this issue to be quite niche and small since it only affects packages that rely on the LD_PRELOAD hack against libc in conjunction with calling utils that rely on those same functions.

  9. xtqqczze commented on Jul 17, 2026

    @xtqqczze
    Collaborator

    It would definitely be worth documenting that using the linux_raw backend prevents a documented feature like LD_PRELOAD function interposition from working. It’s may well be a niche incompatibility, but LD_PRELOAD is a documented and well-established feature, so users are unlikely to expect this behavior.

  10. oech3 commented on Sep 30, 2026

    @oech3
    Contributor

    related: #7967 (which is more serious and mostly impossible to fix at both of our side and other utils's side).

  11. mvanhorn commented on Oct 12, 2026

    @mvanhorn
    Contributor

    On Linux, rustix's raw syscall backend performs the affected calls without entering libc, so an interceptor loaded with LD_PRELOAD never sees them. id uses that backend, and the choice is fixed when the binary is compiled.

    The build section of README.md and the packaging guide now explain that this backend skips libc interposition, with fakeroot and id -u as the case that still reports the real UID.

    #15261

  12. oech3 commented on Oct 12, 2026

    @oech3
    Contributor

    While I really don't like this, I'm fine with using libc at id only since it is easy and fakeroot is widely used. But new apps should not use LD_PRELOAD and we should not support LD_PRELOAD for new apps.

  13. oech3 commented on Oct 17, 2026

    @oech3
    Contributor

    I'm not sure if we can close this just by doc.

  14. mvanhorn commented on Oct 17, 2026

    @mvanhorn
    Contributor

    Agreed. Documentation makes the limitation explicit, but it does not make existing fakeroot/LD_PRELOAD workflows work with the linux_raw backend. We should keep this open until we either have a supported compatibility path or decide that using the libc backend for id is the long-term resolution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions