From 4687d7523bd068bcf0a87ed6ac4e4bfa6f7f4e11 Mon Sep 17 00:00:00 2001 From: Farid Zakaria Date: Sun, 12 Sep 2021 19:04:10 -0700 Subject: [PATCH] glibc: add dependency on netbase /etc/protocols Add an explicit dependency on netbase for /etc/protocols Certain functions in glibc look for files present in /etc such as getprotobyname which reads /etc/protocols. If you are using Nix over a Linux installation, this file may not be present, and therefore it will cause errors. - add netbase as a new package in nixpks - add a dependency in glibc on it using postPatchPhase and substitute the path Fixes #124401 --- doc/builders/packages/etc-files.section.md | 17 +++++++ doc/builders/packages/index.xml | 1 + pkgs/data/misc/iana-etc/default.nix | 18 ++++--- pkgs/development/libraries/glibc/common.nix | 3 ++ .../libraries/glibc/nix-nss-open-files.patch | 51 +++++++++++++++++++ 5 files changed, 84 insertions(+), 6 deletions(-) create mode 100644 doc/builders/packages/etc-files.section.md create mode 100644 pkgs/development/libraries/glibc/nix-nss-open-files.patch diff --git a/doc/builders/packages/etc-files.section.md b/doc/builders/packages/etc-files.section.md new file mode 100644 index 000000000000..0b8379383591 --- /dev/null +++ b/doc/builders/packages/etc-files.section.md @@ -0,0 +1,17 @@ +# /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_. diff --git a/doc/builders/packages/index.xml b/doc/builders/packages/index.xml index f5b05b0bbccf..206e1e49f1f8 100644 --- a/doc/builders/packages/index.xml +++ b/doc/builders/packages/index.xml @@ -17,6 +17,7 @@ + diff --git a/pkgs/data/misc/iana-etc/default.nix b/pkgs/data/misc/iana-etc/default.nix index 60735eb4782c..29ebac848d85 100644 --- a/pkgs/data/misc/iana-etc/default.nix +++ b/pkgs/data/misc/iana-etc/default.nix @@ -1,17 +1,23 @@ -{ lib, fetchzip }: +{ lib, fetchzip, stdenvNoCC, writeText }: let version = "20210225"; -in fetchzip { +in stdenvNoCC.mkDerivation { name = "iana-etc-${version}"; - url = "https://github.com/Mic92/iana-etc/releases/download/${version}/iana-etc-${version}.tar.gz"; - sha256 = "sha256-NVvZG3EJEYOXFDTBXD5m9sg/8msyMiBMkiZr+ZxWZ/g="; + src = fetchzip { + url = "https://github.com/Mic92/iana-etc/releases/download/${version}/iana-etc-${version}.tar.gz"; + sha256 = "sha256:1bbbnj2ya0apyyhnw37521yl1hrz3zy3l8dw6sacmir0y6pmx9gi"; + }; - postFetch = '' - tar -xzvf $downloadedFile --strip-components=1 + installPhase = '' install -D -m0644 -t $out/etc services protocols ''; + setupHook = writeText "setup-hook" '' + export NIX_ETC_PROTOCOLS=@out@/etc/protocols + export NIX_ETC_SERVICES=@out@/etc/services + ''; + meta = with lib; { homepage = "https://github.com/Mic92/iana-etc"; description = "IANA protocol and port number assignments (/etc/protocols and /etc/services)"; diff --git a/pkgs/development/libraries/glibc/common.nix b/pkgs/development/libraries/glibc/common.nix index e651a8effac9..1df1f37cfe9b 100644 --- a/pkgs/development/libraries/glibc/common.nix +++ b/pkgs/development/libraries/glibc/common.nix @@ -120,6 +120,9 @@ stdenv.mkDerivation ({ }) ./fix-x64-abi.patch + + /* https://github.com/NixOS/nixpkgs/pull/137601 */ + ./nix-nss-open-files.patch ] ++ lib.optional stdenv.hostPlatform.isMusl ./fix-rpc-types-musl-conflicts.patch ++ lib.optional stdenv.buildPlatform.isDarwin ./darwin-cross-build.patch; diff --git a/pkgs/development/libraries/glibc/nix-nss-open-files.patch b/pkgs/development/libraries/glibc/nix-nss-open-files.patch new file mode 100644 index 000000000000..9a515c4662e2 --- /dev/null +++ b/pkgs/development/libraries/glibc/nix-nss-open-files.patch @@ -0,0 +1,51 @@ +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 {}; +