This change is prompted by the following, admittedly cursed tarball:
```
> curl https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz 2>/dev/null \
| tar -ztv
drw-rw-rw- 0/0 0 2020-02-18 10:50 package
-rw-rw-rw- 0/0 297 2020-02-18 10:50 package/index.d.ts
-rw-rw-rw- 0/0 1920 2020-02-18 10:50 package/index.js
-rw-rw-rw- 0/0 1092 2020-01-31 11:31 package/LICENSE
-rw-rw-rw- 0/0 937 2020-02-18 10:51 package/package.json
-rw-rw-rw- 0/0 713 2020-02-18 10:50 package/README.md
```
The minimal reproducer for the issue is the following derivation trying
to work around the uid 0 issue with `dontMakeSourcesWritable = true`:
```nix
{ stdenv, fetchurl }:
stdenv.mkDerivation {
name = "test";
src = fetchurl {
sha1 = "d744358226217f981ed58f479b1d6bcc29545dcf";
url = "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz";
};
dontMakeSourcesWritable = true;
installPhase = ''
cp -R . $out
'';
}
```
This currently fails in the following way:
```
these derivations will be built:
/nix/store/pc3jbydl0xcc8nrndf5xkf7hdhpgpb41-test.drv
building '/nix/store/pc3jbydl0xcc8nrndf5xkf7hdhpgpb41-test.drv'...
unpacking sources
unpacking source archive /nix/store/v9p98kqplf4kflmy91p0687xlvr6klb1-char-regex-1.0.2.tgz
source root is package
find: 'package/index.d.ts': Permission denied
find: 'package/index.js': Permission denied
find: 'package/LICENSE': Permission denied
find: 'package/package.json': Permission denied
find: 'package/README.md': Permission denied
/nix/store/6c47azxacncswc1pllzj28zfzqw40d7c-stdenv-linux/setup: line 1311: cd: package: Permission denied
builder for '/nix/store/pc3jbydl0xcc8nrndf5xkf7hdhpgpb41-test.drv' failed with exit code 1
error: build of '/nix/store/pc3jbydl0xcc8nrndf5xkf7hdhpgpb41-test.drv' failed
```
As you can see, the issue is that `$sourceRoot` isn't executable,
prohibiting the call to `cd`. This can be fixed by running
`chmod +x "${sourceRoot}"` before `cd` regardless of
`dontMakeSourcesWritable` in `unpackPhase` since if `chmod` fails, `cd`
would fail as well and we are out of options.
Verified that the workaround works locally.
Another thing to investigate is investigating if we should use
`--no-same-owner` for `tar` and if it helps in this case as well.
See also <https://github.com/Profpatsch/yarn2nix/issues/56>.
Flake users that use a command like `nix build nixpkgs#hello` on a
broken/insecure package will not be able to use an environment variable
to override that behavior, unless they pass `--impure` to the command.
Co-authored-by: pkharvey <kayharvey@protonmail.com>
Add `shellDryRun` to the generic stdenv and substitute it for uses of
`${stdenv.shell} -n`. The point of this layer of abstraction is to add
the flag `-O extglob`, which resolves#126344 in a more direct way.
Packages that use libtool run it as a wrapper around the linker.
Before calling the linker, libtool will determine what libraries would
be linked, and check if there's a corresponding libtool
archive (libfoo.la) file in the same directory . This file
contains extra information about the library. This is especially
important for static linking, because static archives don't contain
dependency information, so we need libtool to use the .la files to
figure out which libraries actually need to be linked against.
But in Nixpkgs, this has never worked. libtool isn't able to find any
libraries, because only the compiler wrapper knows how to find them,
and the compiler wrapper is opaque to libtool. This is why
pkgsStatic.util-linuxMinimal doesn't build prior to this patch — it
depends on libpam, which depends on libaudit, and if libtool can't
find the .la file, nothing will tell the linker to also link against
libaudit when linking libpam. (It was previously possible to build a
static util-linux, because linux-pam only recently had the audit
dependency added.)
There are a couple of ways we could fix this, so that libtool knows
where to look for .la files.
* Set LD_LIBRARY_PATH/DYLD_LIBRARY_PATH/whatever, which libtool will
examine. This would have major side effects though, because the
dynamic linker looks at it too.
* Inject libtool scripts with the appropriate information. That's
what I've done here. It was the obvious choice because we're
already finding and modifying the libtool scripts, to remove paths
outside the Nix store that libtool might check in unsandboxed
builds. Instead of emptying out the system paths, we can
repopulate it with our own library paths.
(We can't use a wrapper like we do for other tools in Nixpkgs, because
libtool scripts are often distributed in source tarballs, so we can't
just add a wrapped version of libtool as a dependency. That's why
there's already the fixLibtool function in stdenv.)
With this change, libtool is able to discover .la files, and
pkgsStatic.util-linuxMinimal can build again, linking correctly
against libpam and libaudit.
This reverts commit 488395c0f8.
Currently, `nix print-dev-env` fails to execute if this function is present, because of its use of hex literals.
Until this issue (https://github.com/NixOS/nix/issues/5262) is solved, we should revert this to prevent breakage.
somehow `read -N 0` behavior changed in bash 5. `read -d ''` has identical behavior
the purpose of the function is to read stdin and exit 1 on a null byte (i.e. if stdin is the content of a binary)
(cherry picked from commit 5d0acf20f8)
The old stdenv adapters were subtly wrong in two ways:
- `overrideAttrs` leaked the original, unoverridden `mkDerivation`.
- `stdenv.override` would throw away any manually-set `mkDerivation`
from a stdenv reverting to the original.
Now, `mkDerivation` is controlled (nearly directly) via an argument, and
always correctly closes over the final ("self") stdenv. This means the
adapters can work entirely via `.override` without any manual `stdenv //
...`, and both those issues are fixed.
Note hashes are changed, because stdenvs no previously overridden like
`stdenvNoCC` and `crossLibcStdenv` now are. I had to add some
`dontDisableStatic = true` accordingly. The flip side however is that
since the overrides compose, we no longer need to override anything but
the default `stdenv` from which all the others are created.
When we "fix" libtool, we empty out its system library path to avoid
it discovering libraries in e.g. /usr when the sandbox is disabled.
But this also means that the checks libtool does to make sure it can
find the libraries its supposed to be linking to won't work. On Linux
and Darwin, this isn't a problem, because libtool doesn't actually
perform any checks, but it is on at least NetBSD and Cygwin[1].
So, we force libtool not to do these checks on any platform, bringing
the more exotic platforms into line with the existing behaviour on
Linux and Darwin.
Without this change, lots of library packages produce warnings like
this in their build output on the platforms with checks by default:
*** Warning: linker path does not have real file for library -lz.
*** I have the capability to make that library automatically link in when
*** you link to this library. But I can only do this if you have a
*** shared version of the library, which you do not appear to have
*** because I did check the linker path looking for a file starting
*** with libz but no candidates were found. (...for regex pattern test)
*** The inter-library dependencies that have been dropped here will be
*** automatically added whenever a program is linked with this library
*** or is declared to -dlopen it.
And dependent packages break because libtool doesn't link their
transitive dependencies. So making this change fixes _lots_ of
packages on those platforms.
[1]: https://git.savannah.gnu.org/cgit/libtool.git/tree/m4/libtool.m4?id=544fc0e2c2a03129a540aebef41ad32bfb5c06b8#n3445