Merge pull request #2326 from aszlig/fix-symlink-leak
Fix symlink leak in restricted eval mode
This commit is contained in:
commit
bc65e02d96
|
@ -349,19 +349,25 @@ Path EvalState::checkSourcePath(const Path & path_)
|
||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
|
/* First canonicalize the path without symlinks, so we make sure an
|
||||||
|
* attacker can't append ../../... to a path that would be in allowedPaths
|
||||||
|
* and thus leak symlink targets.
|
||||||
|
*/
|
||||||
|
Path abspath = canonPath(path_);
|
||||||
|
|
||||||
for (auto & i : *allowedPaths) {
|
for (auto & i : *allowedPaths) {
|
||||||
if (isDirOrInDir(path_, i)) {
|
if (isDirOrInDir(abspath, i)) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found)
|
if (!found)
|
||||||
throw RestrictedPathError("access to path '%1%' is forbidden in restricted mode", path_);
|
throw RestrictedPathError("access to path '%1%' is forbidden in restricted mode", abspath);
|
||||||
|
|
||||||
/* Resolve symlinks. */
|
/* Resolve symlinks. */
|
||||||
debug(format("checking access to '%s'") % path_);
|
debug(format("checking access to '%s'") % abspath);
|
||||||
Path path = canonPath(path_, true);
|
Path path = canonPath(abspath, true);
|
||||||
|
|
||||||
for (auto & i : *allowedPaths) {
|
for (auto & i : *allowedPaths) {
|
||||||
if (isDirOrInDir(path, i)) {
|
if (isDirOrInDir(path, i)) {
|
||||||
|
|
|
@ -38,3 +38,14 @@ ln -sfn $(pwd)/restricted.nix $TEST_ROOT/restricted.nix
|
||||||
nix-instantiate --eval --restrict-eval $TEST_ROOT/restricted.nix -I $TEST_ROOT -I .
|
nix-instantiate --eval --restrict-eval $TEST_ROOT/restricted.nix -I $TEST_ROOT -I .
|
||||||
|
|
||||||
[[ $(nix eval --raw --restrict-eval -I . '(builtins.readFile "${import ./simple.nix}/hello")') == 'Hello World!' ]]
|
[[ $(nix eval --raw --restrict-eval -I . '(builtins.readFile "${import ./simple.nix}/hello")') == 'Hello World!' ]]
|
||||||
|
|
||||||
|
# Check whether we can leak symlink information through directory traversal.
|
||||||
|
traverseDir="$(pwd)/restricted-traverse-me"
|
||||||
|
ln -sfn "$(pwd)/restricted-secret" "$(pwd)/restricted-innocent"
|
||||||
|
mkdir -p "$traverseDir"
|
||||||
|
goUp="..$(echo "$traverseDir" | sed -e 's,[^/]\+,..,g')"
|
||||||
|
output="$(nix eval --raw --restrict-eval -I "$traverseDir" \
|
||||||
|
"(builtins.readFile \"$traverseDir/$goUp$(pwd)/restricted-innocent\")" \
|
||||||
|
2>&1 || :)"
|
||||||
|
echo "$output" | grep "is forbidden"
|
||||||
|
! echo "$output" | grep -F restricted-secret
|
||||||
|
|
Loading…
Reference in a new issue