From e5a211d77eff65b19162b5fda352d7e6586a370f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9ophane=20Hufschmitt?= Date: Thu, 28 Apr 2022 16:02:20 +0200 Subject: [PATCH] Add an owner check when searching for the flake root MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When searching up the filesystem for the root of the flake (the directory that contains the `flake.nix`), don’t go anywhere up if we encounter a directory owned by a different user, as otherwise this other user could craft an arbitrary flake, potentially causing bad stuff to happen (shouldn’t in most cases since all it could do is run sanboxed builds, but there’s probably a lot of edge-cases that would make this very undesirable). This is to fix Nix’s equivalent of CVE-2022-24765 This check is intentionnally not applied to the exact directory specified since: 1. It’s up to the user to not point to an untrusted input 2. In multi-user Nix installations, that would prevent from using a flake in the Nix store (since it’s owned by root and not the current user) Fix #6408 --- doc/manual/src/release-notes/rl-next.md | 4 +++- src/libexpr/flake/flakeref.cc | 12 ++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/doc/manual/src/release-notes/rl-next.md b/doc/manual/src/release-notes/rl-next.md index bde9057c6..e46652f48 100644 --- a/doc/manual/src/release-notes/rl-next.md +++ b/doc/manual/src/release-notes/rl-next.md @@ -1,3 +1,5 @@ # Release X.Y (202?-??-??) -- [`nix-channel`](../command-ref/nix-channel.md) now supports a `--list-generations` subcommand +* When searching upwards for the root of the flake, Nix doesn’t consider + anything that’s not owned by the current user anymore as it’s a + security hazard. diff --git a/src/libexpr/flake/flakeref.cc b/src/libexpr/flake/flakeref.cc index 08adbe0c9..82307f8c7 100644 --- a/src/libexpr/flake/flakeref.cc +++ b/src/libexpr/flake/flakeref.cc @@ -127,6 +127,8 @@ std::pair parseFlakeRefWithFragment( // Save device to detect filesystem boundary dev_t device = lstat(path).st_dev; + // Fix for the Nix equivalent of CVE-2022-24765 + uid_t currentUser = geteuid(); bool found = false; while (path != "/") { if (pathExists(path + "/flake.nix")) { @@ -134,11 +136,13 @@ std::pair parseFlakeRefWithFragment( break; } else if (pathExists(path + "/.git")) throw Error("path '%s' is not part of a flake (neither it nor its parent directories contain a 'flake.nix' file)", path); - else { - if (lstat(path).st_dev != device) - throw Error("unable to find a flake before encountering filesystem boundary at '%s'", path); - } path = dirOf(path); + auto pathStat = lstat(path); + if (pathStat.st_dev != device) + throw Error("unable to find a flake before encountering filesystem boundary at '%s'", path); + if (pathStat.st_uid != currentUser) { + throw Error("unable to find a flake before encountering a directory not owned by us at '%s'", path); + } } if (!found) throw BadURL("could not find a flake.nix file");