Store::getFSAccessor: Do not include the store dir #12531
Store::getFSAccessor: Do not include the store dir #12531edolstra merged 2 commits intoNixOS:masterfrom
Store::getFSAccessor: Do not include the store dir #12531Conversation
tests/functional/shell.sh
Outdated
|
|
||
| # Test that symlinks outside of the store don't work. | ||
| expect 1 nix shell -f shell-hello.nix forbidden-symlink -c hello 2>&1 | grepQuiet "is not in the Nix store" | ||
| expect 1 nix shell -f shell-hello.nix forbidden-symlink -c hello 2>&1 | grepQuiet "points outside source accessor" |
There was a problem hiding this comment.
N.B. error message is quite arguably worse.
On the other hand, this error message should be something that can occur in other contexts for other reasons (e.g. symlinks escaping fetch-tree'd source), in which case having the same message to show the commonality is good.
The fullt expanded messages has all the relevant paths, so the user will still see /nix/store.
e98041b to
ca13970
Compare
ca13970 to
ac1b340
Compare
ac1b340 to
c811b33
Compare
c811b33 to
46fbfea
Compare
edolstra
left a comment
There was a problem hiding this comment.
I don't really understand what ownLocationForSymlinkResolution is for. Can you give a concrete example where it's needed?
src/libutil/source-accessor.cc
Outdated
| have host-OS-agnostic designs), we cannot simply | ||
| use whether we are running on Unix or Windows for | ||
| this. */ | ||
| if (!(hasPrefix(target, ownLocationForSymlinkResolution) && (target.size() == prefixLen || target[prefixLen] == '/'))) { |
There was a problem hiding this comment.
Should target be canonicalized before doing hasPrefix() on it? Otherwise a legal symlink target like /foo///bar won't match /foo/bar.
Also I think you can use isInDir() here.
There was a problem hiding this comment.
Do we have code for a really weak canonicalization for this? We should not get rid of .. for example, we should just collapse adjacent /.
I guess I could write it, but it is tempting to factor out the CanonPath iterator that does this.
27727a8 to
ba3f481
Compare
src/libutil/source-accessor.hh
Outdated
| * | ||
| * (I made these examples use Windows/DOS paths to remind the reader | ||
| * that neither the symlink target nor | ||
| * `ownLocationForSymlinkResolution` should be a `CanonPath`.) |
There was a problem hiding this comment.
I'm not sure how this would work since our source accessor abstraction has no concept of drive letters. Its concept of a path is the CanonPath.
There was a problem hiding this comment.
@edolstra (Just writing down some things we discussed on the call)
Its concept of a path is the CanonPath.
And that doesn't change. This is just about how we interact with the "external" paths in symlink targets, which we need to convert back to our own "internal" paths.
src/libutil/source-accessor.hh
Outdated
| * to implement correctly that I (@Ericson2314) am not doing this at | ||
| * this time, however. | ||
| */ | ||
| std::filesystem::path ownLocationForSymlinkResolution = "/"; |
There was a problem hiding this comment.
I'm still not clear on why this is needed (given that we didn't need it prior to this PR). There may be an issue if you call resolveSymlinks on a projected store path accessor, but presumably we only call resolveSymlinks on storeFS (i.e. the MountedSourceAccessor that sees the entire store, and where we don't need to rewrite /nix/store).
There was a problem hiding this comment.
As discussed on the call, without this there is a test failure because of /nix/store absolute paths in symlink targets. I split the history in two so that if one just tries the first commit it doesn't have this, and that test failure is reproduced.
729a4dc to
d5548a3
Compare
|
🎉 All dependencies have been resolved ! |
|
@Ericson2314 I've made a different fix for the Having said that, I'm not sure whether it really makes sense to have |
|
@edolstra, I am very much a fan of having a
Bu that is what my commit you are skeptical of is for! Making things that don't "locally" include Perhaps we should talk about these things wednesday, once we're good for Nix 2.28 in Nixpkgs. |
d5548a3 to
2d77c87
Compare
Rather than "mounting" the store inside an empty virtual filesystem, just return the store as a virtual filesystem. This is more modular. (FWIW, it also supports two long term hopes of mind: 1. More capability-based Nix language mode. I dream of a "super pure eval" where you can only use relative path literals (See NixOS#8738), and any `fetchTree`-fetched stuff + the store are all disjoint (none is mounted in another) file systems. 2. Windows, where the store dir may include drive letters, etc., and is thus unsuitable to be the prefix of any `CanonPath`s. ) Co-authored-by: Eelco Dolstra <[email protected]>
`storeFS` is the `MountedSourceAccessor` that wraps `store->getFSAccessor()`.
2d77c87 to
9d35956
Compare
Motivation
Rather than "mounting" the store inside an empty virtual filesystem,
just return the store as a virtual filesystem. This is more modular.
Context
Depends on #12667
FWIW, it also supports two long term hopes of mind:
More capability-based Nix language mode. I dream of a "super pure
eval" where you can only use relative path literals (See
no-absolute-path-literalsexperimental feature #8738), andany
fetchTree-fetched stuff + the store are all disjoint (none ismounted in another) file systems.
Windows, where the store dir may include drive letters, etc., and is
thus unsuitable to be the prefix of any
CanonPaths.Add 👍 to pull requests you find important.
The Nix maintainer team uses a GitHub project board to schedule and track reviews.