From mboxrd@z Thu Jan 1 00:00:00 1970 From: Hartmut Goebel Subject: [Patch v2] daemon: Set ownership of kept build directories to the calling user. Date: Thu, 17 Nov 2016 12:30:25 +0100 Message-ID: <1479382225-25227-1-git-send-email-h.goebel@crazy-compilers.com> Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:50614) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1c7Ktq-0002HJ-Vt for guix-devel@gnu.org; Thu, 17 Nov 2016 06:30:42 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1c7Ktm-00036D-75 for guix-devel@gnu.org; Thu, 17 Nov 2016 06:30:38 -0500 Received: from mail-out.m-online.net ([212.18.0.10]:37015) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1c7Ktl-00035t-MD for guix-devel@gnu.org; Thu, 17 Nov 2016 06:30:33 -0500 Received: from frontend01.mail.m-online.net (unknown [192.168.8.182]) by mail-out.m-online.net (Postfix) with ESMTP id 3tKJpG6Wkcz3hk70 for ; Thu, 17 Nov 2016 12:30:30 +0100 (CET) Received: from localhost (dynscan1.mnet-online.de [192.168.6.68]) by mail.m-online.net (Postfix) with ESMTP id 3tKJpF5GcMzvkS7 for ; Thu, 17 Nov 2016 12:30:29 +0100 (CET) Received: from mail.mnet-online.de ([192.168.8.182]) by localhost (dynscan1.mail.m-online.net [192.168.6.68]) (amavisd-new, port 10024) with ESMTP id Iwp1KD4-WOv3 for ; Thu, 17 Nov 2016 12:30:26 +0100 (CET) Received: from hermia.goebel-consult.de (ppp-188-174-150-42.dynamic.mnet-online.de [188.174.150.42]) (using TLSv1 with cipher DHE-RSA-CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by mail.mnet-online.de (Postfix) with ESMTPS for ; Thu, 17 Nov 2016 12:30:26 +0100 (CET) Received: from lenashee.goebel-consult.de (lenashee.goebel-consult.de [192.168.110.2]) by hermia.goebel-consult.de (Postfix) with ESMTP id C73D3604D7 for ; Thu, 17 Nov 2016 12:30:25 +0100 (CET) List-Id: "Development of GNU Guix and the GNU System distribution." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-devel-bounces+gcggd-guix-devel=m.gmane.org@gnu.org Sender: "Guix-devel" To: guix-devel@gnu.org Fixes . * nix/libstore/globals.hh (Settings) Add clientUid and clientGid. * nix/nix-daemon/nix-daemon.cc (pdaemonLoop] Store UID and GID of the caller in settings. * nix/libstore/build.cc (_chown): New function. (DerivationGoal::deleteTmpDir): Use it, change ownership of build directory if it is kept. --- nix/libstore/build.cc | 24 ++++++++++++++++++++++++ nix/libstore/globals.hh | 6 ++++++ nix/nix-daemon/nix-daemon.cc | 13 +++++++++++++ 3 files changed, 43 insertions(+) diff --git a/nix/libstore/build.cc b/nix/libstore/build.cc index ae78e65..b49fb95 100644 --- a/nix/libstore/build.cc +++ b/nix/libstore/build.cc @@ -2609,6 +2609,23 @@ void DerivationGoal::closeLogFile() } +static void _chown(const Path & path, uid_t uid, gid_t gid) +{ + checkInterrupt(); + + printMsg(lvlVomit, format("%1%") % path); + + if (chown(path.c_str(), uid, gid) == -1) { + throw SysError(format("change owner and group of `%1%'") % path); + } + struct stat st = lstat(path); + if (S_ISDIR(st.st_mode)) { + for (auto & i : readDirectory(path)) + _chown(path + "/" + i.name, uid, gid); + } +} + + void DerivationGoal::deleteTmpDir(bool force) { if (tmpDir != "") { @@ -2617,6 +2634,13 @@ void DerivationGoal::deleteTmpDir(bool force) format("note: keeping build directory `%2%'") % drvPath % tmpDir); chmod(tmpDir.c_str(), 0755); + // Change the ownership if clientUid is set. Never change the + // ownership to "root" for security reasons. So zero is used as + // marker for unset. + if (settings.clientUid != 0) { + _chown(tmpDir, settings.clientUid, + settings.clientGid != 0 ? settings.clientGid : -1); + } } else deletePath(tmpDir); diff --git a/nix/libstore/globals.hh b/nix/libstore/globals.hh index 8c07e36..dc6a004 100644 --- a/nix/libstore/globals.hh +++ b/nix/libstore/globals.hh @@ -70,6 +70,12 @@ struct Settings { subgoal of the same goal) fails. */ bool keepGoing; + /* User and groud id of the client issuing the buld request. Used to set + the owner and group of the keept temporary directories of failed + builds. */ + uid_t clientUid; + gid_t clientGid; + /* Whether, if we cannot realise the known closure corresponding to a derivation, we should try to normalise the derivation instead. */ diff --git a/nix/nix-daemon/nix-daemon.cc b/nix/nix-daemon/nix-daemon.cc index 35c284f..e900a7d 100644 --- a/nix/nix-daemon/nix-daemon.cc +++ b/nix/nix-daemon/nix-daemon.cc @@ -950,6 +950,19 @@ static void daemonLoop() strncpy(argvSaved[1], processName.c_str(), strlen(argvSaved[1])); } +#if defined(SO_PEERCRED) + /* Store the client's user and group for this connection. This + has to be done in the forked process since it is per + connection. */ + settings.clientUid = cred.uid; + settings.clientGid = cred.gid; +#else + /* Setting these to zero means: do not change, esp. do not + change to "root". */ + settings.clientUid = 0; + settings.clientGid = 0; +#endif + /* Handle the connection. */ from.fd = remote; to.fd = remote; -- 2.7.4