From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS40173 216.86.168.0/24 X-Spam-Status: No, score=-3.7 required=3.0 tests=BAYES_00,RCVD_IN_DNSWL_LOW, SPF_HELO_PASS shortcircuit=no autolearn=ham autolearn_force=no version=3.4.0 Received: from mxout-08.mxes.net (mxout-08.mxes.net [216.86.168.183]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dcvr.yhbt.net (Postfix) with ESMTPS id 88B64201B0 for ; Tue, 21 Feb 2017 19:24:23 +0000 (UTC) Received: from battleground.jeremyevans.local (unknown [73.90.99.19]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.mxes.net (Postfix) with ESMTPSA id 38522509BF for ; Tue, 21 Feb 2017 14:24:22 -0500 (EST) Received: from jeremyevans.local (speedstar.jeremyevans.local [10.187.8.2]) by battleground.jeremyevans.local (OpenSMTPD) with ESMTP id 6a6fdfbd for ; Tue, 21 Feb 2017 11:24:21 -0800 (PST) Date: Tue, 21 Feb 2017 11:24:21 -0800 From: Jeremy Evans To: unicorn-public@bogomips.org Subject: Patch: Add support for chroot to Worker#user Message-ID: <20170221192421.GI93742@jeremyevans.local> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.7.2 (2016-11-26) List-Id: Any chrooting would need to happen inside Worker#user, because you can't chroot until after you have parsed the list of groups, and you must chroot before dropping root privileges. chroot is an important security feature, so that if the unicorn process is exploited, file system access is limited to the chroot directory instead of the entire system. This is not a complete patch as it does not include tests. I can add tests if you would consider accepting this feature. --- lib/unicorn/worker.rb | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/unicorn/worker.rb b/lib/unicorn/worker.rb index 6748a2f..db418ea 100644 --- a/lib/unicorn/worker.rb +++ b/lib/unicorn/worker.rb @@ -111,9 +111,10 @@ def close # :nodoc: # In most cases, you should be using the Unicorn::Configurator#user # directive instead. This method should only be used if you need # fine-grained control of exactly when you want to change permissions - # in your after_fork hooks. + # in your after_fork hooks, or if you want to use the chroot support. # - # Changes the worker process to the specified +user+ and +group+ + # Changes the worker process to the specified +user+ and +group+, + # and chroots to the current working directory if +chroot+ is set. # This is only intended to be called from within the worker # process from the +after_fork+ hook. This should be called in # the +after_fork+ hook after any privileged functions need to be @@ -123,7 +124,7 @@ def close # :nodoc: # directly back to the caller (usually the +after_fork+ hook. # These errors commonly include ArgumentError for specifying an # invalid user/group and Errno::EPERM for insufficient privileges - def user(user, group = nil) + def user(user, group = nil, chroot = false) # we do not protect the caller, checking Process.euid == 0 is # insufficient because modern systems have fine-grained # capabilities. Let the caller handle any and all errors. @@ -134,6 +135,10 @@ def user(user, group = nil) Process.initgroups(user, gid) Process::GID.change_privilege(gid) end + if chroot + Dir.chroot(Dir.pwd) + Dir.chdir('/') + end Process.euid != uid and Process::UID.change_privilege(uid) @switched = true end -- 2.11.0