From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) by lore.proxmox.com (Postfix) with ESMTPS id 72A161FF136 for ; Mon, 23 Feb 2026 14:09:25 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 60830BF8E; Mon, 23 Feb 2026 14:10:19 +0100 (CET) From: Filip Schauer To: pve-devel@lists.proxmox.com Subject: [PATCH container 6/8] namespaces: add helper to create user namespace from idmap Date: Mon, 23 Feb 2026 14:04:52 +0100 Message-ID: <20260223130706.90972-7-f.schauer@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260223130706.90972-1-f.schauer@proxmox.com> References: <20260223130706.90972-1-f.schauer@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1771852200487 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.002 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: CVFUMMXD6RGZYBCY4RTACR3CM2XFFYDZ X-Message-ID-Hash: CVFUMMXD6RGZYBCY4RTACR3CM2XFFYDZ X-MailFrom: f.schauer@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Signed-off-by: Filip Schauer --- src/PVE/LXC/Namespaces.pm | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/src/PVE/LXC/Namespaces.pm b/src/PVE/LXC/Namespaces.pm index 477d0ac..7836d06 100644 --- a/src/PVE/LXC/Namespaces.pm +++ b/src/PVE/LXC/Namespaces.pm @@ -3,10 +3,10 @@ package PVE::LXC::Namespaces; use strict; use warnings; -use Fcntl qw(O_WRONLY); +use Fcntl qw(O_WRONLY O_RDONLY); use Socket; -use PVE::Tools qw(CLONE_NEWNS CLONE_NEWUSER); +use PVE::Tools qw(CLONE_NEWNS CLONE_NEWUSER O_CLOEXEC); my sub set_id_map($$) { my ($pid, $id_map) = @_; @@ -67,4 +67,34 @@ sub run_in_userns($;$) { PVE::Tools::run_fork($child, { afterfork => $parent }); } +# Create a new user namespace with the provided idmap applied. +# Returns a file handle to the namespace. +sub new_userns($) { + my ($id_map) = @_; + socketpair(my $sp, my $sc, AF_UNIX, SOCK_STREAM, PF_UNSPEC) + or die "socketpair: $!\n"; + my $userns_fh; + my $child = sub { + close($sp); + PVE::Tools::unshare(CLONE_NEWUSER) or die "unshare(NEWUSER): $!\n"; + sync_send($sc, "1\n"); + shutdown($sc, 1); + sync_recv($sc, "2\n"); + close($sc); + }; + my $parent = sub { + my ($pid) = @_; + close($sc); + sync_recv($sp, "1\n"); + set_id_map($pid, $id_map); + sysopen($userns_fh, "/proc/$pid/ns/user", O_RDONLY | O_CLOEXEC) + or die "Failed to open user namespace of child: $!\n"; + sync_send($sp, "2\n"); + close($sp); + }; + PVE::Tools::run_fork($child, { afterfork => $parent }); + + return $userns_fh; +} + 1; -- 2.47.3