Change:
Describe the bug Certain functions in glibc look for files present in /etc such as which reads . If you are using Nix over a Linux installation, this file may not be present, and therefore it will cause errors. Nix should strive to be as reproducible and hermetic as possible. Rather than looking for the files at /etc, glibc should be patched to look for these files in the /nix/store; very similar to how Nix does LOCALARCHIVE. Right now the guidance is to use libredirect () which seems unfortunate and annoying to users. Useful links: Notify maintainers I did not see any explicit maintainers, so tagged a few from the history of the file.
Is this file not supposed to be configurable? Or do you mean there should be environment variables to redirect it?
The file in glibc is hardcoded. For instance on a Debian installation you must have . Ultimately shouldn't everything be self-contained to the /nix/store ? Seems like it's less of a problem on NixOS but on Nix on other Linux distributions it should reading from another nixpkg similar to LOCAL_ARCHIVE.
I think that adding such variables should only be done very carefully. I suspect there are some reasons for restricting some of these (say, LDLIBRARYPATH) in setuid binaries, and we might just be adding a security hole this way (a small-ish one if any, I expect, but still).
I'm not really following your logic reading files outside of the /nix/store and relying on the environment though is antithesis to the concept of Nix and it's versioning. I think this aligns close to many other similar patches such as that to clang/gcc to not read from default library paths or the locales as mentioned.
is runtime configuration data, just like or or . You don't want to rebuild the entire system just to change . Now, in practice nobody ever changes so we could get away with hard-coding it, but it would be a bit fishy. The same applies to BTW.
I don't expect people really need to change this often in practice and years old version would typically suffice, but for those reasons I understand that it may be appealing to add runtime configurability by an environment variable (and keep the same default if it's not defined).
And the potential risks I know about should be fixable by copy&paste of the usual setuid checks (like for LDLIBRARYPATH). Using setuid for nix-built executables on non-NixOS is probably not common anyway. Maybe just... the overall design of these customizations could be given some more thought.
See also , which proposes adding an environment variable for the NSS search path, and which proposes a generic environment variable.
I guess rather than hardcode, I am advocating for something similar to make an environment variable override. It's just a bummer than out-of-the-box on Debian, Nix can cause failures since glibc does not find these files. Maybe a fallback to an entry in the /nix/store ? I'll read the pivot link thanks.
Uh, I wonder what Debian's glibc does then. Any package with a binary using these syscalls should declare a dependency on ?
That's my understanding; and-or it's brought in eventually and the problem stabilizes. (That non-determinism seems perfect for Nix to solve)
We might also make depend on on Debian :trollface: (say, for the short term)
It might be worth noting that go in nixpkgs actually does hardcode this, since . Maybe that has been reverted at some point, but when I looked into this () it was still the case.
Interesting; well that's only for golang built binaries in Nixpkgs. Should I put time on this for a patch or is there a broader discussion here that is more well suited for an RFC?
No. just make a PR.
PR incoming today.
Wow; I spent time trying to dig through the glibc code -- intense. The getproto code is very macro heavy
The glibc code quality is quite bad. Mainly because of one former long-term maintainer. helps to expand/understand macros.
:( I really wanted to patch it. Maybe I'll give it another shot to walk the macros later ...
If it's runtime configuration data, oughtn't we include it in the sandbox?

Discussion:
<ins> # /etc files {#etc} Certain calls in glibc require access to runtime files found in /etc such as `/etc/protocols` or `/etc/services` -- [getprotobyname](https://linux.die.net/man/3/getprotobyname) is one such function. On non-NixOS distributions these files are typically provided by packages (i.e. [netbase](https://packages.debian.org/sid/netbase)) if not already pre-installed in your distribution. This can cause non-reproducibility for code if they rely on these files being present. If [iana-etc](https://hydra.nixos.org/job/nixos/trunk-combined/nixpkgs.iana-etc.x86_64-linux) is part of your _buildInputs_ then it will set the environment varaibles `NIX_ETC_PROTOCOLS` and `NIX_ETC_SERVICES` to the corresponding files in the package through a _setup-hook_. ```bash ❯ nix-shell -p iana-etc [nix-shell:~]$ env | grep NIX_ETC NIX_ETC_SERVICES=/nix/store/aj866hr8fad8flnggwdhrldm0g799ccz-iana-etc-20210225/etc/services NIX_ETC_PROTOCOLS=/nix/store/aj866hr8fad8flnggwdhrldm0g799ccz-iana-etc-20210225/etc/protocols ``` Nixpkg's version of [glibc](https://hydra.nixos.org/job/nixos/trunk-combined/nixpkgs.glibc.x86_64-linux) has been patched to check for the existence of these environment variables. If the environment variable are *not set*, then it will attempt to find the files at the default location within _/etc_. </ins>

<xi:include href="kakoune.section.xml" /> <xi:include href="linux.section.xml" /> <xi:include href="locales.section.xml" /> <ins> <xi:include href="etc-files.section.xml" /> </ins> <xi:include href="nginx.section.xml" /> <xi:include href="opengl.section.xml" /> <xi:include href="shell-helpers.section.xml" />

<del> { lib, fetchzip }: </del> <ins> { lib, fetchzip, stdenvNoCC, writeText }: </ins> let version = "20210225"; <del> in fetchzip { </del> <ins> in stdenvNoCC.mkDerivation { </ins> name = "iana-etc-${version}"; <del> url = "https://github.com/Mic92/iana-etc/releases/download/${version}/iana-etc-${version}.tar.gz"; sha256 = "sha256-NVvZG3EJEYOXFDTBXD5m9sg/8msyMiBMkiZr+ZxWZ/g="; </del> <ins> src = fetchzip { url = "https://github.com/Mic92/iana-etc/releases/download/${version}/iana-etc-${version}.tar.gz"; sha256 = "sha256:1bbbnj2ya0apyyhnw37521yl1hrz3zy3l8dw6sacmir0y6pmx9gi"; }; </ins> <del> postFetch = '' tar -xzvf $downloadedFile --strip-components=1 </del> <ins> installPhase = '' </ins> install -D -m0644 -t $out/etc services protocols ''; <ins> setupHook = writeText "setup-hook" '' export NIX_ETC_PROTOCOLS=@out@/etc/protocols export NIX_ETC_SERVICES=@out@/etc/services ''; </ins> meta = with lib; { homepage = "https://github.com/Mic92/iana-etc"; description = "IANA protocol and port number assignments (/etc/protocols and /etc/services)";

}) ./fix-x64-abi.patch <ins> /* https://github.com/NixOS/nixpkgs/pull/137601 */ ./nix-nss-open-files.patch </ins> ] ++ lib.optional stdenv.hostPlatform.isMusl ./fix-rpc-types-musl-conflicts.patch ++ lib.optional stdenv.buildPlatform.isDarwin ./darwin-cross-build.patch;

<ins> diff --git a/nss/nss_files/files-XXX.c b/nss/nss_files/files-XXX.c index 1db9e46127..3a567e0224 100644 --- a/nss/nss_files/files-XXX.c +++ b/nss/nss_files/files-XXX.c @@ -75,8 +75,20 @@ internal_setent (FILE **stream) if (*stream == NULL) { -      *stream = __nss_files_fopen (DATAFILE); - +      const char *file = DATAFILE; + +      #ifdef NIX_DATAFILE +      // use the Nix environment variable such as `NIX_ETC_PROTOCOLS` +      char *path = secure_getenv (NIX_DATAFILE); + +      // if the environment variable is set, then read from the /nix/store entry instead +      if (path && path[0]) { +        file = path; +      } +      #endif + +      *stream = __nss_files_fopen (file); + if (*stream == NULL) status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL; } diff --git a/nss/nss_files/files-proto.c b/nss/nss_files/files-proto.c index c30bedc0aa..b321e68d3c 100644 --- a/nss/nss_files/files-proto.c +++ b/nss/nss_files/files-proto.c @@ -23,6 +23,7 @@ NSS_DECLARE_MODULE_FUNCTIONS (files) #define ENTNAME		protoent #define DATABASE	"protocols" +#define NIX_DATAFILE "NIX_ETC_PROTOCOLS" struct protoent_data {}; diff --git a/nss/nss_files/files-service.c b/nss/nss_files/files-service.c index bfc2590699..0bff36aee5 100644 --- a/nss/nss_files/files-service.c +++ b/nss/nss_files/files-service.c @@ -24,6 +24,7 @@ NSS_DECLARE_MODULE_FUNCTIONS (files) #define ENTNAME		servent #define DATABASE	"services" +#define NIX_DATAFILE "NIX_ETC_SERVICES" struct servent_data {}; </ins>