Observations: When I call `busybox id` with EUID=0 and RUID!=0 it behaves as if EUID=RUID!=0. It prints: uid=1000(regular) gid=100(users) groups=100(users) When I expect (and coreutils id prints): uid=1000(regular) gid=100(users) euid=0(root) groups=100(users) I use NixOS, which makes .config slightly tiresome to extract. You can find the templates bash script used to generate it at https://github.com/NixOS/nixpkgs/blob/8982f61dd3b58d5520705082069828d87e9fcefc/pkgs/os-specific/linux/busybox/default.nix#L97. Please let me know if you want the exact .config that was used to build my busybox and I will do the slightly tiresome thing. How to reproduce: The easiest way to call something in this fashion is to write a trivial wrapper in C (that just calls execve with appropriate arguments), make it SUID and owned by root, and run it. What I think is happening: Busybox applets declare "bb_suid_t" in their declarations, so that they can define their expectations around EUID to handle cases when busybox binary is SUID. There are three available values: - BB_SUID_DROP -- always set EUID to RUID before starting the applet, - BB_SUID_MAYBE -- do nothing, - BB_SUID_REQUIRE -- fail unless EUID==0. The id applet declares itself to be of BB_SUID_DROP type. This means that _even if busybox is not SUID_, we will set EUID to RUID before running the applet. Suggestions: If the busybox binary _is_ SUID, we are unable to do anything useful here, because the EUID of the caller is destroyed when busybox is execed. If the busybox binary is not SUID, we are making an unforced mistake here: we are destroying the EUID information, which is correct. I would suggest that in handling of BB_SUID_DROP, we detect whether /proc/self/exe is SUID and do not do anything if it isn't. I don't know what I'd expect to happen for busybox binaries that _are_ SUID, given that it's impossible to implement the correct behaviour.
I've realized that CONFIG_FEATURE_SUID exists, that unsetting it makes the issue go away, and that it's set by default (and not unset by my configuration). Likely it makes sense to disable it in NixOS. However, we could still improve the (common?) case of busybox not being SUID but compiled with the default value of that option.