-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Revert "Merge pull request #9902 from NixOS/require-fixed-output-fetchurl" #9911
base: master
Are you sure you want to change the base?
Conversation
Being able to download files without specifying a hash is 100% a very serious bug, so we cannot revert this bug fix, as annoying as that may be to users who were relying on this bug. (It's also worth noting that |
What do you mean? Have you *tried* running this on a properly sandboxed Nix install? I literally ran your example that showed the bug in action and it can't access the internet. I also never said that I used it to download files, anyways. As mentioned in my talk on Zilch, I use And something being undocumented may make it "unstable" from your PoV, but you're not the only user of Nix. Did 9999years go through this much effort keeping an undocumented assumption (that |
I didn't notice that
This is actually fairly sensible (and you already do that same thing with a non-FOD derivation that calls curl). That being said, I'm not sure that we want that in Nix itself, since it can be emulated (and honestly, these fetchers are mostly hacks so that Nix can do some basic operation without depending on Nixpkgs). @puckipedia, what's the reason for using |
…-fetchurl" This is not actually a bug on Nix (version 2.18, at least), and breaks code I've written (with no other way to write that code.) nix-repl> :b builtins.derivation { name = "nix-cache-info"; system = "x86_64-linux"; builder = "builtin:fetchurl"; url = https://cache.nixos.org/nix-cache-info; outputHashMode = "flat"; } warning: error: unable to download 'https://cache.nixos.org/nix-cache-info': Couldn't resolve host name (6); retrying in 309 ms warning: error: unable to download 'https://cache.nixos.org/nix-cache-info': Couldn't resolve host name (6); retrying in 607 ms warning: error: unable to download 'https://cache.nixos.org/nix-cache-info': Couldn't resolve host name (6); retrying in 1002 ms warning: error: unable to download 'https://cache.nixos.org/nix-cache-info': Couldn't resolve host name (6); retrying in 2554 ms error: builder for '/nix/store/z89j6fdfm6k9k1qir99449wyvldpm2ma-nix-cache-info.drv' failed with exit code 1; last 4 log lines: > error: > … writing file '/nix/store/l9ax62fdagg4cvw9wd4h84cf4pxqcmlg-nix-cache-info' > > error: unable to download 'https://cache.nixos.org/nix-cache-info': Couldn't resolve host name (6) For full logs, run 'nix-store -l /nix/store/z89j6fdfm6k9k1qir99449wyvldpm2ma-nix-cache-info.drv'. This reverts commit 081dc5d, reversing changes made to ef6d055.
4ee60b9
to
ba7a34d
Compare
With all do respect @puckipedia, I do get a small bit of https://xkcd.com/1172/ vibes from this. If I understand correctly, you are creating an input-addressed derivation with There is hopefully another way Nix can provide what you need. |
If you do not want this in Nix, open an RFC to remove it properly. I'm will not accept someone seemingly accidentally merging a PR (without even checking the reasoning is correct) removing a feature as the new status quo.
As mentioned in my talk on Zilch, I use Does it matter what I use this for, though? I was under the impression the policy of the Nix team was to avoid code breakage as much as possible. And this sure smells like breakage of previously valid code with perfectly valid semantics to me. And if this truly was such a critical security issue, I'd have expected it to be backported to versions of Nix considered stable by downstream users, like Nixpkgs. |
As mentioned in the opening message of this PR, builtin derivation builders are not exempt from sandboxing. |
The point of https://xkcd.com/1172/ is that, very strictly speaking, almost every change can be construed as a breaking change, and there is always some subjectivity as to where the line is drawn. I think everyone agrees that e.g. small timing variations are are not supposed to be stable. I am also suspicious of things that rely on sandboxing being disabled. At the same time, I recognize a strict declaration of sandboxing being disabled not mattering would invalidate macOS support for most of its history. So I think the best resolution will be to think about what exactly you are using this for, and finding you something else you can use that is acceptable. And of course, we better go and document whatever that thing is (if it needs it) so you can be confident this unfortunate "rug pulled out from under you" will not happen again with the replacement. |
If I *wanted* to fetch a remote URL without declaring a derivation as fixed-output on an unsandboxed system, I'd just use I also believe that having seemingly one person be able to just decide "This feature is unstable" is bad actually, and not having a stability policy in place is a pretty massive footgun. As long as there is no policy, I (and many others) will assume that anything that's been the same for quite a while (e.g. builtin:fetchurl, which has behaved like this since 2015) is likely to be stable, and thus can be relied upon, especially because this is a derivation we're talking about. And this guideline seems to be used by some other Nix team members as well.
As mentioned in my reply to @edolstra, I use |
Ah! I think this is it? You need to add data with arbitrary references, but all our existing Would it work if you could insert arbitrary content-addressed data with arbitrary references? I would support extending |
|
I don't mind having a |
How will that builtin interact with derivation outputs? Will it force IFD? will it output a derivation of its own? Will that derivation be buildable on older Nix daemon versions? I think there's already enough questions for such a builtin that I'd want this "fix" to a non-existent issue be reverted before we can even discuss what color the currently non-existent bikeshed will be. |
..wait, you mean a builtin builder. Yeah, you cannot feature detect those. This means I'd either have to be incompatible with newer versions of the Nix daemon, or older version fo the Nix daemon. There'd be no way to be backward compatible. |
I mean an evaluation built-in, but I guess that is basically the same as the builtin fetchers which fetch at eval time and don't require a NAR hash. If you want it deferred and you don't want the hash known in advanced, there are "impure derivations". We could also make |
Builtin builders and evaluator builtins are very different, and I'd suggest reading up on them before suggesting they are "basically the same." But, to answer your message: Impure derivations are unstable, and require having code that can be run inside the derivation at that point. And, repeating myself once more: I'm not going to stand for people being needlessly forced to consider certain features "stable" when someone else can come by and just say "oh this was never meant to be stable" and change it. If the Nix team are unwilling to come up with a stability policy, they get to deal with issues like this. |
I know they are different. I said the new evaluator builtin I was thinking of is actually the same as an existing evaluator builtin. I was correcting myself, not correcting you. @puckipedia you tone makes it very hard to have this conversation. I am very keen on properly documenting the store layer in isolation precisely so this stuff is pinned down, but until that process is complete situations where "bug or feature" is a matter of pinion like this will arise. I did in fact flip through your slides, but I am not going to watch the entire talk because you don't want to explain what you are trying to do from first principles so we can collaboratively find a new solution that everyone finds agreeable. I am going to go eat a meal now. |
I want to run a binary in my bootstrap. I use To solve this impossibility, I generate a I generalised this mechanism to allow creating arbitrary trees of directories and symlinks, as it is a useful primitive to not have to depend as strongly on large derivation closures just to create a single symlink, and thus it should work with both input-addressed and content-addressed store paths. There is no way to easily replace this with any other existing mechanism: Impure derivations require code to build the tree (or unpack the .nar), and there's no way to create directories or symlinks in Nix (or with the Nonetheless, any new mechanism would still require at least a few versions of Nix in which |
Thanks, also see #9912. |
What happened to the existing behavior being covered by the stability policy even if it's buggy? PRs get rejected with this rationale all the time. The lack of a written stability policy means that, in practice, only contributors with political cachet can make breaking (or "breaking") changes. This rationale in particular is pretty goofy because downloading files without specifying a hash is a long-standing documented use-case for functions like EDIT: To clarify, I know that |
I sure thought we could agree that the |
I don't think this should have been possible in the first place, but since it indeed isn't a correctness issue, we might as well not break user space and keep allowing it (besides, the hack is rather nice). With that said, let's cool down a little here. @puckipedia Now you got me curious. You mention that using an FOD doesn't work because of the references, but what are the references you need to have if all you're doing it putting a static binary under |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/whats-nixs-stable-api-is-code-in-nix-instantiate-part-of-it/37986/6 |
I don't believe I've been aggressive in this thread. I have been frustrated, and that leaked into my messages, sure, but I think I have enough reason to be at least a little annoyed at the others in this PR:
Together with the recent negative experiences of friends (this isn't just me being handled this way!), I was more than reasonable responding as I did.
As mentioned in my previous message, the Nix sandbox does not provide any way to copy files, nor create directories, nor create symlinks, and I (for various reasons) do not want to maintain a properly shaped NAR file myself. (otherwise i would've just patched the issue that i wrote this entire thing for out!) Thus, seemingly my best option is to synthesize a NAR file containing a single symlink into the Nix store, and use |
Completely disagree. This is like not fixing a buffer overflow bug because somebody might be relying on it to gain access to the system (and indeed it gives https://xkcd.com/1172/ vibes). It should be completely uncontroversial that Nix does not permit hash-less downloads from the network (at build time, not evaluation time) since that has always been the case (expect for this bug in an undocumented interface). If we're going to compromise on this, then why even have sandboxing? Remember, this bug would have allowed Nixpkgs to download the latest version of a source tarball, which is not very reproducible. It should be clear that we cannot allow that in a supposedly reproducible build system. |
@edolstra I will ask, and I cannot believe I have to do this, but, have you read my PR message? Please clarify why, when running the example you gave in the initial PR as the reason to remove this functionality, I get the expected result of not the builtin builder not being able to communicate to the internet, as it should behave, rather than the result you seem to be getting, which is it bypassing the Nix sandbox. |
That's because there appears to be a separate bug in |
DNS resolution isn't just broken here, don't worry. nix-repl> :b builtins.derivation { name = "nix-cache-info"; system = "x86_64-linux"; builder = "builtin:fetchurl"; url = http://49.12.206.3/; outputHashMode = "flat"; }
warning: error: unable to download 'http://49.12.206.3/': Couldn't connect to server (7); retrying in 281 ms
warning: error: unable to download 'http://49.12.206.3/': Couldn't connect to server (7); retrying in 508 ms
warning: error: unable to download 'http://49.12.206.3/': Couldn't connect to server (7); retrying in 1000 ms And if that was actually the case, why repeat the exact same point you made before without even trying to explain why the behavior I was seeing didn't match that? |
You're right. However, whether sandboxing is enabled shouldn't affect whether an |
Okay, so we're where we should've been about one reply into the thread. I think that breaking a feature that worked since 2015, with documented uses, for no good reason, is bad. And no real alternative exists for me to use as a replacement of |
To actually respond to this point: As mentioned before, if I wanted to fetch a file in an unsandboxed input-addressed derivation, I'd just call |
False, Nixpkgs maintains avoidance of some of the Nix features.
Well, (By the way, Nix does project this impression of «we won't tell what's stable and we will conspiciously break whatever we do not personally use» from time to time, so I can understand the frustration in messages by @puckipedia ) |
Drive by summarization:The Then, @puckipedia 1 found an unexpected usecase where you could pass it Personal Opinion:Personally I dislike this behavior and I think we should have something less weird, maybe a Footnotes
|
The unpack and non-FOD behavior of The code below demonstrates the requested feature as it is currently being used: @puckipedia is this a close minimal example to what you are doing? The examples provided above using https://cache.nixos.org/nix-cache-info, and http://49.12.206.3, are distractions. Only the "file://" behavior is being asked for? The non-FOD behavior of fetchurl was intended to be restricted as builtin:fetchurl is normally expected to be a FOD. This normal expectation means it can have different behavior when connecting to various remote resources and there is a very real possibility of the proposed change to cause a security problem, interact with sandboxing, or to connect to unexpected URLs. This specific behavior does not seem to have been relied upon until now. Therefore it is valid to consider if supporting it will lead to ossification and continued usage. Some possibilities that are not mutually exclusive or prioritised:
|
Yeah; that's pretty close to what I wrote.
They are not. The examples explicitly used to prove that @edolstra's point, and the reason he created + merged his own PR, was invalid, and trying to add more reason to revert this change before discussing alternative fixes.
None of the other URI schemes that curl may support are useful when no networking is available.
I mean, without it being a FOD it is inherently useless, other than the
This hasn't been an issue for any non-builtin builder that is intended to run as a fixed-output derivation? It seems to me that you are trying to explain away the reason why I see different behavior than Eelco in the most generic possible manner, without actually addressing the points I made. (In fact, noone has actually addressed the points I made against his PR in the first place.)
First of all, "proposed change" implies that this change would be (allegedly) introducing a security problem that wasn't there before. This PR is an exact revert of a patch that has not even made it into a Nix release.
Idem on the explaining away bit. If
"now"? This code has been around for quite a few years; it's just not been very public. Does Nix code need to be 100% public to not be accidentally broken by upstream Nix? What does that say about proprietary/in-company usage of Nix?
Why do *I* need to fight to keep this feature stable and working as it does, even after proving that @edolstra's reasoning for merging the PR was invalid, while e.g.
A bunch of these ("prevent non-FOD usage", "support file:// urls for builtin:fetchurl", and "support non-FOD file:// usage") read quite mutually exclusive to me. Note, also, that FOD file:// usage here is incompatible, as it disallows creating references. |
In short, the change being reverted here was made due to ostensible security impact. The suggested security impact does not exist since the code is being run inside a sandbox and aside from the executable being included with Nix, is a normal build. It's possible that it was tested with the sandbox disabled, leading to the incorrect conclusions stated in #9902, but that is sort of irrelevant, since The change regresses behaviour which exists and has been talked about publicly several months ago, in a lecture hall Eelco was personally in, though that is not a bar for functionality to be supported, of course. The stated reasons to make the change have been shown to be incorrect, so #9902 does not need a replacement either. Perhaps a discussion should be had about replacements for this rather emergent feature that are less cursed, but at the moment, the fact that removing it regresses existing codebases that are doing something reasonable with no alternative seems like a very normal reason to simply revert a PR, regardless of its contents, to think it through some more later. It seems very strange that reverting this unintended removal of functionality in the builder, which has no alternate functionality today that could be migrated to, nor any way to feature-detect, is being fought over. At the same time, tvix using the |
Up till now, I have only been trying make sure I have a clear understanding of the situation. The ability to unpack NARs was specifically added for a similar use case, but intended to be used via "<nix/fetchurl.nix>" and to refer to a known hash, even for "file://" URLs, this is what was tested. (dae5dc7) Another related thread: #3493 suggesting that Generally, I would like for there to be something to solve the original problem to create a file tree without relying on Nixpkgs; specifically thinking about future RFC92 work. And while crafting a NAR via shell printf does solve the problem, I'm doubtful that it should be the primary mechanism. I am mostly interested in what that could be. @Ericson2314 : this was a big missing piece when trying to put a nice user interface on top of dyn-drvs. Would it make sense for the new behavior of
We need to check to ensure that the requested item is only a valid store path. This would be needed to address the problem posed by asking for netrc.
|
This doesn't really require vague overgeneralising speculation, though, such as "This normal expectation means it can have different behavior when connecting to various remote resources"? Bring me real possibilities for security issues, rather than just these vague guesses at possibilities of things going wrong.
I agree with this. However: This should not come at the cost of existing code that's already out there.
This isn't necessary; FODs should run in a sandbox anyways. And if they don't, then any network access is allowed anyways.
I'd be okay with explicitly skipping copying the netrc in the case of non-FODs. Interestingly enough, the preview you showed, showed fetching a
(I'd totally missed this; I don't use netrc and don't know any others that do, as only |
Related, but I just noticed #9902 in fact breaks calling |
@puckipedia is that still an issue for you? |
This pull request has been mentioned on NixOS Discourse. There might be relevant details there: https://discourse.nixos.org/t/nar-unpacking-vulnerability-post-mortem/52301/31 |
This reverts commit 081dc5d, reversing changes made to ef6d055.
Motivation
This is not actually a bug on Nix (2.18, at least), and breaks code I've written (with no other way to write that code.)
Context
Reverts #9902.
Priorities and Process
Add 👍 to pull requests you find important.
The Nix maintainer team uses a GitHub project board to schedule and track reviews.