From 53522cb6ac19bd1da35a657988231cce9387be9c Mon Sep 17 00:00:00 2001 From: Eelco Dolstra Date: Thu, 14 Mar 2019 13:50:07 +0100 Subject: [PATCH] findRoots(): Add 'censor' parameter This is less brittle than filtering paths after the fact in nix-daemon. --- src/libstore/gc.cc | 30 +++++++++++++++----------- src/libstore/local-store.hh | 8 +++---- src/libstore/remote-store.cc | 2 +- src/libstore/remote-store.hh | 2 +- src/libstore/store-api.hh | 6 ++++-- src/nix-daemon/nix-daemon.cc | 41 +++++++++--------------------------- src/nix-store/nix-store.cc | 4 ++-- 7 files changed, 40 insertions(+), 53 deletions(-) diff --git a/src/libstore/gc.cc b/src/libstore/gc.cc index 8c3607f66..d8a5da0d4 100644 --- a/src/libstore/gc.cc +++ b/src/libstore/gc.cc @@ -129,7 +129,7 @@ Path LocalFSStore::addPermRoot(const Path & _storePath, check if the root is in a directory in or linked from the gcroots directory. */ if (settings.checkRootReachability) { - Roots roots = findRoots(); + Roots roots = findRoots(false); if (roots[storePath].count(gcRoot) == 0) printError( format( @@ -197,7 +197,10 @@ void LocalStore::addTempRoot(const Path & path) } -void LocalStore::findTempRoots(FDs & fds, Roots & tempRoots) +static std::string censored = "{censored}"; + + +void LocalStore::findTempRoots(FDs & fds, Roots & tempRoots, bool censor) { /* Read the `temproots' directory for per-process temporary root files. */ @@ -248,7 +251,7 @@ void LocalStore::findTempRoots(FDs & fds, Roots & tempRoots) Path root(contents, pos, end - pos); debug("got temporary root '%s'", root); assertStorePath(root); - tempRoots[root].emplace(fmt("{temp:%d}", pid)); + tempRoots[root].emplace(censor ? censored : fmt("{temp:%d}", pid)); pos = end + 1; } @@ -317,7 +320,7 @@ void LocalStore::findRoots(const Path & path, unsigned char type, Roots & roots) } -void LocalStore::findRootsNoTemp(Roots & roots) +void LocalStore::findRootsNoTemp(Roots & roots, bool censor) { /* Process direct roots in {gcroots,profiles}. */ findRoots(stateDir + "/" + gcRootsDir, DT_UNKNOWN, roots); @@ -327,17 +330,17 @@ void LocalStore::findRootsNoTemp(Roots & roots) NIX_ROOT_FINDER environment variable. This is typically used to add running programs to the set of roots (to prevent them from being garbage collected). */ - findRuntimeRoots(roots); + findRuntimeRoots(roots, censor); } -Roots LocalStore::findRoots() +Roots LocalStore::findRoots(bool censor) { Roots roots; - findRootsNoTemp(roots); + findRootsNoTemp(roots, censor); FDs fds; - findTempRoots(fds, roots); + findTempRoots(fds, roots, censor); return roots; } @@ -381,7 +384,7 @@ static void readFileRoots(const char * path, Roots & roots) } } -void LocalStore::findRuntimeRoots(Roots & roots) +void LocalStore::findRuntimeRoots(Roots & roots, bool censor) { Roots unchecked; @@ -467,7 +470,10 @@ void LocalStore::findRuntimeRoots(Roots & roots) Path path = toStorePath(target); if (isStorePath(path) && isValidPath(path)) { debug(format("got additional root '%1%'") % path); - roots[path].insert(links.begin(), links.end()); + if (censor) + roots[path].insert(censored); + else + roots[path].insert(links.begin(), links.end()); } } } @@ -739,7 +745,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) printError(format("finding garbage collector roots...")); Roots rootMap; if (!options.ignoreLiveness) - findRootsNoTemp(rootMap); + findRootsNoTemp(rootMap, true); for (auto & i : rootMap) state.roots.insert(i.first); @@ -748,7 +754,7 @@ void LocalStore::collectGarbage(const GCOptions & options, GCResults & results) can be added to the set of temporary roots. */ FDs fds; Roots tempRoots; - findTempRoots(fds, tempRoots); + findTempRoots(fds, tempRoots, true); for (auto & root : tempRoots) state.tempRoots.insert(root.first); state.roots.insert(state.tempRoots.begin(), state.tempRoots.end()); diff --git a/src/libstore/local-store.hh b/src/libstore/local-store.hh index 39a34597e..6b655647b 100644 --- a/src/libstore/local-store.hh +++ b/src/libstore/local-store.hh @@ -180,11 +180,11 @@ private: typedef std::shared_ptr FDPtr; typedef list FDs; - void findTempRoots(FDs & fds, Roots & roots); + void findTempRoots(FDs & fds, Roots & roots, bool censor); public: - Roots findRoots() override; + Roots findRoots(bool censor) override; void collectGarbage(const GCOptions & options, GCResults & results) override; @@ -267,9 +267,9 @@ private: void findRoots(const Path & path, unsigned char type, Roots & roots); - void findRootsNoTemp(Roots & roots); + void findRootsNoTemp(Roots & roots, bool censor); - void findRuntimeRoots(Roots & roots); + void findRuntimeRoots(Roots & roots, bool censor); void removeUnusedLinks(const GCState & state); diff --git a/src/libstore/remote-store.cc b/src/libstore/remote-store.cc index a4dd28af0..15faf78a5 100644 --- a/src/libstore/remote-store.cc +++ b/src/libstore/remote-store.cc @@ -596,7 +596,7 @@ void RemoteStore::syncWithGC() } -Roots RemoteStore::findRoots() +Roots RemoteStore::findRoots(bool censor) { auto conn(getConnection()); conn->to << wopFindRoots; diff --git a/src/libstore/remote-store.hh b/src/libstore/remote-store.hh index 4f554b598..e5ab79e59 100644 --- a/src/libstore/remote-store.hh +++ b/src/libstore/remote-store.hh @@ -82,7 +82,7 @@ public: void syncWithGC() override; - Roots findRoots() override; + Roots findRoots(bool censor) override; void collectGarbage(const GCOptions & options, GCResults & results) override; diff --git a/src/libstore/store-api.hh b/src/libstore/store-api.hh index bb1665976..40887b6aa 100644 --- a/src/libstore/store-api.hh +++ b/src/libstore/store-api.hh @@ -484,8 +484,10 @@ public: /* Find the roots of the garbage collector. Each root is a pair (link, storepath) where `link' is the path of the symlink - outside of the Nix store that point to `storePath'. */ - virtual Roots findRoots() + outside of the Nix store that point to `storePath'. If + 'censor' is true, privacy-sensitive information about roots + found in /proc is censored. */ + virtual Roots findRoots(bool censor) { unsupported("findRoots"); } /* Perform a garbage collection. */ diff --git a/src/nix-daemon/nix-daemon.cc b/src/nix-daemon/nix-daemon.cc index 0feafb013..dd8b9bd1e 100644 --- a/src/nix-daemon/nix-daemon.cc +++ b/src/nix-daemon/nix-daemon.cc @@ -475,40 +475,19 @@ static void performOp(TunnelLogger * logger, ref store, case wopFindRoots: { logger->startWork(); - Roots roots = store->findRoots(); + Roots roots = store->findRoots(true); logger->stopWork(); - // Pre-compute roots length using same algo as below. - size_t total_length = 0; - bool hasMemoryLink; - for (auto & root : roots) { - hasMemoryLink = false; - for (auto & link : root.second) { - if (link.rfind("{memory:", 0) == 0) { - if (hasMemoryLink) continue; - ++total_length; - hasMemoryLink = true; - } else { - ++total_length; - } - } - } + size_t size = 0; + for (auto & i : roots) + size += i.second.size(); + + to << size; + + for (auto & [target, links] : roots) + for (auto & link : links) + to << link << target; - to << total_length; - int n = 0; - for (auto & [target, links] : roots) { - bool hasMemoryLink = false; - for (auto & link : links) { - // Obfuscate 'memory' roots as they expose information about other users, - if (link.rfind("{memory:", 0) == 0) { - if (hasMemoryLink) continue; - to << fmt("{memory:%d}", n++) << target; - hasMemoryLink = true; - } else { - to << link << target; - } - } - } break; } diff --git a/src/nix-store/nix-store.cc b/src/nix-store/nix-store.cc index b5530b39e..6f315e509 100644 --- a/src/nix-store/nix-store.cc +++ b/src/nix-store/nix-store.cc @@ -427,7 +427,7 @@ static void opQuery(Strings opFlags, Strings opArgs) maybeUseOutputs(store->followLinksToStorePath(i), useOutput, forceRealise), referrers, true, settings.gcKeepOutputs, settings.gcKeepDerivations); } - Roots roots = store->findRoots(); + Roots roots = store->findRoots(false); for (auto & [target, links] : roots) if (referrers.find(target) != referrers.end()) for (auto & link : links) @@ -591,7 +591,7 @@ static void opGC(Strings opFlags, Strings opArgs) if (!opArgs.empty()) throw UsageError("no arguments expected"); if (printRoots) { - Roots roots = store->findRoots(); + Roots roots = store->findRoots(false); for (auto & [target, links] : roots) for (auto & link : links) cout << link << " -> " << target << std::endl;