summary refs log tree commit diff
path: root/pkgs/build-support/build-fhs-userenv
diff options
context:
space:
mode:
authorNikolay Amiantov <ab@fmap.me>2015-12-15 16:46:37 +0300
committerNikolay Amiantov <ab@fmap.me>2015-12-17 14:21:06 +0300
commit230898ceb2e85ae11dbead2430a829babe2ab452 (patch)
treeb79b4b093a403ec51170eaf9740d214c6dc75542 /pkgs/build-support/build-fhs-userenv
parent83a8e8e4ef535c10e5e1059bcb5a5498e68ecc3c (diff)
downloadnixpkgs-230898ceb2e85ae11dbead2430a829babe2ab452.tar
nixpkgs-230898ceb2e85ae11dbead2430a829babe2ab452.tar.gz
nixpkgs-230898ceb2e85ae11dbead2430a829babe2ab452.tar.bz2
nixpkgs-230898ceb2e85ae11dbead2430a829babe2ab452.tar.lz
nixpkgs-230898ceb2e85ae11dbead2430a829babe2ab452.tar.xz
nixpkgs-230898ceb2e85ae11dbead2430a829babe2ab452.tar.zst
nixpkgs-230898ceb2e85ae11dbead2430a829babe2ab452.zip
chrootenv-user: don't unshare user namespace if we are root
Diffstat (limited to 'pkgs/build-support/build-fhs-userenv')
-rwxr-xr-xpkgs/build-support/build-fhs-userenv/chroot-user.rb43
1 files changed, 27 insertions, 16 deletions
diff --git a/pkgs/build-support/build-fhs-userenv/chroot-user.rb b/pkgs/build-support/build-fhs-userenv/chroot-user.rb
index 97316ac4369..250e6a90843 100755
--- a/pkgs/build-support/build-fhs-userenv/chroot-user.rb
+++ b/pkgs/build-support/build-fhs-userenv/chroot-user.rb
@@ -53,6 +53,7 @@ $unshare = make_fcall 'unshare', [Fiddle::TYPE_INT], Fiddle::TYPE_INT
 
 MS_BIND = 0x1000
 MS_REC  = 0x4000
+MS_SLAVE  = 0x80000
 $mount = make_fcall 'mount', [Fiddle::TYPE_VOIDP,
                               Fiddle::TYPE_VOIDP,
                               Fiddle::TYPE_VOIDP,
@@ -92,23 +93,31 @@ root = Dir.mktmpdir 'chrootenv'
 # we don't use threads at all.
 $cpid = $fork.call
 if $cpid == 0
-  # Save user UID and GID
-  uid = Process.uid
-  gid = Process.gid
-
-  # Create new mount and user namespaces
-  # CLONE_NEWUSER requires a program to be non-threaded, hence
-  # native fork above.
-  $unshare.call CLONE_NEWNS | CLONE_NEWUSER
-
-  # Map users and groups to the parent namespace
-  begin
-    # setgroups is only available since Linux 3.19
-    write_file '/proc/self/setgroups', 'deny'
-  rescue
+  # If we are root, no need to create new user namespace.
+  if Process.uid == 0
+    $unshare.call CLONE_NEWNS
+    # Mark all mounted filesystems as slave so changes
+    # don't propagate to the parent mount namespace.
+    $mount.call nil, '/', nil, MS_REC | MS_SLAVE, nil
+  else
+    # Save user UID and GID
+    uid = Process.uid
+    gid = Process.gid
+
+    # Create new mount and user namespaces
+    # CLONE_NEWUSER requires a program to be non-threaded, hence
+    # native fork above.
+    $unshare.call CLONE_NEWNS | CLONE_NEWUSER
+
+    # Map users and groups to the parent namespace
+    begin
+      # setgroups is only available since Linux 3.19
+      write_file '/proc/self/setgroups', 'deny'
+    rescue
+    end
+    write_file '/proc/self/uid_map', "#{uid} #{uid} 1"
+    write_file '/proc/self/gid_map', "#{gid} #{gid} 1"
   end
-  write_file '/proc/self/uid_map', "#{uid} #{uid} 1"
-  write_file '/proc/self/gid_map', "#{gid} #{gid} 1"
 
   # Do rbind mounts.
   mounts.each do |from, rto|
@@ -117,6 +126,8 @@ if $cpid == 0
     $mount.call from, to, nil, MS_BIND | MS_REC, nil
   end
 
+  # Don't make root private so privilege drops inside chroot are possible
+  File.chmod(0755, root)
   # Chroot!
   Dir.chroot root
   Dir.chdir '/'