From nobody Tue Sep 29 09:46:20 2026 Received: from mail-yw1-f178.google.com (mail-yw1-f178.google.com [209.85.128.178]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DD006282F14 for ; Sun, 9 Aug 2026 15:45:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.178 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786290352; cv=none; b=VNDQECPwOaQ26rkw3HQUJdy+l2gteiigpN5o3GpsJ8YksgdYfaxwiBR0Y/vGRGBWV5o4P3maMOAU/IDzN7OPMDu6QcscWnFvUAmqvBpOcfHhV9un3QHgcldn4bexmfrBVjqtVvfRSjfFeHPR4B2t62UtArBIWI2unicZjQH7RAQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786290352; c=relaxed/simple; bh=eAMqol1zYgr+7QAqNpjRtuDJ60g/z6FUFiVLJddOzHU=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=YRcEX5ZRDs0TBvH7v0HjsAGxuY/UJE89rZibAIYRtb5LhounV4TcFychDsqj6ZOhjYgNbNZkvVeAfQCDC4EVKJ1Iy4kpHenMJ5DjWirqHN0bbvuhARsEbKxoWBqqfoA9S/L5ksF7LdAP9YgezWqaTCOtYn5EUrfGTehq2yPK5jA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=Il0X/cf8; arc=none smtp.client-ip=209.85.128.178 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Il0X/cf8" Received: by mail-yw1-f178.google.com with SMTP id 00721157ae682-8201447e8cdso18554797b3.3 for ; Sun, 09 Aug 2026 08:45:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786290350; x=1786895150; darn=vger.kernel.org; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to:content-type; bh=hn9JpmrDnY0h+wRK1i77j3APz1tT5vx3twjO5WqH6vM=; b=Il0X/cf8czIYtdi0HbSoViVP2LYI0ZX360MjxpLRm9OyOBNiWxf1VIMaH8zpg+8qQw NxNssyK/xZf33sk32yC8xfLqmfk7ZAqm4zMokJ6PpjVWCZbfxqp1jgd8Cbd2ip8z5ioa t9ngghBCUP4TixxA6G/QJowshsVEUarmcADRQs67iBwJB+7xHyGeXwp+jh8I+3VUSbD1 fzRzZGp8WHvxQqruEqU7e9CLbd5hOCl5CFrj1DI/AWtjv2z9SbnHL6zpn0X4uq2aZFHA owpuSXY/UXV8jCGle18fFsXtrMnWA/Hl3RLrxXDTANhXgUqBBVvVJf0ofDDEZdA9Deil SgMw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786290350; x=1786895150; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=hn9JpmrDnY0h+wRK1i77j3APz1tT5vx3twjO5WqH6vM=; b=PnSph2y5zQNlFiYzh7cDiYLxf/lY9hfhVxlRSk8TmbZblbv8A7UqrNKSez5AJIfvUY 8wL+CsRAjvSYYxadUR3n23aInR8mLiOPrvU5NhbWwDEk1LlZ6wtr6Cq0HkC4E1+F3nd0 RwzzoX+SpwmC7V9BtB2cuAkzS+jhul1+3LLJOEt/UWg2nYhaqi5jdm0WjvtlRZmSR5V/ nZPtsLHntBNi23FLJAgvJIpsru7jYI+CdDCtRXWYWw3Ai9w7CoF3WZB/Z4beRr43jVz4 xbYLN86TcpkyjfTb48V4gD7+PIdL5JiF6pzFGi+sTjaAyMTOytIVmY5XfABWPd4GVu5o dO1Q== X-Gm-Message-State: AOJu0YyygIMkQZETpatsqSSjMyVSZtfIUtlkJk2a2kBdIDWAA/XD4yL2 XjTBo13I5zPVu9sKAJYFGLeoy8KSjBR2Ep6r8vNUU2KuxkZiu7eVNFAi7Jb1H9Jj X-Gm-Gg: AR+sD11ZmXc5YOfKGtYFtbiskVUnIKFYHMABI8HzPJIaL0jGgTsMEVxmemhNnmtcqnG UW/eZ2q14003GtPSlYjMfoX2nqjI7UgTzchqCzs9ryzjH1I8qOsdGKRj8GpxmpOTMaDJlR/tf8V /nQyjCDxECm0iiy4Z+eLGsboIbZaMgC31kcmo6QJcupBiqdDoYn9YYBu/bHpfh96XYiDfiJbidt I/fUWU/DQdma+Izephmk5S6WwdRtyiYeNMwuSlJ8oJQWMZ2PJCBSsS/JoawRrmir8IL/oPzsppy qG6wWX9O03RHc/eiGkPQwJrHVTVQc/f12Vnqj6bNDwoyKzDLfSHM0dT6PKunAQQlmw/0LUh5bHM pJXjhI+LTI0ggoL7fwHtjVcma8K1fLWsB/PI5KmmhmqIAQrQcX984F8OMUwXhAfUelhO4XtqC7l ayJC6ST5NslM2aaLcKm5PW3nQ8gJvuEskp2rxR3Gyw2oHuwT5uufTGxp4p6cVLeWt1eJabTe0N/ lTXK7YIh2yORy7Sh6M8nhw= X-Received: by 2002:a05:690e:16e3:b0:668:9567:db70 with SMTP id 956f58d0204a3-6699aacf1d5mr15790620d50.40.1786290349820; Sun, 09 Aug 2026 08:45:49 -0700 (PDT) Received: from zenbox ([2600:1700:18fb:6011:4665:53b0:3ac9:3545]) by smtp.gmail.com with ESMTPSA id 956f58d0204a3-66acacdbea9sm4838001d50.3.2026.08.09.08.45.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Aug 2026 08:45:49 -0700 (PDT) From: Justin Suess To: gnoack3000@gmail.com, mic@digikod.net Cc: linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org, Justin Suess Subject: [PATCH v4 1/5] landlock: Check landlock_restrict_self(2)'s flags before privileges Date: Sun, 9 Aug 2026 11:45:19 -0400 Message-ID: <20260809154544.1253100-2-utilityemal77@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260809154544.1253100-1-utilityemal77@gmail.com> References: <20260809154544.1253100-1-utilityemal77@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable sys_landlock_restrict_self() currently checks the no_new_privs / CAP_SYS_ADMIN requirement before validating the flags argument. An unprivileged caller without no_new_privs thus gets EPERM even when the passed flags are invalid, hiding the EINVAL error. Move the no_new_privs / CAP_SYS_ADMIN check just after the flags check so that malformed calls consistently error out with EINVAL whatever the caller's privileges, the same way seccomp(2) validates its flags before checking no_new_privs. Update the restrict_self_checks_ordering test accordingly. Cc: Micka=C3=ABl Sala=C3=BCn Signed-off-by: Justin Suess --- Notes: v4: - New patch, following Micka=C3=ABl's review of the main patch: che= ck the flags argument before the no_new_privs / CAP_SYS_ADMIN requirement, in the same order as seccomp(2). security/landlock/syscalls.c | 8 ++++---- tools/testing/selftests/landlock/base_test.c | 6 +++++- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/security/landlock/syscalls.c b/security/landlock/syscalls.c index 36b02892c62f..e3ef7b980c82 100644 --- a/security/landlock/syscalls.c +++ b/security/landlock/syscalls.c @@ -535,6 +535,10 @@ SYSCALL_DEFINE2(landlock_restrict_self, const int, rul= eset_fd, const __u32, if (!is_initialized()) return -EOPNOTSUPP; =20 + if ((flags | LANDLOCK_MASK_RESTRICT_SELF) !=3D + LANDLOCK_MASK_RESTRICT_SELF) + return -EINVAL; + /* * Similar checks as for seccomp(2), except that an -EPERM may be * returned. @@ -543,10 +547,6 @@ SYSCALL_DEFINE2(landlock_restrict_self, const int, rul= eset_fd, const __u32, !ns_capable_noaudit(current_user_ns(), CAP_SYS_ADMIN)) return -EPERM; =20 - if ((flags | LANDLOCK_MASK_RESTRICT_SELF) !=3D - LANDLOCK_MASK_RESTRICT_SELF) - return -EINVAL; - /* Translates "off" flag to boolean. */ log_same_exec =3D !(flags & LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF); /* Translates "on" flag to boolean. */ diff --git a/tools/testing/selftests/landlock/base_test.c b/tools/testing/s= elftests/landlock/base_test.c index cbd3c1669951..f3c126d5c003 100644 --- a/tools/testing/selftests/landlock/base_test.c +++ b/tools/testing/selftests/landlock/base_test.c @@ -255,8 +255,12 @@ TEST(restrict_self_checks_ordering) =20 /* Checks unprivileged enforcement without no_new_privs. */ drop_caps(_metadata); + /* + * The flags validity is checked before the no_new_privs / + * CAP_SYS_ADMIN requirement. + */ ASSERT_EQ(-1, landlock_restrict_self(-1, -1)); - ASSERT_EQ(EPERM, errno); + ASSERT_EQ(EINVAL, errno); ASSERT_EQ(-1, landlock_restrict_self(-1, 0)); ASSERT_EQ(EPERM, errno); ASSERT_EQ(-1, landlock_restrict_self(ruleset_fd, 0)); --=20 2.55.0 From nobody Tue Sep 29 09:46:20 2026 Received: from mail-yw1-f177.google.com (mail-yw1-f177.google.com [209.85.128.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F31AA35C697 for ; Sun, 9 Aug 2026 21:25:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.177 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786310709; cv=none; b=fRshNTVY1Ycg7r5/8Q5mICFUZZoAjvcJIS/j79IMMWOsKbWY/pih7Vy4LboQdQfa++fpBlg888c4UyA6OevOJS9vT+v5E3W/N3i709FHI3Gy+zah7XtVdLomVXnTEWHfkjHqSaLGzWs21IsbXf09YeExCd92t1W/r40yfTtXa9U= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786310709; c=relaxed/simple; bh=Lcp8j2SUJLlQP7y2eZFQ8/UVa7Prfjafhf5LdQWkeMs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=MeJhKvinOj4G3dsRAmtWKWzcnrPUOLXr0y607W2CmpMHESmAJjnofDEEn9zWb2kCM51dpnUvMx0yHsiNEsyHG5oRvRqsg1AjUGhb8bISbVl4LCSkoKXqBvK4Iays4I3UfVN9SDF+eQbYxWi4PtwLtFEy1KqfzHzdgjXL6t8bOws= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=PUrb5T+A; arc=none smtp.client-ip=209.85.128.177 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="PUrb5T+A" Received: by mail-yw1-f177.google.com with SMTP id 00721157ae682-81f64e8dfbcso18318467b3.2 for ; Sun, 09 Aug 2026 14:25:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786310706; x=1786915506; darn=vger.kernel.org; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to:content-type; bh=xwZIucPGJPCGDD6h9KBB2EiWbEKq4cSnPvNB4kuHRak=; b=PUrb5T+AuaP9N3lDCfkYFIo5p6D7bKZ0dXptK9rFidY22o5gXHkEfQ1ghB9BiJUkc7 sACVuqhizzy7pmTvB3S1P6G0/we+IkiEP/MsvmwK0P1DCNe7qo5dyGnFbHY1NLGYsur8 z/ANsYBJwp4mpzCtPlSYoev/gw+tBTVVyTUYRMxU7UzE1teTWQamMReFZpalX5S4+Vg6 I0B2ruoIymME391RITkO4g7sf3IF+ip8PXBD99r0B/f5k5WCNBKmUk8AMFvcYcnXrGfX r0pG0bxxIdmnKugPT2q4OfVr/EQK6PExQFgNsvLXeWcbg8fmAg1x6fDqOVxAyVb1xDkr /cBg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786310706; x=1786915506; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=xwZIucPGJPCGDD6h9KBB2EiWbEKq4cSnPvNB4kuHRak=; b=EwAHEyNKdFQtszLkA7D3D5N2tFDiK0SeX5Wx+Rf6bzAixj60GEMdKgjq3cRcgGsWcM 2xXruyNQGklE9FElkOKS1wz8H2WIUW5vX2/hcWArtwnUunL48wdwogJWYjldamcC5ha7 N32E+szdYw+vZMmbI/eAHPlgvdF/OtRR53W2LDlYW5cykoe3dplYoqjh2OYHN/Q2s5hg 1v0W+cfPSy/HxkqRkOPS6aJf0deSqWYPmuaPfijCGV5adE78lZ2yUsKoP2s3VQkPTOWn 6wgmA1lanhiL1p8q9ycuxjbS9ICVcsyqCodF1KGZUGp1ivBPJwOW3qgy5Wxsr80iYdIf 33CA== X-Gm-Message-State: AOJu0YwST9okah3XpI3ElPdAzgGSFskcOsFgByve1TJaFv6CrHVY5s2o CCSEjlegZ1mPw9ny6qnkqtuanngm+2mGtDUm4tvxU+ukhpW9IZhQjQdq X-Gm-Gg: AR+sD12Wg5HlJFVnRVZ58Kii0Pr7Qmja20O4HA2A4RIYb1oYM/Cx15QUf2G1jFZTH95 /oKJytDOD48P8CoC1AyQsGTpWl6i3IKURCndutmOnk4os0Fi6Mv+Stw6insziUIHhp+ba87SzWF BDuZwQu5w7BKoBPtVllyGuXf2SvpWNH1f+TDz2lzvSsGpVV9iPBn+ioGxpTJg1GMLb27rjUL2/J 6/Tq0tG8u/IMGj0pyY+DIdM6WH+pFTBqXuJeANnArRXiAP/J32pHUcBnyko2uty7TxrrjxqvEsk AN9ybDPaduzLLOuxi7hi4PNmog/mn1TZRr1pATqf4qlotR5IPFGaQtw3mQ0Cbq8eh0xnRE/L16d eEPmxFduUa8t2rWUpPFPwxlpRS/a7sbqhZVm6pWW/05hQ0zCQDKVHqGaHHZjSRl2MUaQh1WnPdv EFtBB5qziSw4aV1MC4v2Ycfw2ogTgd6AnJFpF/BhCbgWh+JKK28BEdiLdB3BjvpA36S/Nr8wHyB Qlzr6tAkHUkzqi5FGLXJkfeckz52IhrOAo= X-Received: by 2002:a05:690c:6e01:b0:820:132b:6309 with SMTP id 00721157ae682-8202b0835bemr230889597b3.35.1786310706433; Sun, 09 Aug 2026 14:25:06 -0700 (PDT) Received: from zenbox ([2600:1700:18fb:6011:4665:53b0:3ac9:3545]) by smtp.gmail.com with ESMTPSA id 00721157ae682-823efa07c0esm44883487b3.1.2026.08.09.14.25.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Aug 2026 14:25:05 -0700 (PDT) From: Justin Suess To: gnoack3000@gmail.com, mic@digikod.net Cc: linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org, Justin Suess Subject: [PATCH v4 2/5] landlock: Add LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS Date: Sun, 9 Aug 2026 17:24:59 -0400 Message-ID: <20260809212459.2427878-1-utilityemal77@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260809154544.1253100-1-utilityemal77@gmail.com> References: <20260809154544.1253100-1-utilityemal77@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Add a landlock_restrict_self(2) flag to set the no_new_privs attribute of the calling thread only after enforcement of the ruleset: no_new_privs is set if and only if the call succeeds. This removes the need for a prior prctl(2) PR_SET_NO_NEW_PRIVS call and guarantees that a failed enforcement leaves the attribute unchanged. Because no_new_privs is set by the call itself, the no_new_privs / CAP_SYS_ADMIN requirement of landlock_restrict_self(2) is fulfilled by construction, and the related EPERM check is skipped. Unlike LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF, this flag always requires a valid ruleset: with a ruleset_fd of -1, such a call would be nothing more than a Landlock-flavored prctl(2) PR_SET_NO_NEW_PRIVS, and there is no valid use case for setting no_new_privs (possibly with LANDLOCK_RESTRICT_SELF_TSYNC) without also enforcing Landlock restrictions. Rejecting these calls also keeps the option of giving them a meaning later. The attribute is only set past the last point of failure, just before committing the new credentials. When combined with LANDLOCK_RESTRICT_SELF_TSYNC, no_new_privs is set on the sibling threads as well, in their commit phase, with the same ordering. Bump the Landlock ABI version to 11, and include the minimal related test changes to keep the tests bisectable. Cc: Micka=C3=ABl Sala=C3=BCn Signed-off-by: Justin Suess --- Notes: v3->v4: - Rebase on the new preparatory patch: the flags-before-privileges ordering (and its EINVAL/EPERM visible change) is now handled there. - Drop the set_no_new_privs variable and check the flag directly at both use sites, per Micka=C3=ABl's feedback. - Fold in the minimal selftest changes (ABI version, last-flag, and checks-ordering updates) to keep the series bisectable, following the commit tweaked by Micka=C3=ABl. - Reword the flag kdoc: "call (or %CAP_SYS_ADMIN use)" instead of "call, and with it the %CAP_SYS_ADMIN requirement". include/uapi/linux/landlock.h | 13 ++++++++++ security/landlock/limits.h | 2 +- security/landlock/syscalls.c | 27 +++++++++++++++----- security/landlock/tsync.c | 8 ++++-- security/landlock/tsync.h | 4 ++- tools/testing/selftests/landlock/base_test.c | 12 +++++++-- 6 files changed, 53 insertions(+), 13 deletions(-) diff --git a/include/uapi/linux/landlock.h b/include/uapi/linux/landlock.h index 27ae3f39cafb..cceda3b3b961 100644 --- a/include/uapi/linux/landlock.h +++ b/include/uapi/linux/landlock.h @@ -191,12 +191,25 @@ struct landlock_ruleset_attr { * * If the calling thread is running with no_new_privs, this operation * enables no_new_privs on the sibling threads as well. + * + * The following flag ties the no_new_privs attribute to the ruleset + * enforcement: + * + * %LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS + * Sets the no_new_privs attribute of the calling thread only once the + * enforcement of the ruleset succeeded: no_new_privs is set if and on= ly + * if sys_landlock_restrict_self() succeeds. This removes the need fo= r a + * prior :manpage:`prctl(2)` ``PR_SET_NO_NEW_PRIVS`` call (or + * %CAP_SYS_ADMIN use). This flag requires a ruleset. When + * combined with %LANDLOCK_RESTRICT_SELF_TSYNC, no_new_privs is set on= the + * sibling threads as well. */ /* clang-format off */ #define LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF (1U << 0) #define LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON (1U << 1) #define LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF (1U << 2) #define LANDLOCK_RESTRICT_SELF_TSYNC (1U << 3) +#define LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS (1U << 4) /* clang-format on */ =20 /** diff --git a/security/landlock/limits.h b/security/landlock/limits.h index 08d5f2f6d321..1a7c5fb8f6fd 100644 --- a/security/landlock/limits.h +++ b/security/landlock/limits.h @@ -34,7 +34,7 @@ #define LANDLOCK_NUM_ACCESS_MAX \ MAX(MAX(LANDLOCK_NUM_ACCESS_FS, LANDLOCK_NUM_ACCESS_NET), LANDLOCK_NUM_SC= OPE) =20 -#define LANDLOCK_LAST_RESTRICT_SELF LANDLOCK_RESTRICT_SELF_TSYNC +#define LANDLOCK_LAST_RESTRICT_SELF LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS #define LANDLOCK_MASK_RESTRICT_SELF ((LANDLOCK_LAST_RESTRICT_SELF << 1) - = 1) =20 /* clang-format on */ diff --git a/security/landlock/syscalls.c b/security/landlock/syscalls.c index e3ef7b980c82..e5f65a1c35ff 100644 --- a/security/landlock/syscalls.c +++ b/security/landlock/syscalls.c @@ -169,7 +169,7 @@ static const struct file_operations ruleset_fops =3D { * If the change involves a fix that requires userspace awareness, also up= date * the errata documentation in Documentation/userspace-api/landlock.rst . */ -const int landlock_abi_version =3D 10; +const int landlock_abi_version =3D 11; =20 /** * sys_landlock_create_ruleset - Create a new ruleset @@ -502,21 +502,28 @@ SYSCALL_DEFINE4(landlock_add_rule, const int, ruleset= _fd, * - %LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON * - %LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF * - %LANDLOCK_RESTRICT_SELF_TSYNC + * - %LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS * * This system call enforces a Landlock ruleset on the current thread. * Enforcing a ruleset requires that the task has %CAP_SYS_ADMIN in its * namespace or is running with no_new_privs. This avoids scenarios where * unprivileged tasks can affect the behavior of privileged children. * + * With %LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS, the no_new_privs attribute o= f the + * calling thread is set only once the enforcement of the ruleset succeede= d, + * which fulfills the above requirement: no_new_privs is set if and only i= f the + * call succeeds. + * * Return: 0 on success, or -errno on failure. Possible returned errors a= re: * * - %EOPNOTSUPP: Landlock is supported by the kernel but disabled at boot= time; * - %EINVAL: @flags contains an unknown bit. * - %EBADF: @ruleset_fd is not a file descriptor for the current thread; * - %EBADFD: @ruleset_fd is not a ruleset file descriptor; - * - %EPERM: @ruleset_fd has no read access to the underlying ruleset, or = the - * current thread is not running with no_new_privs, or it doesn't have - * %CAP_SYS_ADMIN in its namespace. + * - %EPERM: @ruleset_fd has no read access to the underlying ruleset, or + * %LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS is not set while the current thr= ead + * is not running with no_new_privs and doesn't have %CAP_SYS_ADMIN in i= ts + * namespace. * - %E2BIG: The maximum number of stacked rulesets is reached for the cur= rent * thread. * @@ -541,9 +548,11 @@ SYSCALL_DEFINE2(landlock_restrict_self, const int, rul= eset_fd, const __u32, =20 /* * Similar checks as for seccomp(2), except that an -EPERM may be - * returned. + * returned. LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS fulfills this + * requirement. */ - if (!task_no_new_privs(current) && + if (!(flags & LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS) && + !task_no_new_privs(current) && !ns_capable_noaudit(current_user_ns(), CAP_SYS_ADMIN)) return -EPERM; =20 @@ -620,12 +629,16 @@ SYSCALL_DEFINE2(landlock_restrict_self, const int, ru= leset_fd, const __u32, =20 if (flags & LANDLOCK_RESTRICT_SELF_TSYNC) { const int err =3D landlock_restrict_sibling_threads( - current_cred(), new_cred); + current_cred(), new_cred, flags); if (err) { abort_creds(new_cred); return err; } } =20 + /* Sets no_new_privs past the last point of failure. */ + if (flags & LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS) + task_set_no_new_privs(current); + return commit_creds(new_cred); } diff --git a/security/landlock/tsync.c b/security/landlock/tsync.c index c5730bbd9ed3..0b71e158c3f5 100644 --- a/security/landlock/tsync.c +++ b/security/landlock/tsync.c @@ -17,6 +17,7 @@ #include #include #include +#include =20 #include "cred.h" #include "tsync.h" @@ -466,7 +467,8 @@ static void cancel_tsync_works(const struct tsync_works= *works, * restrict_sibling_threads - enables a Landlock policy for all sibling th= reads */ int landlock_restrict_sibling_threads(const struct cred *old_cred, - const struct cred *new_cred) + const struct cred *new_cred, + const u32 restrict_flags) { int err; struct tsync_shared_context shared_ctx; @@ -481,7 +483,9 @@ int landlock_restrict_sibling_threads(const struct cred= *old_cred, init_completion(&shared_ctx.all_finished); shared_ctx.old_cred =3D old_cred; shared_ctx.new_cred =3D new_cred; - shared_ctx.set_no_new_privs =3D task_no_new_privs(current); + shared_ctx.set_no_new_privs =3D + (restrict_flags & LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS) || + task_no_new_privs(current); =20 /* * Serialize concurrent TSYNC operations to prevent deadlocks when diff --git a/security/landlock/tsync.h b/security/landlock/tsync.h index ef86bb61c2f6..2ae4f938ca00 100644 --- a/security/landlock/tsync.h +++ b/security/landlock/tsync.h @@ -9,8 +9,10 @@ #define _SECURITY_LANDLOCK_TSYNC_H =20 #include +#include =20 int landlock_restrict_sibling_threads(const struct cred *old_cred, - const struct cred *new_cred); + const struct cred *new_cred, + u32 restrict_flags); =20 #endif /* _SECURITY_LANDLOCK_TSYNC_H */ diff --git a/tools/testing/selftests/landlock/base_test.c b/tools/testing/s= elftests/landlock/base_test.c index f3c126d5c003..288d6bc19232 100644 --- a/tools/testing/selftests/landlock/base_test.c +++ b/tools/testing/selftests/landlock/base_test.c @@ -76,7 +76,7 @@ TEST(abi_version) const struct landlock_ruleset_attr ruleset_attr =3D { .handled_access_fs =3D LANDLOCK_ACCESS_FS_READ_FILE, }; - ASSERT_EQ(10, landlock_create_ruleset(NULL, 0, + ASSERT_EQ(11, landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION)); =20 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 0, @@ -265,6 +265,14 @@ TEST(restrict_self_checks_ordering) ASSERT_EQ(EPERM, errno); ASSERT_EQ(-1, landlock_restrict_self(ruleset_fd, 0)); ASSERT_EQ(EPERM, errno); + /* + * LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS fulfills the no_new_privs / + * CAP_SYS_ADMIN requirement but requires a ruleset, so the FD is + * checked next. + */ + ASSERT_EQ(-1, landlock_restrict_self( + -1, LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS)); + ASSERT_EQ(EBADF, errno); =20 ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)); =20 @@ -310,7 +318,7 @@ TEST(restrict_self_fd_logging_flags) =20 TEST(restrict_self_logging_flags) { - const __u32 last_flag =3D LANDLOCK_RESTRICT_SELF_TSYNC; + const __u32 last_flag =3D LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS; =20 /* Tests invalid flag combinations. */ =20 --=20 2.55.0 From nobody Tue Sep 29 09:46:20 2026 Received: from mail-yx1-f41.google.com (mail-yx1-f41.google.com [74.125.224.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3FABA28CF5D for ; Sun, 9 Aug 2026 15:45:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.224.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786290355; cv=none; b=iRsgUOJKmrBEQzVz6MUPHADCZS0c17I99NqrgncYHYgPLYcs8fKDPF+o3bnFYaLxyx6fGKdRX/qvXV8Ev8K2f5NdjgwGfPY86PygHWSSXg7ZwplbpldqBi+/wnYp9bxv7xcx1dqsvogN/K/35WQTsz5fXAepAPsUS7hnJ1ryPcs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786290355; c=relaxed/simple; bh=PP74AEuJV6z4so5ONmbbCZB2EUZwnxJ0x3ltSyo07Uk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=fd9cHIWLFAmYvnudmFxftv8dqjj7Ne90IW3Mq1GePFHOauc0E9AtYnwepGXLnMy+wYHtzn3Irue4x1CKAatuN4wmoQX8/vFi19nfMxmC0Yea7oeozJVm5XxpcQLd8NG89Rr2TKD4Qg8vxX3dCRsQT8a1J8sd78AhK7b1J/C+f1k= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=plk4ljHI; arc=none smtp.client-ip=74.125.224.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="plk4ljHI" Received: by mail-yx1-f41.google.com with SMTP id 956f58d0204a3-664ce3000e6so696326d50.0 for ; Sun, 09 Aug 2026 08:45:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786290353; x=1786895153; darn=vger.kernel.org; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to:content-type; bh=028iBPYlb+T5xtatdfaP1GUdKAs7WH+fsWa8mh5VDGI=; b=plk4ljHILn3tkrHx9LNkkTR5pSxH5LNag/MPPMGgOq23F/LuKq1zaFQLrVxND8Dmgm oQ9ItZUPuqeP/Vdauh9Z1mzJ8ZIkUelRL033utCyA4V5YZM684OtVRDCvaZ/jfdEEXMK rDPqjnpH4pT4/fcHVVT4rwLd1NjO2kvHSye5UYUUlZr1DE5t2gWiAmps24IqKMhvDeKg W3xkANREbOrsWHIl0h9U3p4BrT2mBfOj2GgZNXSOL4S6wE/sw06qFzUBECSny16vigAv nfYtkijwflmytemb+qJKWf84FgtpJdaKtp3CiTK8Pk6y7+/oKiWYiZWgcc9A5cCQjdmt q1PA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786290353; x=1786895153; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=028iBPYlb+T5xtatdfaP1GUdKAs7WH+fsWa8mh5VDGI=; b=cm2BKXQ4UOt8EjKBZNMYMoxwmehTnRK/JWNMlKCp2T6PoRnfhJCVVuKU+9P014M/M6 DoygkkFcYUZ+VVhwjrAj/em5VTzrQ7UI+bSZ6M7b6DJhbQIN97z4t3RnVqyYjTuP5P2g JzhdXzlhPnNiVuvOiD6t4mRVuZrFwb6fz7tr9vbDJ3znbjIjXZsAC/IUlMXBy/462XXN Dj6f/2h2fPyVdTpO5olC+yxwWGPJ5U9pl1sQOLkPWhuEl2PpuWqETB8HTW7v95qsHe+e OVcQcDxC9dSf2W5hXGl90KkaoJ+iuMWUvQFnilLT9O7TB/SjAUq6J+qlRWl34E6EiNRQ xT9g== X-Gm-Message-State: AOJu0Yz9nER0fdZ1x23wFRtpQwzREdqX7QJ/axu0Fno1Sjw1VI7Rc1OG +CSw+qr9M5/MF56dW1Z1M9n54XpZTcojhhdsLy0QHRQ85ejrPXtCDA4z X-Gm-Gg: AR+sD11mzzLIKnHnp0svhSG9KS6VPz47bdVsOYDQrhf7upJHDVbZr/ORhL78S61lqOc 4bMxzv8asTXztLjmZo7OqMKE8OlrOlPGgGyMPA9EO2Lzpwh4EpKYsjrb5mr4+sY0jpYYu9cFh6Z WQaClLZ+hWeIgpPOVleo3BDcnsaNlW1Vbq3Plu0EZTPGLZXyli94vUK4MpeNUizoAF8Bl5aCrF7 raOivPkbfd3ewPp2chBIlyw2b1j+H9tmfFVl56sv8gHIqNVZ4Wm5J+cm1GAzs1MeP9/Mbl4kARi t6lm7HVZE5UUXDXDdw09u1xUkSASTws41c3Lg63vQMotIKbPbvWR9zmgDiy3/ZAr0CoaQxNLaYm oYkRwYKI89hhFdWKNaOgJW66M4nVPTOpz2I/bm0BkHPQY2RoahLGnHjuiC24nT9aiHWIRrlFXNp 58+N5WzmF1op6s5gUYDzQUKsSOV6NT4TXl+rK1gA6W2nLk2jVgF6r/jp/ERICSP2zIQJGDLV5IF rovbTE04pFrtJ9SlS1C3Kg= X-Received: by 2002:a05:690e:480d:b0:668:90cd:8aef with SMTP id 956f58d0204a3-66acd2f1bf7mr6955238d50.25.1786290352849; Sun, 09 Aug 2026 08:45:52 -0700 (PDT) Received: from zenbox ([2600:1700:18fb:6011:4665:53b0:3ac9:3545]) by smtp.gmail.com with ESMTPSA id 956f58d0204a3-66acacdbea9sm4838001d50.3.2026.08.09.08.45.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Aug 2026 08:45:52 -0700 (PDT) From: Justin Suess To: gnoack3000@gmail.com, mic@digikod.net Cc: linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org, Justin Suess Subject: [PATCH v4 3/5] selftests/landlock: Test LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS Date: Sun, 9 Aug 2026 11:45:21 -0400 Message-ID: <20260809154544.1253100-4-utilityemal77@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260809154544.1253100-1-utilityemal77@gmail.com> References: <20260809154544.1253100-1-utilityemal77@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Check that a successful landlock_restrict_self(2) call with LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS sets no_new_privs without a prior prctl(2) call nor CAP_SYS_ADMIN, that a failed call from both an invalid ruleset and hitting the layer maximum leaves the attribute unchanged, and that LANDLOCK_RESTRICT_SELF_TSYNC extends it to sibling threads. Also check that this flag requires a ruleset. Turn the multi_threaded_success test into a multi_threaded fixture with success, no_new_privs, and no_new_privs_max_layers variants to factor out the threading code. Finally, rename restrict_self_fd_logging_flags to restrict_self_fd_flags, and restrict_self_logging_flags to restrict_self_flags to indicate that non-logging flags are now tested. Signed-off-by: Justin Suess --- Notes: v3->v4: - Turn multi_threaded_{success,no_new_privs,no_new_privs_max_layers} into variants of a multi_threaded fixture, per Micka=C3=ABl's feedback. - Move the minimal ABI/flag checks into the previous patch. tools/testing/selftests/landlock/base_test.c | 86 ++++++++++++++++- tools/testing/selftests/landlock/tsync_test.c | 96 ++++++++++++++++--- 2 files changed, 168 insertions(+), 14 deletions(-) diff --git a/tools/testing/selftests/landlock/base_test.c b/tools/testing/s= elftests/landlock/base_test.c index 288d6bc19232..d20ab8f0862c 100644 --- a/tools/testing/selftests/landlock/base_test.c +++ b/tools/testing/selftests/landlock/base_test.c @@ -289,6 +289,41 @@ TEST(restrict_self_checks_ordering) ASSERT_EQ(0, close(ruleset_fd)); } =20 +TEST(restrict_self_max_layers) +{ + const struct landlock_ruleset_attr ruleset_attr =3D { + .handled_access_fs =3D LANDLOCK_ACCESS_FS_EXECUTE, + }; + struct landlock_path_beneath_attr path_beneath_attr =3D { + .allowed_access =3D LANDLOCK_ACCESS_FS_EXECUTE, + .parent_fd =3D -1, + }; + const int ruleset_fd =3D + landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); + ASSERT_LE(0, ruleset_fd); + + path_beneath_attr.parent_fd =3D + open("/tmp", O_PATH | O_NOFOLLOW | O_DIRECTORY | O_CLOEXEC); + ASSERT_LE(0, path_beneath_attr.parent_fd); + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, + &path_beneath_attr, 0)); + ASSERT_EQ(0, close(path_beneath_attr.parent_fd)); + + /* Enforces the maximum number of allowed layers. */ + for (int i =3D 0; i < LANDLOCK_MAX_NUM_LAYERS; i++) + ASSERT_EQ(0, landlock_restrict_self(ruleset_fd, 0)); + + /* Enforces one too many rulesets. */ + drop_caps(_metadata); + ASSERT_EQ(-1, landlock_restrict_self( + ruleset_fd, LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS)); + ASSERT_EQ(E2BIG, errno); + + /* Checks that the failed call did not set no_new_privs. */ + ASSERT_EQ(0, prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0)); + ASSERT_EQ(0, close(ruleset_fd)); +} + TEST(restrict_self_fd) { int fd; @@ -300,7 +335,7 @@ TEST(restrict_self_fd) EXPECT_EQ(EBADFD, errno); } =20 -TEST(restrict_self_fd_logging_flags) +TEST(restrict_self_fd_flags) { int fd; =20 @@ -314,9 +349,14 @@ TEST(restrict_self_fd_logging_flags) EXPECT_EQ(-1, landlock_restrict_self( fd, LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF)); EXPECT_EQ(EBADFD, errno); + + /* LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS requires a ruleset FD. */ + EXPECT_EQ(-1, landlock_restrict_self( + fd, LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS)); + EXPECT_EQ(EBADFD, errno); } =20 -TEST(restrict_self_logging_flags) +TEST(restrict_self_flags) { const __u32 last_flag =3D LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS; =20 @@ -361,6 +401,17 @@ TEST(restrict_self_logging_flags) LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON)); EXPECT_EQ(EBADF, errno); =20 + /* LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS requires a ruleset FD. */ + + EXPECT_EQ(-1, landlock_restrict_self( + -1, LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS)); + EXPECT_EQ(EBADF, errno); + + EXPECT_EQ(-1, landlock_restrict_self( + -1, LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF | + LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS)); + EXPECT_EQ(EBADF, errno); + /* Tests with an invalid ruleset_fd. */ =20 EXPECT_EQ(-1, landlock_restrict_self( @@ -371,6 +422,37 @@ TEST(restrict_self_logging_flags) -1, LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF)); } =20 +TEST(restrict_self_no_new_privs) +{ + const struct landlock_ruleset_attr ruleset_attr =3D { + .handled_access_fs =3D LANDLOCK_ACCESS_FS_READ_FILE, + }; + const int ruleset_fd =3D + landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); + + ASSERT_LE(0, ruleset_fd); + + /* + * The calling thread does not need CAP_SYS_ADMIN nor an explicit + * prctl(2) PR_SET_NO_NEW_PRIVS call. + */ + drop_caps(_metadata); + ASSERT_EQ(0, prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0)); + + /* Checks that a failed call does not set no_new_privs. */ + EXPECT_EQ(-1, landlock_restrict_self( + -1, LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS)); + EXPECT_EQ(EBADF, errno); + EXPECT_EQ(0, prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0)); + + /* Checks that a successful call sets no_new_privs. */ + ASSERT_EQ(0, landlock_restrict_self( + ruleset_fd, LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS)); + EXPECT_EQ(1, prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0)); + + EXPECT_EQ(0, close(ruleset_fd)); +} + TEST(ruleset_fd_io) { struct landlock_ruleset_attr ruleset_attr =3D { diff --git a/tools/testing/selftests/landlock/tsync_test.c b/tools/testing/= selftests/landlock/tsync_test.c index 9cf1491bbaaf..2b53596c986e 100644 --- a/tools/testing/selftests/landlock/tsync_test.c +++ b/tools/testing/selftests/landlock/tsync_test.c @@ -62,32 +62,104 @@ static void *idle(void *data) pthread_cleanup_pop(1); } =20 -TEST(multi_threaded_success) +FIXTURE(multi_threaded) { - pthread_t t1, t2; - bool no_new_privs1, no_new_privs2; - const int ruleset_fd =3D create_ruleset(_metadata); + int ruleset_fd; +}; + +FIXTURE_VARIANT(multi_threaded) +{ + const __u32 restrict_flags; + /* Sets no_new_privs with prctl(2) before the enforcement. */ + const bool prior_no_new_privs; + /* Enforces the maximum number of allowed layers beforehand. */ + const bool max_layers; + const int expected_errno; + /* Expected no_new_privs state of all threads after the call. */ + const bool expected_no_new_privs; +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(multi_threaded, success) { + /* clang-format on */ + .restrict_flags =3D LANDLOCK_RESTRICT_SELF_TSYNC, + .prior_no_new_privs =3D true, + .expected_no_new_privs =3D true, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(multi_threaded, no_new_privs) { + /* clang-format on */ + .restrict_flags =3D LANDLOCK_RESTRICT_SELF_TSYNC | + LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS, + .expected_no_new_privs =3D true, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(multi_threaded, no_new_privs_max_layers) { + /* clang-format on */ + .restrict_flags =3D LANDLOCK_RESTRICT_SELF_TSYNC | + LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS, + .max_layers =3D true, + .expected_errno =3D E2BIG, + .expected_no_new_privs =3D false, +}; + +FIXTURE_SETUP(multi_threaded) +{ + self->ruleset_fd =3D create_ruleset(_metadata); + + if (variant->max_layers) { + /* Enforces the maximum number of allowed layers. */ + for (int i =3D 0; i < LANDLOCK_MAX_NUM_LAYERS; i++) + ASSERT_EQ(0, + landlock_restrict_self(self->ruleset_fd, 0)); + } =20 disable_caps(_metadata); +} + +FIXTURE_TEARDOWN(multi_threaded) +{ + EXPECT_EQ(0, close(self->ruleset_fd)); +} + +TEST_F(multi_threaded, restrict) +{ + pthread_t t1, t2; + bool no_new_privs1, no_new_privs2; =20 ASSERT_EQ(0, pthread_create(&t1, NULL, idle, &no_new_privs1)); ASSERT_EQ(0, pthread_create(&t2, NULL, idle, &no_new_privs2)); =20 - ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)); + if (variant->prior_no_new_privs) { + ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)); + } else { + /* No prior prctl(2) PR_SET_NO_NEW_PRIVS call. */ + ASSERT_EQ(0, prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0)); + } =20 - EXPECT_EQ(0, landlock_restrict_self(ruleset_fd, - LANDLOCK_RESTRICT_SELF_TSYNC)); + if (variant->expected_errno) { + EXPECT_EQ(-1, landlock_restrict_self(self->ruleset_fd, + variant->restrict_flags)); + EXPECT_EQ(variant->expected_errno, errno); + } else { + EXPECT_EQ(0, landlock_restrict_self(self->ruleset_fd, + variant->restrict_flags)); + } + + /* Checks the no_new_privs state of the calling thread. */ + EXPECT_EQ(variant->expected_no_new_privs, + prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0)); =20 ASSERT_EQ(0, pthread_cancel(t1)); ASSERT_EQ(0, pthread_cancel(t2)); ASSERT_EQ(0, pthread_join(t1, NULL)); ASSERT_EQ(0, pthread_join(t2, NULL)); =20 - /* The no_new_privs flag was implicitly enabled on all threads. */ - EXPECT_TRUE(no_new_privs1); - EXPECT_TRUE(no_new_privs2); - - EXPECT_EQ(0, close(ruleset_fd)); + /* Checks the no_new_privs state of the sibling threads. */ + EXPECT_EQ(variant->expected_no_new_privs, no_new_privs1); + EXPECT_EQ(variant->expected_no_new_privs, no_new_privs2); } =20 TEST(multi_threaded_success_despite_diverging_domains) --=20 2.55.0 From nobody Tue Sep 29 09:46:20 2026 Received: from mail-yw1-f173.google.com (mail-yw1-f173.google.com [209.85.128.173]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 33914282F14 for ; Sun, 9 Aug 2026 15:45:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.173 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786290357; cv=none; b=FIs+z1lhJL5UYQvp1DSWktnWZZhIWaumCMQP/l4O9kogc0F4EAfBMqGZgmYR5eebLkiXuHt7QOHvMIz9jX6Kiup9bWgNLsBdcK6PcOwF4qpE3tEW8v7Ox1AtkAJPDQUEMcFmJk3rju9D++qeVpsvgd5k2OPoc39Ezw1nLem8EJo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786290357; c=relaxed/simple; bh=9JZUzyBo+CbXJSkhEUaPm8GPC8AE4DGGZu0FmSVJVn8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=P0R2CorQlB8QnpN489OGNkrXn8VrIDwFZLutHDB0KZYau5vnLD6/zrYPu2irCjUwB4go9mZQ0CNn2b0PFgBj/MWRCID5TCjhnleumEk2l54yU7xOBC1A0CwZMiKAacfUUt5fxPQkOpBCxZAHIIdxZKsGUcKGIaUe01IdSkyC5Ms= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=phUZY5uZ; arc=none smtp.client-ip=209.85.128.173 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="phUZY5uZ" Received: by mail-yw1-f173.google.com with SMTP id 00721157ae682-81ecf499af9so14483597b3.1 for ; Sun, 09 Aug 2026 08:45:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786290355; x=1786895155; darn=vger.kernel.org; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to:content-type; bh=Jg/kaf72XcXDaCB/gqQtAj1XATKp4pN9Sx21Fhzi3WM=; b=phUZY5uZta1tNJeezc/h8wAzpRncS5D3HVIpKeXo/aXlNd/dZlzzYh4G+DkIusaUST LmSvj5dm2mmHlZPIzvhfB6u33GcN5ncjQEY0AzyO3cMTZm1wGn/uxjeAZ77XwXv91h9h BFlPwsK8INroswa96TXrf8FaPRB1Bnx4S6j7tlp6KVPEqGAbpFUD/tytdDvUmSin3gvI rQzVsaL80TXRQS+utU3RJ/r3dQoZcP18IgI1yWkGZ7hw4XZQGP1xdzFgfgxsgfCaxxVD DDfioPy1TxzSGhv309ouBoWSXa/N2yxcb6HwBIJiv6eTnhUHq9s+XL99pzBkpAcxxgVb kJYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786290355; x=1786895155; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=Jg/kaf72XcXDaCB/gqQtAj1XATKp4pN9Sx21Fhzi3WM=; b=OXz/hq7NHgUJjtC5bIF0tESSKB4ZT07wN15gJstg9fYNZV/S1/92E4ZXHPylZJGAQm TxyUuRNDnQaf409HSXhWXtK5KwaC6kBFIGHTEVny+BYH3WsnrAgAo4apuHWHS9YLFA9K M585KsQfQ1ULDIwmq71fykhDPJkHAQm0u4O33zJuRYA5pP8Db9uoot5PyhoN5oSiUmUM WLvV+tPX48imlFHtNSe08DDslR3J3FYqiMcP0iTAEyIsLwhQ/6OACaKoXM/zzjaue9ui 6lj7QNHJxhcWix33Ow6emtchXOpZu8CuAAVo6Kjw6aaNOiJPzphzaKNlTta8bFXWk9J5 8vBA== X-Gm-Message-State: AOJu0YyK6pr4pQdLKLaB20r3NrHy9NNbgS60JLHfoQeOEOAhLsv0HRWH KLXUGCHWXVRMKqk9OUiAgiiwmWA9656veU/5tdkQ1/sKI4FrqWCem6y1 X-Gm-Gg: AR+sD12kZ2NxiVd6x5dOduvbDRP40CIBSEPuXP8EICVSmcf3NpVg35GNP5PDeuPdGKT L4MAMtGKmdL9dr2P9ESmQZC3MFO2kQup+Bp0QoC9sR1g4iIikfG1tKbzRjZGO9Fjrx04ml6/kYP vLCiV3DdQo5ogws2gIHiPyrj5cu+JY6ljKI4Pw5YhW2iSyzLbpxfdNALuk7O6ikqyjYy7D9Vy0q tooYqxPiQaEozsiBykE1w4ZCmWm6Luqyjz+qQkz0DbOkz4KuP0jADZls0bsMOSMjggOKdFdiUCk ZOKU0wfUph3qY2ZFVc9nm/gTdeIzpy9ts+AzxwZM/OfjR7X4X72p2wAoaHtTF/dBAovCRy9QUmZ qFnu1GG2fQ0xfN9nOj7Ofs43GMUKbtuBNat86fRXw8eQ2QxmZk1UwI+BmKn+ZIV8H2PCpNi4Yl6 l/4S6oFmEYsmgJtSUYUR1vKG3fZDQc7+W8mHcG3ncKqhrIsaWFZF+RdDBQ7yROCWt2y+Z7/6b1u U22uB5ATVs7YT0LKYorDCw= X-Received: by 2002:a05:690e:4396:b0:667:b164:3e04 with SMTP id 956f58d0204a3-6699a90f267mr17116820d50.22.1786290355019; Sun, 09 Aug 2026 08:45:55 -0700 (PDT) Received: from zenbox ([2600:1700:18fb:6011:4665:53b0:3ac9:3545]) by smtp.gmail.com with ESMTPSA id 956f58d0204a3-66acacdbea9sm4838001d50.3.2026.08.09.08.45.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Aug 2026 08:45:54 -0700 (PDT) From: Justin Suess To: gnoack3000@gmail.com, mic@digikod.net Cc: linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org, Justin Suess Subject: [PATCH v4 4/5] landlock: Document LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS Date: Sun, 9 Aug 2026 11:45:22 -0400 Message-ID: <20260809154544.1253100-5-utilityemal77@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260809154544.1253100-1-utilityemal77@gmail.com> References: <20260809154544.1253100-1-utilityemal77@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Document setting no_new_privs with ruleset enforcement, following the same compatibility section style as previous ABI additions. Include a section explaining the tradeoffs of setting no_new_privs through any means for privileged users of Landlock. Signed-off-by: Justin Suess --- Notes: v3->v4: - Reword the tutorial paragraph on CAP_SYS_ADMIN and no_new_privs to remove the ambiguous "it"s, per Micka=C3=ABl's feedback. - Use the suggested "call (or ``CAP_SYS_ADMIN`` use)" wording in the compatibility section. Documentation/userspace-api/landlock.rst | 47 +++++++++++++++++++++--- 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/Documentation/userspace-api/landlock.rst b/Documentation/users= pace-api/landlock.rst index 5085822d8930..782e65020b77 100644 --- a/Documentation/userspace-api/landlock.rst +++ b/Documentation/userspace-api/landlock.rst @@ -8,7 +8,7 @@ Landlock: unprivileged access control =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D =20 :Author: Micka=C3=ABl Sala=C3=BCn -:Date: July 2026 +:Date: August 2026 =20 The goal of Landlock is to enable restriction of ambient rights (e.g. glob= al filesystem or network access) for a set of processes. Because Landlock @@ -250,7 +250,8 @@ similar backwards compatibility check is needed for the= restrict flags =20 __u32 restrict_flags =3D LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON | - LANDLOCK_RESTRICT_SELF_TSYNC; + LANDLOCK_RESTRICT_SELF_TSYNC | + LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS; switch (abi) { case 1 ... 6: /* Removes logging flags for ABI < 7 */ @@ -269,16 +270,37 @@ similar backwards compatibility check is needed for t= he restrict flags * children (and not for all threads, including parents and siblin= gs). */ restrict_flags &=3D ~LANDLOCK_RESTRICT_SELF_TSYNC; + __attribute__((fallthrough)); + case 8 ... 10: + /* Removes no new privs flag for ABI < 11 */ + restrict_flags &=3D ~LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS; } =20 The next step is to restrict the current thread from gaining more privileg= es -(e.g. through a SUID binary). We now have a ruleset with the first rule -allowing read and execute access to ``/usr`` while denying all other handl= ed -accesses for the filesystem, and two more rules allowing DNS queries. +(e.g. through a SUID binary). For unprivileged processes, setting the +no_new_privs attribute is required by Landlock. + +Processes with ``CAP_SYS_ADMIN`` in their namespace can enforce a ruleset +without setting no_new_privs, but leaving no_new_privs unset is risky even +when Landlock does not require this attribute: sandboxed processes could +still execute set-user-ID, set-group-ID or file-capability binaries, which +would then run with elevated privileges while being restricted by a Landlo= ck +domain they may not expect, making them potential confused deputies. +no_new_privs should only be left unset if such a privilege transition is +expected. + +We now have a ruleset with the first rule allowing read and execute access= to +``/usr`` while denying all other handled accesses for the filesystem, and = two +more rules allowing DNS queries. =20 .. code-block:: c =20 - if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { + /* + * If the ABI > 10, we can tie setting no_new_privs with successful ru= leset + * enforcement and skip the manual prctl(PR_SET_NO_NEW_PRIVS, ...) cal= l. + */ + if (!(restrict_flags & LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS) && + prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { perror("Failed to restrict privileges"); close(ruleset_fd); return 1; @@ -792,6 +814,19 @@ when at least one sys_landlock_add_rule() call is made= for it with the ``LANDLOCK_ADD_RULE_QUIET`` flag, additional add-rule calls for the same object without this flag do not clear it. =20 +no_new_privs flag (ABI < 11) +---------------------------- + +Starting with the Landlock ABI version 11, sys_landlock_restrict_self() +accepts the ``LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS`` flag, which sets the +no_new_privs attribute of the calling thread only once the enforcement of +the ruleset succeeded: no_new_privs is set if and only if the call +succeeds. This removes the need for a prior :manpage:`prctl(2)` +``PR_SET_NO_NEW_PRIVS`` call (or ``CAP_SYS_ADMIN`` use). When combined +with ``LANDLOCK_RESTRICT_SELF_TSYNC``, no_new_privs is set on all threads +of the process. As explained in the tutorial above, leaving no_new_privs +unset is risky even when Landlock does not require it. + .. _kernel_support: =20 Kernel support --=20 2.55.0 From nobody Tue Sep 29 09:46:20 2026 Received: from mail-yx1-f49.google.com (mail-yx1-f49.google.com [74.125.224.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C3D6D23EA8B for ; Sun, 9 Aug 2026 15:45:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.224.49 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786290360; cv=none; b=QLZNVHWYgmvoUYQlla6yphJOKJyzCFdz4C+oJU922DYgnGoIYfrRneoxunD57bd8D992LDiEzXBgBL8jAHw6dqMxQNEiLhAmrcsC1GI3nDSqFBEDSIZKLngPlo6QsvXPkxZHai0n3eJ6mgGM2BQMuhpwcEj0HlZRsddXPrEwj3Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786290360; c=relaxed/simple; bh=9YgdDQB594YhY04UhKjFUKPBBqlh+WnhU+EuLELG1mM=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=V2DoR73mZH8MeW4HR9YXZqAfbnrfra06q8y0QBUbjhRDORIxgUl1FKYkasKgt3U5lD3bWj5YVMQ0wD4MvC4YAuq4Ou0duRQAiPouATyctW6AnnPwuBreX3PATgoSo2adM1Ls5MyM+cnNIwAS3v6GZ3QwTr3mwD1jVswlgfCClV0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=gORyc2qm; arc=none smtp.client-ip=74.125.224.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="gORyc2qm" Received: by mail-yx1-f49.google.com with SMTP id 956f58d0204a3-6679d88abdcso1424571d50.2 for ; Sun, 09 Aug 2026 08:45:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786290358; x=1786895158; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=KdWOIkrtO8O1vO8qraAFeciOWzTCObEsIaLYBRcPpHo=; b=gORyc2qmbXP0g1bSUjkEZFuu/Rp1MT14CSODKxzkB/2TRymuUkMr2dq+aHOJq4c2mI QRuOZIxuoC4HaNtbFVDYT199l74E0sDq70r7+gf/4MDeAadp7Ao58JXG7ZIMwLiacb+4 F39sn2ZbuZACP/d3Ms0RD9Erv/rRiTfm9tSQNVRP4Db+5CLkmdjW3OxeVEAQMKiv2Q2L Z2hXeptSTwB4FDcsv1ZhffDJBR4YrfS8ybpFT+Tm4VuMcmv9tSsCM191934wBqbVurKW AQqP6lov9I/j+ql0GY89CzaAG2oVEw3/401lRkyEpiBJ/GeOU9IZIv9ZwQebmpnX7m8O ZPlA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786290358; x=1786895158; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=KdWOIkrtO8O1vO8qraAFeciOWzTCObEsIaLYBRcPpHo=; b=DO0nPsXFqUSbg8h1JlmHKlfttk0PLH1e8J3UZI+2YfZnKdKPgL2+xZXVW1wLDuuy/q XNJRDIOPqdup9R9voGxMwyBUH7SOHdgXnngIpXvriQ8ne4ko5m8qUs+Rgbcicc9vDkl9 C6KGx/3NqvGl/JnsZYdg8jbyP2o8Qhjx1u1Zst5VYrUgRaGJEFVUHENPKPT1c7MsJAKq mgKe2SzLn3xoNN5LUVhId4we3kN/8U12R8I5OL9TbuHmvGnhVYqnvCZ2nkD5Ttoe3QWt RKsQlgkU4sRLy35NnxwetMQe7CidS3SEPRnirjC/Qp9FUDyjTH/TbovLlFy6bPdszezm OgMQ== X-Gm-Message-State: AOJu0Yy/TCCz8NfuYmCLgsq62oHhhFURAxD2A8N8itapgJsViljHIwx8 dpXdLYNp64A4Hzbise9fC5bUoqWy5OzurGmqwcMXGvD8uUj1RgBkEz+NyDVa0rpJ X-Gm-Gg: AR+sD10jkNUpPcKvLHMh0mj63xBy4QACn60H8l/DKqyCojKDrwUyLFr7mGytX3vUGlz 02WjYPc6xnD845px7kvtAfQwCzC5DC3/mU9QIieOsxFY8nQGEhSBGgoe2lEfjLD7R5cwfj03vKa qukGiaV5SXqU/lc1PReKcy6ud3n/3XYyzsq8TtEOGqTnDAd0cZsYuBc751qqi+A46TZi7nEk2Ag LQRpdXLwuSvv/ZV9EUcUEjXrhuuD0GNR1VJMS2fVxhh0iLUHvaazDb2uQRPfaDfjv3PhpVW0GqB zqSs9umDF9Shdy1KfrUzC4y9p8C1TJ83qKm7eyYW7uX29ysanmSyzjNX512SBLqvqb7ObBlTqwh mzG+FpFRacUmlZdM+REozS3Ajelq4BUKeSXBJY7i2hHeD1Pvqpd/ip4QFUHEY8+iDmhmplNxyMe deqiKHzeq6ti22R9zzv8EQmrsj47/HtVnP9/JOGlUTHYrTBpcLpcRG8deyxWalSHyibzAuR97VB dETrmi+f1YVgto+lA32UjYIPdcTr7sWKw== X-Received: by 2002:a05:690e:1552:10b0:666:541f:6355 with SMTP id 956f58d0204a3-66ad72fa49amr6636286d50.35.1786290357741; Sun, 09 Aug 2026 08:45:57 -0700 (PDT) Received: from zenbox ([2600:1700:18fb:6011:4665:53b0:3ac9:3545]) by smtp.gmail.com with ESMTPSA id 956f58d0204a3-66acacdbea9sm4838001d50.3.2026.08.09.08.45.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Aug 2026 08:45:57 -0700 (PDT) From: Justin Suess To: gnoack3000@gmail.com, mic@digikod.net Cc: linux-kernel@vger.kernel.org, linux-security-module@vger.kernel.org, Justin Suess Subject: [PATCH v4 5/5] samples/landlock: Add LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS to sampler Date: Sun, 9 Aug 2026 11:45:23 -0400 Message-ID: <20260809154544.1253100-6-utilityemal77@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260809154544.1253100-1-utilityemal77@gmail.com> References: <20260809154544.1253100-1-utilityemal77@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS to the default flag setting. Gate the flag on the ABI version, but do not expose any userspace control over this flag as it has no practical effect on the resulting sandbox. Signed-off-by: Justin Suess --- Notes: v3->v4: - No change. samples/landlock/sandboxer.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/samples/landlock/sandboxer.c b/samples/landlock/sandboxer.c index ac71019e6212..030583273f3f 100644 --- a/samples/landlock/sandboxer.c +++ b/samples/landlock/sandboxer.c @@ -369,7 +369,7 @@ static int add_quiet_access(const char *const env_var, return 0; } =20 -#define LANDLOCK_ABI_LAST 10 +#define LANDLOCK_ABI_LAST 11 =20 #define XSTR(s) #s #define STR(s) XSTR(s) @@ -453,8 +453,9 @@ int main(const int argc, char *const argv[], char *cons= t *const envp) .quiet_scoped =3D 0, }; bool quiet_supported =3D true; - int supported_restrict_flags =3D LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON; - int set_restrict_flags =3D 0; + int supported_restrict_flags =3D LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON | + LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS; + int set_restrict_flags =3D LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS; =20 if (argc < 2) { fprintf(stderr, help, argv[0]); @@ -545,6 +546,12 @@ int main(const int argc, char *const argv[], char *con= st *const envp) LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP); /* Removes quiet flags for ABI < 10 later on. */ quiet_supported =3D false; + __attribute__((fallthrough)); + case 10: + /* Removes LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS for ABI < 11 */ + supported_restrict_flags &=3D + ~LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS; + set_restrict_flags &=3D ~LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS; =20 /* Must be printed for any ABI < LANDLOCK_ABI_LAST. */ fprintf(stderr, @@ -673,7 +680,8 @@ int main(const int argc, char *const argv[], char *cons= t *const envp) } } =20 - if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { + if (!(set_restrict_flags & LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS) && + prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { perror("Failed to restrict privileges"); goto err_close_ruleset; } --=20 2.55.0