~ruther/guix-local

ca03f7379050c93a51fadb00659481180572157c — Ludovic Courtès 1 year, 4 months ago c5a9227
daemon: Tolerate pipes and sockets in failed build trees.

Fixes <https://issues.guix.gnu.org/78919>.
Fixes guix/guix#471.

Fixes a bug introduced in ae18b3d9e6bd0c184505a094851448d08555e23e
whereby interrupting ‘guix build -K hello’ would leave a build directory
with root ownership due ‘secureFilePerms’ bailing out due to the
presence of FIFOs in the temporary build directory.

* nix/libstore/build.cc (secureFilePerms): Add ‘allowSpecialFiles’
parameter; honor it and pass it in recursive call.
(DerivationGoal::deleteTmpDir): Pass true as the second argument to
‘secureFilePerms’.

Reported-by: Janneke Nieuwenhuizen <janneke@gnu.org>
Reported-by: David Elsing <david.elsing@posteo.net>
Change-Id: I638a4ee909a2b5022f9153e1cbb832bfb2e15263
1 files changed, 15 insertions(+), 5 deletions(-)

M nix/libstore/build.cc
M nix/libstore/build.cc => nix/libstore/build.cc +15 -5
@@ 1318,8 1318,9 @@ MakeError(NotDeterministic, BuildError)
/* Recursively make the file permissions of a path safe for exposure to
   arbitrary users, but without canonicalising its permissions, timestamp, and
   user.  Throw an exception if a file type that isn't explicitly known to be
   safe is found. */
static void secureFilePerms(Path path)
   safe is found; when 'allowSpecialFiles' is true, pipes and sockets are
   allowed. */
static void secureFilePerms(Path path, bool allowSpecialFiles = false)
{
  struct stat st;
  if (lstat(path.c_str(), &st)) return;


@@ 1330,7 1331,7 @@ static void secureFilePerms(Path path)

  case S_IFDIR:
    for (auto & i : readDirectory(path)) {
      secureFilePerms(path + "/" + i.name);
      secureFilePerms(path + "/" + i.name, allowSpecialFiles);
    }
    /* FALLTHROUGH */



@@ 1338,6 1339,14 @@ static void secureFilePerms(Path path)
    chmod(path.c_str(), (st.st_mode & ~S_IFMT) & ~(S_ISUID | S_ISGID | S_IWOTH));
    break;

  case S_IFSOCK:
  case S_IFIFO:
    if (allowSpecialFiles) {
      chmod(path.c_str(), (st.st_mode & ~S_IFMT) & ~(S_ISUID | S_ISGID | S_IWOTH));
      break;
    }
    /* FALLTHROUGH */

  default:
    throw Error(format("file `%1%' has an unsupported type") % path);
  }


@@ 3401,8 3410,9 @@ void DerivationGoal::deleteTmpDir(bool force)
		gid_t gid = settings.clientGid != 0 ? settings.clientGid : -1;
		bool reown = false;

		/* First remove setuid/setgid bits.  */
		secureFilePerms(tmpDir);
		/* First remove setuid/setgid bits.  Allow sockets and pipes
		   in the build directory.  */
		secureFilePerms(tmpDir, true);

		try {
		    _chown(tmpDir, uid, gid);