From nobody Sat Sep 5 05:48:52 2026 Received: from mail-wm1-f53.google.com (mail-wm1-f53.google.com [209.85.128.53]) (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 57A3B29E10B for ; Sun, 30 Aug 2026 20:17:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788121025; cv=none; b=sjP+XNeznbi8mAsd2vNuHUgv6Kik7f+LHIQ7sX0bZp8zPShQJqSd6Yk2WDhIGfNyTy+yCHpPkKisr2CEJYtSnUlu/TYWn/qoK3VSjtwLnndN7buf6w9zRYI3jyoj9Zf5Mmwqa1qFgNVRIZT+T5xTiT15Qdq+VmuhjtKS41czV4s= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788121025; c=relaxed/simple; bh=e1JVroCpy0yxR3TLrzWrxJUaIa9LSvQI5OwiRs8w1Q8=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=YtZhIy4VMyCzRXLC9PKHSxy1g1cIrik7Pc+Mnhz+P/64aKQAypK5/LON/m8AcIDuk09fsRfHl5g79JDnmdZ4EWunuegDAre90M79qfP7YW4DHNARsW9vwE9tqz742Qw0PPKwgPdG00yXn5Dohe9perg47VnKgMRW9HIV/1ivW38= 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=rq/BSMLy; arc=none smtp.client-ip=209.85.128.53 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="rq/BSMLy" Received: by mail-wm1-f53.google.com with SMTP id 5b1f17b1804b1-49b8be0409fso16089595e9.2 for ; Sun, 30 Aug 2026 13:17:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788121022; x=1788725822; darn=lists.linux.dev; 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=xRwk2mxThRhdae+9PHJjX8tprSZn9ioaIXoGdJjtfRc=; b=rq/BSMLyuWa3JPRmhz2nOTPqqKFWTPOfOiluilFVEqYlih/aNQ1vkfeO5iFtr+Ff2d wRt+yUQRwdIKJDndmwYBgRvdxPisJRFnXNAlkbUu5dZ0NMNyQcvOxD5U1GyHze9fYysD IDihErJYrtl3ybWWTvVsSUGh+y7NMI9eRPpNQp2rXRn3YvuqxwBnY8DHgom8SNWn8qHu +4o8THYNN5CR0N+onWVrRk3p5V7vxej7ZDQRjL1V7NSLZ0Ip9bJpuYfr5ytseRcEKJcL rLn763pbMo3HS8tf36sPpzFV7STSn0Gm+JfdDT/pNH8Xn0KzRkqKKey0/yngPlzG201A uhoA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788121022; x=1788725822; 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=xRwk2mxThRhdae+9PHJjX8tprSZn9ioaIXoGdJjtfRc=; b=eRZhdm25Vb/0STQ4GuIr7PP+fGXCpQbiGoyAzYVuwNJ6jlsDTI7+JIoZvOihjxlAbg qNLglo6MO4y2Vyr/OcNS7RhJvqexU7/twkGr0dC3quVqtoBOM6yAIx6mAgoN68ujR4x0 ohmIfvWKbsxj3HlaQG08iUuAvKMtpRAKLMKoTsUu3E41/4n6B99rZi3L0nAHGIMeD2ID 1xgzfRynkNEfD/N98PqCF6BdQtDWazx0E/2L04Qgf1h7ZDLgDyROMz1Nm22/TZPyPd2u ww+j7oU/rTkO5/CvNaS5O9yBuelH9n88EMT7DfzA3QSAnf4evxMdZvcQfK3Bp3N2rTd/ L9KA== X-Forwarded-Encrypted: i=1; AHgh+RrXzcADpi+j0/dfxGu+ILOrdnfcg3WmAY0UoyMiVYIq9e5JZ18kL2DYc8E45AdLDoWe9d0lbA==@lists.linux.dev X-Gm-Message-State: AFuF++n5TKyyhzOt9ky10kuu6JBGTOSqFny26PnwZt1b2+/gkNtk/vNx +Xkj6udFPXaKDQIt8M92+f//ygyJmjPgVJzfExD+LOd1Cgv/jEsrJUNgP27iSELj X-Gm-Gg: AR+sD11jzOhgSrcj8vfy586+W7D+BnzHgX1ovfdEFx+QkuOzbkDOnj7pMzRrw0uj87o MF+IS8wSAPVm94Oi8+Y2EpU8jvbyi+JEdDhOabxYouWxLPX7S0EqlUdWD9kDA+MTAkpDfkTseZl 8HaSsYnfyVtbnUL2E6/xMS2oF5IT7gzexHSvcyswnafqIxA/UIoAGB3p6D+9B/QFoJ8BhMbV6cq aMdRTn4JAZduf/oZ4+3zlmt2BU05pw2Pr0OmunUK/CtEpTjK6qF+cPKBjuP4XL0qsYzE/mpNIVB rJw1+TsShGLnl9E47UIJenNWwr9GbKWtfd4VP2pGRxryuHORGMyxwaxd+8VoL5uhMBgLNXgwoxv 2tfgO911ja51nnuldFKYprjsorlvwo3RC6eXGN7gAVv8pqB7GM+Vhp0yxggaVnkMaq96Ey80CQ7 bdlxdmzd2/j9EPH67FpRB1EW0/bbTAWHQGVEC53Fae0BIE/28n4HuVSBqsUlnFXZu4EBAtJHeJh 3Uk1YnVyjWAkA== X-Received: by 2002:a05:600c:6215:b0:499:5a50:b022 with SMTP id 5b1f17b1804b1-49b91c1bb18mr334176195e9.3.1788121022190; Sun, 30 Aug 2026 13:17:02 -0700 (PDT) Received: from localhost (ip87-106-108-193.pbiaas.com. [87.106.108.193]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49b91c5790csm193360025e9.0.2026.08.30.13.17.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 30 Aug 2026 13:17:01 -0700 (PDT) From: =?UTF-8?q?G=C3=BCnther=20Noack?= To: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= Cc: Matthieu Baerts , Mat Martineau , Geliang Tang , Mikhail Ivanov , mptcp@lists.linux.dev, netdev@vger.kernel.org, linux-security-module@vger.kernel.org, =?UTF-8?q?G=C3=BCnther=20Noack?= Subject: [PATCH 1/6] samples/landlock: Implement best-effort fallback for network rules. Date: Sun, 30 Aug 2026 22:16:45 +0200 Message-ID: <20260830201650.67050-2-gnoack3000@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260830201650.67050-1-gnoack3000@gmail.com> References: <20260830201650.67050-1-gnoack3000@gmail.com> Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable The sandboxer sample tool added network rules unconditionally, even on systems that only support lower Landlock ABI versions, resulting in errors. This change implements the correct best-effort fallback: As on older Landlock ABI versions, the given operation is not restrictable, is also does not need to be allow-listed. Signed-off-by: G=C3=BCnther Noack --- samples/landlock/sandboxer.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/samples/landlock/sandboxer.c b/samples/landlock/sandboxer.c index 030583273f3f..1c514efecafb 100644 --- a/samples/landlock/sandboxer.c +++ b/samples/landlock/sandboxer.c @@ -198,6 +198,10 @@ static int populate_ruleset_net(const char *const env_= var, const int ruleset_fd, .allowed_access =3D allowed_access, }; =20 + /* A rule without access rights and flags is a no-op. */ + if (!allowed_access && !flags) + return 0; + env_port_name =3D getenv(env_var); if (!env_port_name) return 0; @@ -657,19 +661,27 @@ int main(const int argc, char *const argv[], char *co= nst *const envp) } =20 if (populate_ruleset_net(ENV_TCP_BIND_NAME, ruleset_fd, - LANDLOCK_ACCESS_NET_BIND_TCP, 0)) { + ruleset_attr.handled_access_net & + LANDLOCK_ACCESS_NET_BIND_TCP, + 0)) { goto err_close_ruleset; } if (populate_ruleset_net(ENV_TCP_CONNECT_NAME, ruleset_fd, - LANDLOCK_ACCESS_NET_CONNECT_TCP, 0)) { + ruleset_attr.handled_access_net & + LANDLOCK_ACCESS_NET_CONNECT_TCP, + 0)) { goto err_close_ruleset; } if (populate_ruleset_net(ENV_UDP_BIND_NAME, ruleset_fd, - LANDLOCK_ACCESS_NET_BIND_UDP, 0)) { + ruleset_attr.handled_access_net & + LANDLOCK_ACCESS_NET_BIND_UDP, + 0)) { goto err_close_ruleset; } if (populate_ruleset_net(ENV_UDP_CONNECT_SEND_NAME, ruleset_fd, - LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP, 0)) { + ruleset_attr.handled_access_net & + LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP, + 0)) { goto err_close_ruleset; } =20 --=20 2.55.0 From nobody Sat Sep 5 05:48:52 2026 Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com [209.85.128.54]) (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 0313A30568F for ; Sun, 30 Aug 2026 20:17:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788121027; cv=none; b=glaiGreYybrRBRZPZv1Y8FKMBcYKrKY9DA573S2P/aeH820c4w8yCZwaM4VG8TgnVpw+dK1kH6RAQTYKQ35n3b88MTS5kK1sjfP2CVnn4CONwt5JCzvnbAyFg171PFzIVBlXI5ILCK+MbECzkF9baEbttN74pSs5f2vogASVgvc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788121027; c=relaxed/simple; bh=7wEDaDm21llur5hKylLQvWMRMvBg/bAaty0AoAvvgrI=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=cX7SMrCMDEOAxg/00vnTqJBKhUANaKVE+nDAe7EcHPbm9ajFX95pJgZnV5zcrgBR1u08YfNpSzsh5odOq9s+pX5nmMnUyVuaLPUExAlk3pH4tmINZuo+H9M5x/Mw4timfIv5lp6BkIWyfwwmk6lwI0q3NXKSY19A57sPPiUlgqw= 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=cg9Tye1Y; arc=none smtp.client-ip=209.85.128.54 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="cg9Tye1Y" Received: by mail-wm1-f54.google.com with SMTP id 5b1f17b1804b1-49cd77e0f95so2576305e9.3 for ; Sun, 30 Aug 2026 13:17:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788121024; x=1788725824; darn=lists.linux.dev; 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=7Pdseog3hjBqegC/S81uic44NEP627xpHcoKP1WPxsA=; b=cg9Tye1YFjIY+KTzmOesfxymnFdXCeOursxnn/el2VJhJ8DTWzg00/5Oln4ceOV3SQ YxilK4w0zJw6Wjz7/kf6fRXV1/CnvhYoqx283mVbubBdgg5J1dLFADjylMI0rK+LFSXu KNYC5KhJszH/eaK/PfDhhYSxD6fV0fNUtznaXIA6NQ/DNxXMAFW3wdBv308hP9WE+uN9 CGUEATbVR77rJCRT8+bbuyghzYnajZj+s451V3qNaWKlGTJff3rUKt86OCcG7SS704ys w2fvM5PSkZQUzD2gdLnnU5hOPuzb7i+l66mGVPc7y7YwkbHDip10haYP3gKfmakpy/16 NSvw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788121024; x=1788725824; 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=7Pdseog3hjBqegC/S81uic44NEP627xpHcoKP1WPxsA=; b=XHdRoLVV93MZYrRnlEanUD01bQedds30cbl/rwFhxuylc61wXF9X707PRjeinm9xCW sMtsf5mkn6VZJxEWfCBcU376esGHv1ji3lE6G1pKy2qpZMl8nsq2l2X4XYvvkJ9Hb1f6 CXEKfV42JVvIJFBQLCvustdpL4uW3bynyqQP7VU9JUuqwlN6ahAL9HI8AUK3YfEz0G42 t+3GmDOLoTQhPf92qYcBjtnezM8JI8T7GOyBOZ1DEX3nEohQ56v7ZyixyGKqixu+EhTu fCU+9kqjn8qLYQmWKTQp+NGjmuBykFYj1A47bVFMJbcYo137xyTLbMDr//eZW7znGhQN 67/A== X-Forwarded-Encrypted: i=1; AHgh+Rp8DhNYqMTY7Opm63EtDc6KGPEGqfd501KxEue3skEJ6gltr360e28zb5i5Q2xNmKM8VTUpcA==@lists.linux.dev X-Gm-Message-State: AFuF++lFPuNeg7tciKj6cLiGVT5YBkqBJmoEYxuby8v83/WVkX6NJgPr nMLd+CwX5/cRi7yt8zAB1oqjSkMbgPKW9WfYVZYYxKQSp5pGBQ+iaPeQ X-Gm-Gg: AR+sD10SfR6Qaus7ISmWk0hQi5CEPcy/73aNbbpPWT5/pUBB/TU5iWE0M6HGe9yM/NL YDPkee6hskAig4OMLeqHaPRd4zvNggBYjt3FR66w+aenQkMFwnuPLck0NqHti1+8rad5bml5F5G 8UIh3s1Wpw5mgrxLSucKnWv+sHGwHl/EsO50BitenPthRTUvh1xJQujdt6YUif3sMYclOl+cVrc OBKYU9Wovj2zTDyEpMJPkgNkP7iIeOsHecZo0iBNzlSt0QjZ3Kd5X4fdokG01QCflSiL8uMp3NW HlSjePmClR8tKaFhHXPgpKsnlT1p6JJQfTejH1vb0j+ZP8LxfsIJt3gwef+Sb18vyANOnrpBFRs w4ZEPD4P91C2t6HuFqxC7GV/ft/izLGXU6sN6AUhlSua64fs8NoyERi+u0JV5CbPK+TjcjbFys9 x3v9M1l4b5gZB1wyLpjB8DPeNefmlgkV7T90f/eX2z/6bdN0jXuDRnrh6Wbh8jnGlbCRtN78KPh bdg7jreDGJWg4J+2By+68VN X-Received: by 2002:a05:600c:a106:b0:49c:cb6a:1687 with SMTP id 5b1f17b1804b1-49ccb6a1689mr169989075e9.4.1788121024059; Sun, 30 Aug 2026 13:17:04 -0700 (PDT) Received: from localhost (ip87-106-108-193.pbiaas.com. [87.106.108.193]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49b94dcaf61sm214133605e9.4.2026.08.30.13.17.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 30 Aug 2026 13:17:03 -0700 (PDT) From: =?UTF-8?q?G=C3=BCnther=20Noack?= To: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= Cc: Matthieu Baerts , Mat Martineau , Geliang Tang , Mikhail Ivanov , mptcp@lists.linux.dev, netdev@vger.kernel.org, linux-security-module@vger.kernel.org, =?UTF-8?q?G=C3=BCnther=20Noack?= Subject: [PATCH 2/6] selftests/landlock: Generalize net test helpers for multiple socket types Date: Sun, 30 Aug 2026 22:16:46 +0200 Message-ID: <20260830201650.67050-3-gnoack3000@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260830201650.67050-1-gnoack3000@gmail.com> References: <20260830201650.67050-1-gnoack3000@gmail.com> Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Create helper methods for determining the access rights to be tested based on socket type (TCP or UDP). This makes it simpler to add more socket types with similar bind(2) and connect(2) restrictions in the future. Signed-off-by: G=C3=BCnther Noack --- tools/testing/selftests/landlock/net_test.c | 85 +++++++++++---------- 1 file changed, 46 insertions(+), 39 deletions(-) diff --git a/tools/testing/selftests/landlock/net_test.c b/tools/testing/se= lftests/landlock/net_test.c index a18761e0fd82..3a0482beca5f 100644 --- a/tools/testing/selftests/landlock/net_test.c +++ b/tools/testing/selftests/landlock/net_test.c @@ -108,11 +108,41 @@ static bool prot_is_udp(const struct protocol_variant= *const prot) static bool is_restricted(const struct protocol_variant *const prot, const enum sandbox_type sandbox) { - if (sandbox =3D=3D TCP_SANDBOX) + switch (sandbox) { + case TCP_SANDBOX: return prot_is_tcp(prot); - else if (sandbox =3D=3D UDP_SANDBOX) + case UDP_SANDBOX: return prot_is_udp(prot); - return false; + case NO_SANDBOX: + default: + return false; + } +} + +static __u64 sandbox_bind_access(const enum sandbox_type sandbox) +{ + switch (sandbox) { + case TCP_SANDBOX: + return LANDLOCK_ACCESS_NET_BIND_TCP; + case UDP_SANDBOX: + return LANDLOCK_ACCESS_NET_BIND_UDP; + case NO_SANDBOX: + default: + return 0; + } +} + +static __u64 sandbox_connect_access(const enum sandbox_type sandbox) +{ + switch (sandbox) { + case TCP_SANDBOX: + return LANDLOCK_ACCESS_NET_CONNECT_TCP; + case UDP_SANDBOX: + return LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP; + case NO_SANDBOX: + default: + return 0; + } } =20 static int socket_variant(const struct service_fixture *const srv) @@ -916,16 +946,10 @@ static void test_bind_and_connect(struct __test_metad= ata *const _metadata, =20 TEST_F(protocol, bind) { - if (variant->sandbox =3D=3D TCP_SANDBOX || - variant->sandbox =3D=3D UDP_SANDBOX) { - const __u64 bind_access =3D - (variant->sandbox =3D=3D TCP_SANDBOX ? - LANDLOCK_ACCESS_NET_BIND_TCP : - LANDLOCK_ACCESS_NET_BIND_UDP); + if (variant->sandbox !=3D NO_SANDBOX) { + const __u64 bind_access =3D sandbox_bind_access(variant->sandbox); const __u64 conn_access =3D - (variant->sandbox =3D=3D TCP_SANDBOX ? - LANDLOCK_ACCESS_NET_CONNECT_TCP : - LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP); + sandbox_connect_access(variant->sandbox); const struct landlock_ruleset_attr ruleset_attr =3D { .handled_access_net =3D bind_access | conn_access, }; @@ -987,16 +1011,10 @@ TEST_F(protocol, bind) =20 TEST_F(protocol, connect) { - if (variant->sandbox =3D=3D TCP_SANDBOX || - variant->sandbox =3D=3D UDP_SANDBOX) { - const __u64 bind_access =3D - (variant->sandbox =3D=3D TCP_SANDBOX ? - LANDLOCK_ACCESS_NET_BIND_TCP : - LANDLOCK_ACCESS_NET_BIND_UDP); + if (variant->sandbox !=3D NO_SANDBOX) { + const __u64 bind_access =3D sandbox_bind_access(variant->sandbox); const __u64 conn_access =3D - (variant->sandbox =3D=3D TCP_SANDBOX ? - LANDLOCK_ACCESS_NET_CONNECT_TCP : - LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP); + sandbox_connect_access(variant->sandbox); const struct landlock_ruleset_attr ruleset_attr =3D { .handled_access_net =3D bind_access | conn_access, }; @@ -1054,9 +1072,7 @@ TEST_F(protocol, connect) =20 TEST_F(protocol, bind_unspec) { - const __u64 bind_access =3D (variant->sandbox =3D=3D TCP_SANDBOX ? - LANDLOCK_ACCESS_NET_BIND_TCP : - LANDLOCK_ACCESS_NET_BIND_UDP); + const __u64 bind_access =3D sandbox_bind_access(variant->sandbox); const struct landlock_ruleset_attr ruleset_attr =3D { .handled_access_net =3D bind_access, }; @@ -1066,8 +1082,7 @@ TEST_F(protocol, bind_unspec) }; int bind_fd, ret; =20 - if (variant->sandbox =3D=3D TCP_SANDBOX || - variant->sandbox =3D=3D UDP_SANDBOX) { + if (variant->sandbox !=3D NO_SANDBOX) { const int ruleset_fd =3D landlock_create_ruleset( &ruleset_attr, sizeof(ruleset_attr), 0); ASSERT_LE(0, ruleset_fd); @@ -1103,8 +1118,7 @@ TEST_F(protocol, bind_unspec) } EXPECT_EQ(0, close(bind_fd)); =20 - if (variant->sandbox =3D=3D TCP_SANDBOX || - variant->sandbox =3D=3D UDP_SANDBOX) { + if (variant->sandbox !=3D NO_SANDBOX) { const int ruleset_fd =3D landlock_create_ruleset( &ruleset_attr, sizeof(ruleset_attr), 0); ASSERT_LE(0, ruleset_fd); @@ -1150,13 +1164,8 @@ TEST_F(protocol, bind_unspec) =20 TEST_F(protocol, connect_unspec) { - const __u64 connect_right =3D - (variant->sandbox =3D=3D TCP_SANDBOX ? - LANDLOCK_ACCESS_NET_CONNECT_TCP : - LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP); - const __u64 bind_right =3D (variant->sandbox =3D=3D TCP_SANDBOX ? - LANDLOCK_ACCESS_NET_BIND_TCP : - LANDLOCK_ACCESS_NET_BIND_UDP); + const __u64 connect_right =3D sandbox_connect_access(variant->sandbox); + const __u64 bind_right =3D sandbox_bind_access(variant->sandbox); const struct landlock_ruleset_attr ruleset_conn =3D { .handled_access_net =3D connect_right, }; @@ -1197,8 +1206,7 @@ TEST_F(protocol, connect_unspec) EXPECT_EQ(0, ret); } =20 - if (variant->sandbox =3D=3D TCP_SANDBOX || - variant->sandbox =3D=3D UDP_SANDBOX) { + if (variant->sandbox !=3D NO_SANDBOX) { const int ruleset_fd =3D landlock_create_ruleset( &ruleset_conn, sizeof(ruleset_conn), 0); ASSERT_LE(0, ruleset_fd); @@ -1229,8 +1237,7 @@ TEST_F(protocol, connect_unspec) EXPECT_EQ(0, ret); } =20 - if (variant->sandbox =3D=3D TCP_SANDBOX || - variant->sandbox =3D=3D UDP_SANDBOX) { + if (variant->sandbox !=3D NO_SANDBOX) { const int ruleset_fd =3D landlock_create_ruleset( &ruleset_conn_bind, sizeof(ruleset_conn_bind), 0); --=20 2.55.0 From nobody Sat Sep 5 05:48:52 2026 Received: from mail-wm1-f43.google.com (mail-wm1-f43.google.com [209.85.128.43]) (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 055B531A7E2 for ; Sun, 30 Aug 2026 20:17:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788121030; cv=none; b=cskCfoMchudtfD7Pb9CcKbrg3b1fxXuRsXuyR9BMZDpwSbNNSCCV5MJx3gmNfn0WgpAoviKEDsT3S4yiDCr4JzUpMV3P0cctZJDiqcznQ3mwq1ayw4xQYS7XTsQkl47eoxW152bbL06q7JgW/3rULSsIfnWrLlGQFRg3BDv/Umg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788121030; c=relaxed/simple; bh=3HlGz5FZAf5YiW0SZUDdJqY51I4PRzoZ+1IAMBTh0S0=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=RL/ppjsmZAX61dKgZXlhs9mKJkrKQomwwoAU/S6jdSeYyUlmAXP1rr9cdhgRDAMJprQENggWT47kQo+Y4QPHobo4pkOa2t6RY6NweR5VR723MucnTKXIj3znVbw8045Rve1cMTf5GSc13w7Sj3uXSHP1kGLGUc5kRlVb/2z1aak= 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=YB3+zMau; arc=none smtp.client-ip=209.85.128.43 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="YB3+zMau" Received: by mail-wm1-f43.google.com with SMTP id 5b1f17b1804b1-49b0dd3c9a0so20097495e9.1 for ; Sun, 30 Aug 2026 13:17:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788121026; x=1788725826; darn=lists.linux.dev; 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=PCMfevEQD6EgJt39HDJsajq+HZlaKHKHiTDnNP3c2jg=; b=YB3+zMau9bPSDRJRaJTC1Rv/RH6ujva8zDns2ae2x4HQRxrtKoUADPjEP7YBVjS9fR OSXOPOSgTxix5VeXVMniecAV3ZmVwmIctOQyvyGG4k9LUnp1Afmw8tiFJFZqmKD/QPyd 0OBGK/Ieeaqed0hKpgosMNPLaNfgDK2YN6SokM6B82DyF7+tr8AC4c1caBvDetj5anOL YPJu5r6xTL1rn/soHMOWhkMRiBTYKDmqZyBYAFU4LmGjn1d3g30SX1k5E6MBKTwzmNnm /oyiTim7kPY7y4iR0NJzb5pnZ3vEbRgCs1itdF4m3iaf5bP7QAH6HW7sdoBqhEex5sLZ v1WQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788121026; x=1788725826; 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=PCMfevEQD6EgJt39HDJsajq+HZlaKHKHiTDnNP3c2jg=; b=LlMetSkgKqtDkHdDydrg3CGKnf6RD1AhNA6dGxcqCuHZ/5Gltq9lOQd4p7dsB20q3c 90nwImDTbzvfQbbbHUJYH+YlDojin4hleQmDU06e7dtmZZiZydGEWam07I+ylt1EN8JS sXAwf1EzACgyWdKXQC6pxPUXe1mtoPRjtqDFmnBSP0pifcTPep8ZAinBm8Jmg5qQ72wr F6SZ9yoRks5kYLVigDg4zbub1DYtIyNz0MGZtUuql1qC/mbk/OSiLKN2Yj/4yj9sO2Y7 AyOzgOlZdL5iJIcHZ6q5XP5rKrQb57J7HDmuAlR3QGeAjn7Ad3GL9SeA5zvAfiIuXSul 7+Zw== X-Forwarded-Encrypted: i=1; AHgh+RqJA2tA6qbw7bzFtg7PBV4BGAbM33itHlTKTfLmH0WqYYcjgLQBHCC3E6IUt7+9zcBHhM+Nmw==@lists.linux.dev X-Gm-Message-State: AFuF++kxsKINNWF5zvXp/r2CdDaFSluvs6AbilbL7RoX1dXn7KBgdk+H YV4y0zpjYL5REudAyXT8ZD7Ga5y70VGek5EEtnVw6gGkCURbQ12oHRTn X-Gm-Gg: AR+sD12s7rrm9HZMTK7B4a5A7PnqdVKtSW8tUQJS6LJtqW7vABChDynxnGF439XOP0l QJ7PfFQke2MZmnXWG3/ujw5aa9ItmgrWRfyOv4KOtuIz+6JFdyaap1U+EjEB9OS3ARoBNJ45Qfd F2kK84tbgERh6d0VSThrHGUVpVoBna0srCDeKrAHuG/wq7AqEXUfsw0ITZQr3z6fcvVfA9hBoBM jDKuKBOKYdyAB2rWSr+bwhB44wujJfdKR5nR19TuaURqpUtIvUWsPXMPmv+X3EXoFJuSqdgbDZt 72bfADeJVSY3Q30l8B5+572VXxzUwZbjTkzr2BtUxT1KzKvbj9xws8OWEj8a207/rMakbKSyMkW IaBu9hLxsReZ3r7uK7EYA3iDdrV76weXVHZ9RNhbyCQ5gzc0K18Fs8MYWB940m3kf9AwgJIQLB6 88DdMs+cFCdS1ROoS6b/wXAhuQuqfKcJopGhMs6P8+fbbsvcrLjr3DrO+RvvGddSuu7zFISwH4/ yp9mdQfWhTNoA== X-Received: by 2002:a05:600c:1f8f:b0:499:b65d:1250 with SMTP id 5b1f17b1804b1-49b91c1fc4bmr290143725e9.2.1788121025986; Sun, 30 Aug 2026 13:17:05 -0700 (PDT) Received: from localhost (ip87-106-108-193.pbiaas.com. [87.106.108.193]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49cd2e9d9fcsm129432455e9.1.2026.08.30.13.17.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 30 Aug 2026 13:17:05 -0700 (PDT) From: =?UTF-8?q?G=C3=BCnther=20Noack?= To: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= Cc: Matthieu Baerts , Mat Martineau , Geliang Tang , Mikhail Ivanov , mptcp@lists.linux.dev, netdev@vger.kernel.org, linux-security-module@vger.kernel.org, =?UTF-8?q?G=C3=BCnther=20Noack?= Subject: [PATCH 3/6] landlock: Add MPTCP bind and connect access rights Date: Sun, 30 Aug 2026 22:16:47 +0200 Message-ID: <20260830201650.67050-4-gnoack3000@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260830201650.67050-1-gnoack3000@gmail.com> References: <20260830201650.67050-1-gnoack3000@gmail.com> Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable MPTCP sockets have equivalent bind(2) and connect(2) operations as TCP sockets, but can not currently be restricted with Landlock without explicit MPTCP access rights. As MPTCP operates on the same TCP port number space as TCP, this is a gap in Landlock's policies. Add access rights for MPTCP bind(2) and connect(2) operations and document them in the header. Treat TCP Fast Open the same as done for plain TCP in commit 33cb713db016 ("landlock: Fix TCP Fast Open connection bypass") The port numbers used in MPTCP subflows are negotiated by the kernel and therefore not subject to these access rights. Bump the Landlock ABI version to 12. Closes: https://github.com/landlock-lsm/linux/issues/54 Signed-off-by: G=C3=BCnther Noack --- include/linux/landlock.h | 5 +- include/uapi/linux/landlock.h | 24 +++++++ security/landlock/limits.h | 2 +- security/landlock/net.c | 68 ++++++++++++++------ security/landlock/syscalls.c | 2 +- tools/testing/selftests/landlock/base_test.c | 2 +- 6 files changed, 79 insertions(+), 24 deletions(-) diff --git a/include/linux/landlock.h b/include/linux/landlock.h index 004cbd0b9298..b04ffc7caa21 100644 --- a/include/linux/landlock.h +++ b/include/linux/landlock.h @@ -46,7 +46,10 @@ _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_NET_CONNECT_TCP, "connect_tcp"), \ _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_NET_BIND_UDP, "bind_udp"), \ _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP, \ - "connect_send_udp") + "connect_send_udp"), \ + _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_NET_BIND_MPTCP, "bind_mptcp"), \ + _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_NET_CONNECT_MPTCP, \ + "connect_mptcp") =20 #define _LANDLOCK_SCOPE_NAMES \ _LANDLOCK_NAME_ENTRY(LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET, \ diff --git a/include/uapi/linux/landlock.h b/include/uapi/linux/landlock.h index cceda3b3b961..2a953ba7ce25 100644 --- a/include/uapi/linux/landlock.h +++ b/include/uapi/linux/landlock.h @@ -448,6 +448,9 @@ struct landlock_net_port_attr { * - %LANDLOCK_ACCESS_NET_CONNECT_TCP: Connect TCP sockets to the given * remote port. Support added in Landlock ABI version 4. * + * .. note:: These rights do not apply to MPTCP sockets, which have their = own + * access rights (see below). + * * And similarly for UDP port numbers: * * - %LANDLOCK_ACCESS_NET_BIND_UDP: Bind UDP sockets to the given local @@ -474,12 +477,33 @@ struct landlock_net_port_attr { * .. note:: Sending datagrams to an ``AF_UNSPEC`` destination address * family is not supported for IPv6 UDP sockets: you will need to use a * ``NULL`` address instead. + * + * MPTCP sockets (created with ``IPPROTO_MPTCP``) use TCP port numbers, but + * they are controlled by their own access rights: + * + * - %LANDLOCK_ACCESS_NET_BIND_MPTCP: Bind MPTCP sockets to the given local + * port. Support added in Landlock ABI version 12. + * - %LANDLOCK_ACCESS_NET_CONNECT_MPTCP: Connect MPTCP sockets to the given + * remote port. Support added in Landlock ABI version 12. + * + * .. note:: The TCP and the MPTCP access rights are independent, even tho= ugh + * they refer to the same port number space. Handling only + * %LANDLOCK_ACCESS_NET_BIND_TCP and %LANDLOCK_ACCESS_NET_CONNECT_TCP le= aves + * MPTCP sockets unrestricted, and vice versa. A sandbox that wants to + * control all TCP-based traffic needs to handle both sets. + * + * .. note:: These MPTCP access rights restrict the ports passed to + * :manpage:`bind(2)` and :manpage:`connect(2)`. The ports used in MPTCP + * subflows are negotiated in the MPTCP protocol by the kernel and are n= ot + * subject to these restrictions. */ /* clang-format off */ #define LANDLOCK_ACCESS_NET_BIND_TCP (1ULL << 0) #define LANDLOCK_ACCESS_NET_CONNECT_TCP (1ULL << 1) #define LANDLOCK_ACCESS_NET_BIND_UDP (1ULL << 2) #define LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP (1ULL << 3) +#define LANDLOCK_ACCESS_NET_BIND_MPTCP (1ULL << 4) +#define LANDLOCK_ACCESS_NET_CONNECT_MPTCP (1ULL << 5) /* clang-format on */ =20 /** diff --git a/security/landlock/limits.h b/security/landlock/limits.h index 1a7c5fb8f6fd..d25e056b7ca2 100644 --- a/security/landlock/limits.h +++ b/security/landlock/limits.h @@ -23,7 +23,7 @@ #define LANDLOCK_MASK_ACCESS_FS ((LANDLOCK_LAST_ACCESS_FS << 1) - 1) #define LANDLOCK_NUM_ACCESS_FS __const_hweight64(LANDLOCK_MASK_ACCESS_FS) =20 -#define LANDLOCK_LAST_ACCESS_NET LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP +#define LANDLOCK_LAST_ACCESS_NET LANDLOCK_ACCESS_NET_CONNECT_MPTCP #define LANDLOCK_MASK_ACCESS_NET ((LANDLOCK_LAST_ACCESS_NET << 1) - 1) #define LANDLOCK_NUM_ACCESS_NET __const_hweight64(LANDLOCK_MASK_ACCESS_NE= T) =20 diff --git a/security/landlock/net.c b/security/landlock/net.c index 8f2aaac54b33..8541b0c07d64 100644 --- a/security/landlock/net.c +++ b/security/landlock/net.c @@ -11,6 +11,7 @@ #include #include #include +#include =20 #include "common.h" #include "cred.h" @@ -53,6 +54,26 @@ int landlock_append_net_rule(struct landlock_ruleset *co= nst ruleset, return err; } =20 +static bool sk_is_mptcp_socket(const struct sock *sk) +{ + return sk_is_inet(sk) && sk->sk_type =3D=3D SOCK_STREAM && + sk->sk_protocol =3D=3D IPPROTO_MPTCP; +} + +static bool is_connect_access(const access_mask_t access_request) +{ + return access_request =3D=3D LANDLOCK_ACCESS_NET_CONNECT_TCP || + access_request =3D=3D LANDLOCK_ACCESS_NET_CONNECT_MPTCP || + access_request =3D=3D LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP; +} + +static bool is_bind_access(const access_mask_t access_request) +{ + return access_request =3D=3D LANDLOCK_ACCESS_NET_BIND_TCP || + access_request =3D=3D LANDLOCK_ACCESS_NET_BIND_MPTCP || + access_request =3D=3D LANDLOCK_ACCESS_NET_BIND_UDP; +} + static bool unmask_layers_net(const struct landlock_domain *const domain, const struct landlock_id id, struct layer_masks *masks, @@ -104,6 +125,7 @@ static int current_check_access_socket(struct socket *c= onst sock, switch (address->sa_family) { case AF_UNSPEC: if (access_request =3D=3D LANDLOCK_ACCESS_NET_CONNECT_TCP || + access_request =3D=3D LANDLOCK_ACCESS_NET_CONNECT_MPTCP || (access_request =3D=3D LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP && connecting)) { /* @@ -147,17 +169,15 @@ static int current_check_access_socket(struct socket = *const sock, }); return -EACCES; } - } else if (access_request =3D=3D LANDLOCK_ACCESS_NET_BIND_TCP || - access_request =3D=3D LANDLOCK_ACCESS_NET_BIND_UDP) { + } else if (is_bind_access(access_request)) { /* * Binding to an AF_UNSPEC address is treated * differently by IPv4 and IPv6 sockets. The socket's * family may change under our feet due to * setsockopt(IPV6_ADDRFORM), but that's ok: we either - * reject entirely for IPv6 or require - * %LANDLOCK_ACCESS_NET_BIND_TCP or - * %LANDLOCK_ACCESS_NET_BIND_UDP for IPv4, so it cannot - * be used to bypass the policy. + * reject entirely for IPv6 or require the relevant bind + * access right for IPv4, so it cannot be used to bypass + * the policy. * * IPv4 sockets map AF_UNSPEC to AF_INET for * retrocompatibility for bind accesses, only if the @@ -204,12 +224,10 @@ static int current_check_access_socket(struct socket = *const sock, addr4 =3D (struct sockaddr_in *)address; port =3D addr4->sin_port; =20 - if (access_request =3D=3D LANDLOCK_ACCESS_NET_CONNECT_TCP || - access_request =3D=3D LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP) { + if (is_connect_access(access_request)) { audit_net.dport =3D port; audit_net.v4info.daddr =3D addr4->sin_addr.s_addr; - } else if (access_request =3D=3D LANDLOCK_ACCESS_NET_BIND_TCP || - access_request =3D=3D LANDLOCK_ACCESS_NET_BIND_UDP) { + } else if (is_bind_access(access_request)) { audit_net.sport =3D port; audit_net.v4info.saddr =3D addr4->sin_addr.s_addr; } else { @@ -228,12 +246,10 @@ static int current_check_access_socket(struct socket = *const sock, addr6 =3D (struct sockaddr_in6 *)address; port =3D addr6->sin6_port; =20 - if (access_request =3D=3D LANDLOCK_ACCESS_NET_CONNECT_TCP || - access_request =3D=3D LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP) { + if (is_connect_access(access_request)) { audit_net.dport =3D port; audit_net.v6info.daddr =3D addr6->sin6_addr; - } else if (access_request =3D=3D LANDLOCK_ACCESS_NET_BIND_TCP || - access_request =3D=3D LANDLOCK_ACCESS_NET_BIND_UDP) { + } else if (is_bind_access(access_request)) { audit_net.sport =3D port; audit_net.v6info.saddr =3D addr6->sin6_addr; } else { @@ -331,6 +347,8 @@ static int hook_socket_bind(struct socket *const sock, =20 if (sk_is_tcp(sock->sk)) access_request =3D LANDLOCK_ACCESS_NET_BIND_TCP; + else if (sk_is_mptcp_socket(sock->sk)) + access_request =3D LANDLOCK_ACCESS_NET_BIND_MPTCP; else if (sk_is_udp(sock->sk)) access_request =3D LANDLOCK_ACCESS_NET_BIND_UDP; else @@ -349,6 +367,8 @@ static int hook_socket_connect(struct socket *const soc= k, =20 if (sk_is_tcp(sock->sk)) access_request =3D LANDLOCK_ACCESS_NET_CONNECT_TCP; + else if (sk_is_mptcp_socket(sock->sk)) + access_request =3D LANDLOCK_ACCESS_NET_CONNECT_MPTCP; else if (sk_is_udp(sock->sk)) access_request =3D LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP; else @@ -377,12 +397,20 @@ static int hook_socket_sendmsg(struct socket *const s= ock, access_mask_t access_request; int ret =3D 0; =20 - if ((msg->msg_flags & MSG_FASTOPEN) && address && sk_is_tcp(sock->sk)) { - ret =3D current_check_access_socket( - sock, address, addrlen, LANDLOCK_ACCESS_NET_CONNECT_TCP, - true); - if (ret !=3D 0) - return ret; + if ((msg->msg_flags & MSG_FASTOPEN) && address) { + access_mask_t fastopen_access =3D 0; + + if (sk_is_tcp(sock->sk)) + fastopen_access =3D LANDLOCK_ACCESS_NET_CONNECT_TCP; + else if (sk_is_mptcp_socket(sock->sk)) + fastopen_access =3D LANDLOCK_ACCESS_NET_CONNECT_MPTCP; + + if (fastopen_access) { + ret =3D current_check_access_socket( + sock, address, addrlen, fastopen_access, true); + if (ret !=3D 0) + return ret; + } } =20 if (sk_is_udp(sock->sk)) diff --git a/security/landlock/syscalls.c b/security/landlock/syscalls.c index 1d02d57f4c48..cc54d4f1d502 100644 --- a/security/landlock/syscalls.c +++ b/security/landlock/syscalls.c @@ -172,7 +172,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 11; +const int landlock_abi_version =3D 12; =20 /** * sys_landlock_create_ruleset - Create a new ruleset diff --git a/tools/testing/selftests/landlock/base_test.c b/tools/testing/s= elftests/landlock/base_test.c index d20ab8f0862c..58fe322d8637 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(11, landlock_create_ruleset(NULL, 0, + ASSERT_EQ(12, landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION)); =20 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 0, --=20 2.55.0 From nobody Sat Sep 5 05:48:52 2026 Received: from mail-wm1-f41.google.com (mail-wm1-f41.google.com [209.85.128.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 A670C30F92E for ; Sun, 30 Aug 2026 20:17:09 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788121031; cv=none; b=iDu5QHIsXGi9r08ZbfzHA9bfbP8w+jtSmLSslniI12X3tMaphIsq64VlMzneLKkyttBkOdq+S8naZ/VNqGZn22Ryt9XoMoheDKLQZmQHS0bOr8O9ScRLRWLNYWl13lKG4cmPnsGVli4l+5sVL34iNiVTO2wa1E8stMHOk6faWUc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788121031; c=relaxed/simple; bh=jNY4uJoFtV1wVz5cGO5OQXFw5bVAghAZjzW8EipPaDE=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=uk7ajsJdilM5GgPrhL17GwUW/9Er6zDxzpoO+RLrIMMqGrMytxz/fa3GkYtu/toJcSStFVFLD5+cXWfMk78EFivj4mpAa3UdovFJ/z4FpVFV0fEMRTWpcANPIjNnjYIIH2QImUHDenFQR7B4WWbHy4Nw3/yPJQiHRAFbSUoq0Tk= 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=RpjBtkXf; arc=none smtp.client-ip=209.85.128.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="RpjBtkXf" Received: by mail-wm1-f41.google.com with SMTP id 5b1f17b1804b1-49b96837ca3so15012955e9.3 for ; Sun, 30 Aug 2026 13:17:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788121028; x=1788725828; darn=lists.linux.dev; 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=SGjXy395v8FjFoEjmZQLYbJNRsx4nqNp3408l01vhyw=; b=RpjBtkXfrLW6sZDGooz9Xu60D6xAvdnMhv6QDG+zk0NyHA20IvQckOabtR2BQ9ZOaH Q+8iQu9x3q14MEaCLMQeHQiQrsdnngMxRz+Y8Aq13LxKLK175TG/zshzV7g508AfuPKy 4JoTVkq3nhgE8lyDhd00MYDSYkpGGT9SmQTYYVu7d73aA5Wc/rSVyxh2k1lAGVDSlgKg ulNKMuoPnkXE853oYRpV6kRTKWWBR+HDc2T+fUz1GTpmr4oi6uiLVXkieLYwW1LFYPC2 FuoCiXbTkDQe0RXAijNiLN/dveP771qmORIR3Y4Fh3/tXzuxzLEL8dhYePa6+i3Zdvhd DXaA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788121028; x=1788725828; 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=SGjXy395v8FjFoEjmZQLYbJNRsx4nqNp3408l01vhyw=; b=fqwhyYH1iQPOydkIzjgPDKLXS9FE489aAlCLSfQ7pFR4VJZjbK2FlgK1qGjdJYCv1V u0rLMJ4F2W/NzBxgSJaw5I313o7SJfkIm2fub5ec+hXb761cCZcxDdhOQpLo7GmOAgbW aie7mVeiGyo19BfahTLrvVl1QXNYgxQPtZhkfuUsp3EeQY+rgUWuXlI46zlKWnCoTBVD SBtL1otgR4ycwnHpKWsQnuCS0mH8oegmNSlcL6KV8imWd9WgDhBTDYlShHi37o0uOouK EpItW0WIvGQxd7QaovdAp1B1KbWNvDKmeP3GuDUT/5Rpxqr/d9B0aQvYF7VA6YgUsQqp lj6Q== X-Forwarded-Encrypted: i=1; AHgh+RoYGg6IpnVPwTRH36vYwbGbQrAOc+g/kOuPJpINipUhaGbJEuVl1AJ3B7FaEceZurmUD3xY/A==@lists.linux.dev X-Gm-Message-State: AFuF++kTuAVoS7FNR/9hjt0Sr4dbdWh4L7ekIZdXGGIuhFzcXp5Q33WM 25V4kufbDfiEVloEH8e+LSWpJrPwMmvDAsaJ0QEr5izZeVSs5CcT1hf5 X-Gm-Gg: AR+sD10Jbe381X0JdCZZzfnTeaQ+xzsSmTSSg8pfk58tx3vMKWrd2wRyLL0eXFnLWnD 2FRibXJb/xFwU9D+zKVO3acEEtWlGelc8f1IetCbSY4pmJiTFXiTDgXK3dakJVxQ5QuoLo7CJ0Y QM/sEl5dyRG65Ve3o3ZNzyoH2DSv+33Jw9un5YBjegpuD9JPr8nPYzSgjWSL1FbM/Cfdn7JzDnu z5MrYNZyxpMkhLeK4oigedoUZO61hgX+WQKrw3r5dM6QLzZCh/ZuIh7WW6s3Jb24zRjrF4ym7aS GbZYImJ15m/rvvJ/wNv6sw8dLicGTOp2nCF2O99zxguvNHzw3PXZzbI61iQg7IRzRaaEFE9QH62 TpFCYJ0xrupkmVD5fRXWY8VYJ2ozY0J9UC/RVapniBTmwEfFAITXAIE3a7IYwwjHbVa35uJ19gf MGxoQNR1o758PnYqN93aTiYgtWHQyU1Y7nZiiMIXopJkNpX2ap6Q+d3+VT2cYUBVxrq3myle8wN prwOc7q120yjQ== X-Received: by 2002:a05:600c:1d1d:b0:499:ad2e:f7bc with SMTP id 5b1f17b1804b1-49b91c3ddbcmr257245375e9.10.1788121027637; Sun, 30 Aug 2026 13:17:07 -0700 (PDT) Received: from localhost (ip87-106-108-193.pbiaas.com. [87.106.108.193]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49cc9497b3esm180660665e9.5.2026.08.30.13.17.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 30 Aug 2026 13:17:07 -0700 (PDT) From: =?UTF-8?q?G=C3=BCnther=20Noack?= To: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= Cc: Matthieu Baerts , Mat Martineau , Geliang Tang , Mikhail Ivanov , mptcp@lists.linux.dev, netdev@vger.kernel.org, linux-security-module@vger.kernel.org, =?UTF-8?q?G=C3=BCnther=20Noack?= Subject: [PATCH 4/6] selftests/landlock: Add MPTCP network access tests Date: Sun, 30 Aug 2026 22:16:48 +0200 Message-ID: <20260830201650.67050-5-gnoack3000@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260830201650.67050-1-gnoack3000@gmail.com> References: <20260830201650.67050-1-gnoack3000@gmail.com> Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Test LANDLOCK_ACCESS_NET_BIND_MPTCP and LANDLOCK_ACCESS_NET_CONNECT_MPTCP: * Add the MPTCP_SANDBOX variant to the net_test fixtures. * Introduce prot_*() helper functions for audit tests. * Extend existing tests as needed for MPTCP, including the tcp_fastopen tes= t. Signed-off-by: G=C3=BCnther Noack --- tools/testing/selftests/landlock/net_test.c | 256 ++++++++++++++++---- 1 file changed, 210 insertions(+), 46 deletions(-) diff --git a/tools/testing/selftests/landlock/net_test.c b/tools/testing/se= lftests/landlock/net_test.c index 3a0482beca5f..fbb3a99bc380 100644 --- a/tools/testing/selftests/landlock/net_test.c +++ b/tools/testing/selftests/landlock/net_test.c @@ -40,6 +40,7 @@ enum sandbox_type { /* This may be used to test rules that allow *and* deny accesses. */ TCP_SANDBOX, UDP_SANDBOX, + MPTCP_SANDBOX, }; =20 static int set_service(struct service_fixture *const srv, @@ -105,6 +106,12 @@ static bool prot_is_udp(const struct protocol_variant = *const prot) (prot->protocol =3D=3D IPPROTO_UDP || prot->protocol =3D=3D IPPROT= O_IP); } =20 +static bool prot_is_mptcp(const struct protocol_variant *const prot) +{ + return (prot->domain =3D=3D AF_INET || prot->domain =3D=3D AF_INET6) && + prot->type =3D=3D SOCK_STREAM && prot->protocol =3D=3D IPPROTO_MPT= CP; +} + static bool is_restricted(const struct protocol_variant *const prot, const enum sandbox_type sandbox) { @@ -113,6 +120,8 @@ static bool is_restricted(const struct protocol_variant= *const prot, return prot_is_tcp(prot); case UDP_SANDBOX: return prot_is_udp(prot); + case MPTCP_SANDBOX: + return prot_is_mptcp(prot); case NO_SANDBOX: default: return false; @@ -126,6 +135,8 @@ static __u64 sandbox_bind_access(const enum sandbox_typ= e sandbox) return LANDLOCK_ACCESS_NET_BIND_TCP; case UDP_SANDBOX: return LANDLOCK_ACCESS_NET_BIND_UDP; + case MPTCP_SANDBOX: + return LANDLOCK_ACCESS_NET_BIND_MPTCP; case NO_SANDBOX: default: return 0; @@ -139,6 +150,8 @@ static __u64 sandbox_connect_access(const enum sandbox_= type sandbox) return LANDLOCK_ACCESS_NET_CONNECT_TCP; case UDP_SANDBOX: return LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP; + case MPTCP_SANDBOX: + return LANDLOCK_ACCESS_NET_CONNECT_MPTCP; case NO_SANDBOX: default: return 0; @@ -815,6 +828,114 @@ FIXTURE_VARIANT_ADD(protocol, udp_sandbox_with_unix_d= atagram) { }, }; =20 +/* clang-format off */ +FIXTURE_VARIANT_ADD(protocol, mptcp_sandbox_with_ipv4_tcp1) { + /* clang-format on */ + .sandbox =3D MPTCP_SANDBOX, + .prot =3D { + .domain =3D AF_INET, + .type =3D SOCK_STREAM, + /* IPPROTO_IP =3D=3D 0 */ + .protocol =3D IPPROTO_IP, + }, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(protocol, mptcp_sandbox_with_ipv4_tcp2) { + /* clang-format on */ + .sandbox =3D MPTCP_SANDBOX, + .prot =3D { + .domain =3D AF_INET, + .type =3D SOCK_STREAM, + .protocol =3D IPPROTO_TCP, + }, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(protocol, mptcp_sandbox_with_ipv4_mptcp) { + /* clang-format on */ + .sandbox =3D MPTCP_SANDBOX, + .prot =3D { + .domain =3D AF_INET, + .type =3D SOCK_STREAM, + .protocol =3D IPPROTO_MPTCP, + }, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(protocol, mptcp_sandbox_with_ipv6_tcp1) { + /* clang-format on */ + .sandbox =3D MPTCP_SANDBOX, + .prot =3D { + .domain =3D AF_INET6, + .type =3D SOCK_STREAM, + /* IPPROTO_IP =3D=3D 0 */ + .protocol =3D IPPROTO_IP, + }, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(protocol, mptcp_sandbox_with_ipv6_tcp2) { + /* clang-format on */ + .sandbox =3D MPTCP_SANDBOX, + .prot =3D { + .domain =3D AF_INET6, + .type =3D SOCK_STREAM, + .protocol =3D IPPROTO_TCP, + }, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(protocol, mptcp_sandbox_with_ipv6_mptcp) { + /* clang-format on */ + .sandbox =3D MPTCP_SANDBOX, + .prot =3D { + .domain =3D AF_INET6, + .type =3D SOCK_STREAM, + .protocol =3D IPPROTO_MPTCP, + }, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(protocol, mptcp_sandbox_with_ipv4_udp) { + /* clang-format on */ + .sandbox =3D MPTCP_SANDBOX, + .prot =3D { + .domain =3D AF_INET, + .type =3D SOCK_DGRAM, + }, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(protocol, mptcp_sandbox_with_ipv6_udp) { + /* clang-format on */ + .sandbox =3D MPTCP_SANDBOX, + .prot =3D { + .domain =3D AF_INET6, + .type =3D SOCK_DGRAM, + }, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(protocol, mptcp_sandbox_with_unix_stream) { + /* clang-format on */ + .sandbox =3D MPTCP_SANDBOX, + .prot =3D { + .domain =3D AF_UNIX, + .type =3D SOCK_STREAM, + }, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(protocol, mptcp_sandbox_with_unix_datagram) { + /* clang-format on */ + .sandbox =3D MPTCP_SANDBOX, + .prot =3D { + .domain =3D AF_UNIX, + .type =3D SOCK_DGRAM, + }, +}; + static void test_bind_and_connect(struct __test_metadata *const _metadata, const struct service_fixture *const srv, const bool deny_bind, const bool deny_connect) @@ -1294,14 +1415,12 @@ TEST_F(protocol, connect_unspec) =20 TEST_F(protocol, tcp_fastopen) { - const bool restricted =3D variant->sandbox =3D=3D TCP_SANDBOX && - variant->prot.type =3D=3D SOCK_STREAM && - (variant->prot.protocol =3D=3D IPPROTO_TCP || - variant->prot.protocol =3D=3D IPPROTO_IP) && - (variant->prot.domain =3D=3D AF_INET || - variant->prot.domain =3D=3D AF_INET6); + const bool stream_sandbox =3D variant->sandbox =3D=3D TCP_SANDBOX || + variant->sandbox =3D=3D MPTCP_SANDBOX; + const bool restricted =3D stream_sandbox && + is_restricted(&variant->prot, variant->sandbox); const struct landlock_ruleset_attr ruleset_attr =3D { - .handled_access_net =3D LANDLOCK_ACCESS_NET_CONNECT_TCP, + .handled_access_net =3D sandbox_connect_access(variant->sandbox), }; int bind_fd, client_fd, status; char buf; @@ -1324,7 +1443,7 @@ TEST_F(protocol, tcp_fastopen) connect_fd =3D socket_variant(&self->srv0); ASSERT_LE(0, connect_fd); =20 - if (variant->sandbox =3D=3D TCP_SANDBOX) { + if (stream_sandbox) { const int ruleset_fd =3D landlock_create_ruleset( &ruleset_attr, sizeof(ruleset_attr), 0); ASSERT_LE(0, ruleset_fd); @@ -2219,13 +2338,15 @@ FIXTURE_TEARDOWN(mini) =20 /* clang-format off */ =20 -#define ACCESS_LAST LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP +#define ACCESS_LAST LANDLOCK_ACCESS_NET_CONNECT_MPTCP =20 #define ACCESS_ALL ( \ LANDLOCK_ACCESS_NET_BIND_TCP | \ LANDLOCK_ACCESS_NET_CONNECT_TCP | \ LANDLOCK_ACCESS_NET_BIND_UDP | \ - LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP) + LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP | \ + LANDLOCK_ACCESS_NET_BIND_MPTCP | \ + LANDLOCK_ACCESS_NET_CONNECT_MPTCP) =20 /* clang-format on */ =20 @@ -2949,6 +3070,28 @@ FIXTURE_VARIANT_ADD(audit, ipv6_udp) { }, }; =20 +/* clang-format off */ +FIXTURE_VARIANT_ADD(audit, ipv4_mptcp) { + /* clang-format on */ + .addr =3D "127\\.0\\.0\\.1", + .prot =3D { + .domain =3D AF_INET, + .type =3D SOCK_STREAM, + .protocol =3D IPPROTO_MPTCP, + }, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(audit, ipv6_mptcp) { + /* clang-format on */ + .addr =3D "::1", + .prot =3D { + .domain =3D AF_INET6, + .type =3D SOCK_STREAM, + .protocol =3D IPPROTO_MPTCP, + }, +}; + FIXTURE_SETUP(audit) { struct protocol_variant prot_unspec =3D variant->prot; @@ -2975,17 +3118,56 @@ FIXTURE_TEARDOWN(audit) clear_cap(_metadata, CAP_AUDIT_CONTROL); } =20 +static __u64 prot_bind_access(const struct protocol_variant *const prot) +{ + if (prot_is_mptcp(prot)) + return LANDLOCK_ACCESS_NET_BIND_MPTCP; + + if (prot->type =3D=3D SOCK_STREAM) + return LANDLOCK_ACCESS_NET_BIND_TCP; + + return LANDLOCK_ACCESS_NET_BIND_UDP; +} + +static __u64 prot_connect_access(const struct protocol_variant *const prot) +{ + if (prot_is_mptcp(prot)) + return LANDLOCK_ACCESS_NET_CONNECT_MPTCP; + + if (prot->type =3D=3D SOCK_STREAM) + return LANDLOCK_ACCESS_NET_CONNECT_TCP; + + return LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP; +} + +static const char *prot_bind_blocker(const struct protocol_variant *const = prot) +{ + if (prot_is_mptcp(prot)) + return "net\\.bind_mptcp"; + + if (prot->type =3D=3D SOCK_STREAM) + return "net\\.bind_tcp"; + + return "net\\.bind_udp"; +} + +static const char * +prot_connect_blocker(const struct protocol_variant *const prot) +{ + if (prot_is_mptcp(prot)) + return "net\\.connect_mptcp"; + + if (prot->type =3D=3D SOCK_STREAM) + return "net\\.connect_tcp"; + + return "net\\.connect_send_udp"; +} + TEST_F(audit, bind) { - const char *audit_evt =3D (variant->prot.type =3D=3D SOCK_STREAM ? - "net\\.bind_tcp" : - "net\\.bind_udp"); - const __u64 access_rights =3D - (variant->prot.type =3D=3D SOCK_STREAM ? - LANDLOCK_ACCESS_NET_BIND_TCP | - LANDLOCK_ACCESS_NET_CONNECT_TCP : - LANDLOCK_ACCESS_NET_BIND_UDP | - LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP); + const char *audit_evt =3D prot_bind_blocker(&variant->prot); + const __u64 access_rights =3D prot_bind_access(&variant->prot) | + prot_connect_access(&variant->prot); const struct landlock_ruleset_attr ruleset_attr =3D { .handled_access_net =3D access_rights, .quiet_access_net =3D access_rights, @@ -3031,15 +3213,9 @@ TEST_F(audit, bind) =20 TEST_F(audit, connect) { - const char *audit_evt =3D (variant->prot.type =3D=3D SOCK_STREAM ? - "net\\.connect_tcp" : - "net\\.connect_send_udp"); - const __u64 bind_right =3D (variant->prot.type =3D=3D SOCK_STREAM ? - LANDLOCK_ACCESS_NET_BIND_TCP : - LANDLOCK_ACCESS_NET_BIND_UDP); - const __u64 conn_right =3D (variant->prot.type =3D=3D SOCK_STREAM ? - LANDLOCK_ACCESS_NET_CONNECT_TCP : - LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP); + const char *audit_evt =3D prot_connect_blocker(&variant->prot); + const __u64 bind_right =3D prot_bind_access(&variant->prot); + const __u64 conn_right =3D prot_connect_access(&variant->prot); const __u64 access_rights =3D bind_right | conn_right; const struct landlock_ruleset_attr ruleset_attr =3D { .handled_access_net =3D access_rights, @@ -3104,15 +3280,9 @@ TEST_F(audit, connect) /* Quieting bind access has no effect on connect. */ TEST_F(audit, connect_quiet_bind) { - const char *audit_evt =3D (variant->prot.type =3D=3D SOCK_STREAM ? - "net\\.connect_tcp" : - "net\\.connect_send_udp"); - const int bind_right =3D (variant->prot.type =3D=3D SOCK_STREAM ? - LANDLOCK_ACCESS_NET_BIND_TCP : - LANDLOCK_ACCESS_NET_BIND_UDP); - const int conn_right =3D (variant->prot.type =3D=3D SOCK_STREAM ? - LANDLOCK_ACCESS_NET_CONNECT_TCP : - LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP); + const char *audit_evt =3D prot_connect_blocker(&variant->prot); + const int bind_right =3D prot_bind_access(&variant->prot); + const int conn_right =3D prot_connect_access(&variant->prot); const int access_rights =3D bind_right | conn_right; const struct landlock_ruleset_attr ruleset_attr =3D { .handled_access_net =3D access_rights, @@ -3194,15 +3364,9 @@ static int matches_log_connect_bound(int audit_fd, c= onst char *const blockers, */ TEST_F(audit, connect_bound) { - const __u64 bind_right =3D (variant->prot.type =3D=3D SOCK_STREAM ? - LANDLOCK_ACCESS_NET_BIND_TCP : - LANDLOCK_ACCESS_NET_BIND_UDP); - const __u64 conn_right =3D (variant->prot.type =3D=3D SOCK_STREAM ? - LANDLOCK_ACCESS_NET_CONNECT_TCP : - LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP); - const char *const audit_evt =3D (variant->prot.type =3D=3D SOCK_STREAM ? - "net\\.connect_tcp" : - "net\\.connect_send_udp"); + const __u64 bind_right =3D prot_bind_access(&variant->prot); + const __u64 conn_right =3D prot_connect_access(&variant->prot); + const char *const audit_evt =3D prot_connect_blocker(&variant->prot); const struct landlock_ruleset_attr ruleset_attr =3D { .handled_access_net =3D bind_right | conn_right, }; --=20 2.55.0 From nobody Sat Sep 5 05:48:52 2026 Received: from mail-wr1-f53.google.com (mail-wr1-f53.google.com [209.85.221.53]) (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 670AC31E821 for ; Sun, 30 Aug 2026 20:17:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788121033; cv=none; b=eTMC7tt5qanPon91RJ4tFpm5MtFN26nMydNynb+Dj3cVzLlFYn1kOSlx9/B/s8uHVU63X8TXCXuSKbjl5n2Tc2PvPUzt9RmZy2JCYeERwfFNwsHUq5gFB+TMVyb5z3GLpVvG/9+ZWO8UbSTuZ13O3EiIAI/gB6s6o4gYTY71gZI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788121033; c=relaxed/simple; bh=f/CraVslGraq/5v+2fXAMKOP6bZGEG+2lxqiFAm2vk4=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=R9nX1c22BtUtB105xiCI8qDr8iESt8xvJm8SI0xO3pXaOnNVhpD8mimTU8pCeNIe6jXOTBvmxyCnd989R/LjHuS+SF0j97Mjt7lvpzrCsNUWdTI/VSLF6M17k4x2BRifgIJjn4t4T4+oUBE/F9GQuQrlePfWpsFYE6NbrJ9s7Wk= 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=KtWf07M1; arc=none smtp.client-ip=209.85.221.53 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="KtWf07M1" Received: by mail-wr1-f53.google.com with SMTP id ffacd0b85a97d-482ea739de2so1638574f8f.0 for ; Sun, 30 Aug 2026 13:17:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788121029; x=1788725829; darn=lists.linux.dev; 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=xz4w4A2CPC2oBpOuImVyjCDcMdVG2rtFR3i2CLf98XA=; b=KtWf07M1dkdxEnyqN79EGnmjWNUJA+k9Y93yahLWbeSn0viu6qtTI5RCfBwbbybh9Q 4t7oIdClq7yvBeNxbAZL9vP+7L8m6vckEPAe008RETt1guea7WFqkZubxRBhMHnwf9Er pc9RmRgAcMPpc6cv7uBEQxDDgXCx25cJID+8NLD/ZEJkJdzAd2wfDEGAwTXNYEV60wNU is/NeNOKuLIZGyU/7zlF02GEZ+LzbJZncFx6ojBfG5ThRLKQpkKwCNWtd+eStrO6OMZN zROSZtVVUrZWcLjzHhYlWuxOTYHg21X14aAT3FEqy7o13vl3Ov7+PxZZ43WilJAaiTjY zBNA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788121029; x=1788725829; 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=xz4w4A2CPC2oBpOuImVyjCDcMdVG2rtFR3i2CLf98XA=; b=Kc0sQnx5l/jGKInl2XE9GUcsPLhPlKwDQXZeO3tjrFt/1kUtSkR2xwvvxgDue7l1ID f+pXrGLM7KyQ06dE2BhXZ93WmJ1PP8bOpafQvzp1zixlaOSOGf31hOsnP6XpcUdTAlg1 ETLYsYdW+DdqfD+PR+CgIXwQQo/fj0Kr82UzSZyqGiHHH5LbKMS1uX0QuFrc+CDHpjk6 N6xnaFeTHKzJ6uxTDjKS2XYJ3fEq+gMPkh/HjkjYr8dgZYF02uKYOPnpNrgcsWcfBW80 MEi5KUI8VO6sADgpNzqw+sUuOQi6IxdiAILMRGFobsTmN9poY6Y7pcDTLkdS5udExPI0 WUTA== X-Forwarded-Encrypted: i=1; AKwUvBxT09YL6amnP9sOSw6bycDenF7wJvlcyOchzPKWQPUR/AnqH1uzw5mSZ37eCqUVi6F95I6hLg==@lists.linux.dev X-Gm-Message-State: AFuF++lQYAAzXL19NIZeyNBjFVPpC7tkI8O1mUhtO/swClHbeNaLxCZ5 U+ssFlG8+43H1HqxLwR3GdjZt8fOtAeqnLXQ4aK0CNX/VSF4Xow3zkqC X-Gm-Gg: AYBFou3z1fsjbJJMeqYthjDeZQc/4xOkLQFKHBFZp9KeH0IGnTR443uKes60Chvi2eV VS1Q27t2Ypl7r9TgmrW7qrq4D7+n0oQBddfWSToYPcPBPR4GtrQhXqxUf2T40uUoSWITO+7Obbo 5HaSxwbIH4QNGtTCzBvR7NarMhuL4YVcOH7TgJZAdmpWSR6GmS0mWenoLJCW5WCIS8O0J5wE23W 4Q34CNuivaEW2+vRvm0jljlaMmfzWAr3FF88h+6Iv38pOLTXDuGNBLd7YALhhj4PckDEdItzm5W +vOOcz0TRD4wPTc53s5CHben7NveAg4LHYw8LZp7NN7+VB5xQuJakPU1+KirnxC3qd8Nn12e6ko KjLeCz4BS7XOl9Pyf/wxgCZmovHvaD40bqKHivuLisPDeM4/KW7pHarfA8KcrwJ4ZoMVF86M8rS NLtXfanCYFh6rPLEkw5P9ckElLi8cvriukKFivWx2r5d5dTsvlZ5jeoNSMnhAEQXMCF6V6SqNSY s1QXvM7Nz7H6w== X-Received: by 2002:a5d:5e8d:0:b0:484:3328:2f6f with SMTP id ffacd0b85a97d-4843395c662mr13687693f8f.28.1788121029480; Sun, 30 Aug 2026 13:17:09 -0700 (PDT) Received: from localhost (ip87-106-108-193.pbiaas.com. [87.106.108.193]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-482fbac7c01sm18901239f8f.14.2026.08.30.13.17.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 30 Aug 2026 13:17:09 -0700 (PDT) From: =?UTF-8?q?G=C3=BCnther=20Noack?= To: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= Cc: Matthieu Baerts , Mat Martineau , Geliang Tang , Mikhail Ivanov , mptcp@lists.linux.dev, netdev@vger.kernel.org, linux-security-module@vger.kernel.org, =?UTF-8?q?G=C3=BCnther=20Noack?= Subject: [PATCH 5/6] samples/landlock: Support MPTCP access rights Date: Sun, 30 Aug 2026 22:16:49 +0200 Message-ID: <20260830201650.67050-6-gnoack3000@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260830201650.67050-1-gnoack3000@gmail.com> References: <20260830201650.67050-1-gnoack3000@gmail.com> Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Add the LL_MPTCP_BIND and LL_MPTCP_CONNECT environment variables to restrict the ports MPTCP sockets may bind and connect to, and the matching "mptcp_bind" and "mptcp_connect" values for LL_QUIET_ACCESS. Because MPTCP sockets use TCP port numbers but are not covered by the TCP access rights, LL_TCP_BIND and LL_TCP_CONNECT alone leave MPTCP unrestricted. Point that out in the help text. Bump LANDLOCK_ABI_LAST to 12 and drop the new access rights when running on an older kernel. Signed-off-by: G=C3=BCnther Noack --- samples/landlock/sandboxer.c | 52 ++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/samples/landlock/sandboxer.c b/samples/landlock/sandboxer.c index 1c514efecafb..5eae6fe7467f 100644 --- a/samples/landlock/sandboxer.c +++ b/samples/landlock/sandboxer.c @@ -67,6 +67,8 @@ static inline int landlock_restrict_self(const int rulese= t_fd, #define ENV_FORCE_LOG_NAME "LL_FORCE_LOG" #define ENV_UDP_BIND_NAME "LL_UDP_BIND" #define ENV_UDP_CONNECT_SEND_NAME "LL_UDP_CONNECT_SEND" +#define ENV_MPTCP_BIND_NAME "LL_MPTCP_BIND" +#define ENV_MPTCP_CONNECT_NAME "LL_MPTCP_CONNECT" #define ENV_DELIMITER ":" =20 static int str2num(const char *numstr, __u64 *num_dst) @@ -353,6 +355,12 @@ static int add_quiet_access(const char *const env_var, else if (strcmp(str_access, "udp_connect") =3D=3D 0) ruleset_attr->quiet_access_net |=3D LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP; + else if (strcmp(str_access, "mptcp_bind") =3D=3D 0) + ruleset_attr->quiet_access_net |=3D + LANDLOCK_ACCESS_NET_BIND_MPTCP; + else if (strcmp(str_access, "mptcp_connect") =3D=3D 0) + ruleset_attr->quiet_access_net |=3D + LANDLOCK_ACCESS_NET_CONNECT_MPTCP; else if (strcmp(str_access, "abstract_unix_socket") =3D=3D 0) ruleset_attr->quiet_scoped |=3D LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET; @@ -373,7 +381,7 @@ static int add_quiet_access(const char *const env_var, return 0; } =20 -#define LANDLOCK_ABI_LAST 11 +#define LANDLOCK_ABI_LAST 12 =20 #define XSTR(s) #s #define STR(s) XSTR(s) @@ -401,6 +409,12 @@ static const char help[] =3D "* " ENV_UDP_CONNECT_SEND_NAME ": remote UDP ports allowed to connect " "or send to (client: use as destination port / server: receive only from = it)\n" "(caution: sending requires being able to bind to a local source port)\n" + "* " ENV_MPTCP_BIND_NAME ": ports allowed to bind with MPTCP sockets " + "(server)\n" + "* " ENV_MPTCP_CONNECT_NAME ": ports allowed to connect to with MPTCP " + "sockets (client)\n" + "(caution: MPTCP sockets use TCP ports but are not covered by " + ENV_TCP_BIND_NAME " nor " ENV_TCP_CONNECT_NAME ")\n" "* " ENV_SCOPED_NAME ": actions denied on the outside of the landlock dom= ain\n" " - \"a\" to restrict opening abstract unix sockets\n" " - \"s\" to restrict sending signals\n" @@ -418,6 +432,8 @@ static const char help[] =3D " - \"tcp_connect\" to quiet tcp connect denials\n" " - \"udp_bind\" to quiet udp bind denials\n" " - \"udp_connect\" to quiet udp connect / send denials\n" + " - \"mptcp_bind\" to quiet mptcp bind denials\n" + " - \"mptcp_connect\" to quiet mptcp connect denials\n" " - \"abstract_unix_socket\" to quiet abstract unix socket denials\n" " - \"signal\" to quiet signal denials\n" "\n" @@ -449,7 +465,9 @@ int main(const int argc, char *const argv[], char *cons= t *const envp) .handled_access_net =3D LANDLOCK_ACCESS_NET_BIND_TCP | LANDLOCK_ACCESS_NET_CONNECT_TCP | LANDLOCK_ACCESS_NET_BIND_UDP | - LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP, + LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP | + LANDLOCK_ACCESS_NET_BIND_MPTCP | + LANDLOCK_ACCESS_NET_CONNECT_MPTCP, .scoped =3D LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET | LANDLOCK_SCOPE_SIGNAL, .quiet_access_fs =3D 0, @@ -556,6 +574,12 @@ int main(const int argc, char *const argv[], char *con= st *const envp) supported_restrict_flags &=3D ~LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS; set_restrict_flags &=3D ~LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS; + __attribute__((fallthrough)); + case 11: + /* Removes MPTCP support for ABI < 12 */ + ruleset_attr.handled_access_net &=3D + ~(LANDLOCK_ACCESS_NET_BIND_MPTCP | + LANDLOCK_ACCESS_NET_CONNECT_MPTCP); =20 /* Must be printed for any ABI < LANDLOCK_ABI_LAST. */ fprintf(stderr, @@ -600,6 +624,18 @@ int main(const int argc, char *const argv[], char *con= st *const envp) ruleset_attr.handled_access_net &=3D ~LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP; } + /* Removes MPTCP bind access control if not supported by a user. */ + env_port_name =3D getenv(ENV_MPTCP_BIND_NAME); + if (!env_port_name) { + ruleset_attr.handled_access_net &=3D + ~LANDLOCK_ACCESS_NET_BIND_MPTCP; + } + /* Removes MPTCP connect access control if not supported by a user. */ + env_port_name =3D getenv(ENV_MPTCP_CONNECT_NAME); + if (!env_port_name) { + ruleset_attr.handled_access_net &=3D + ~LANDLOCK_ACCESS_NET_CONNECT_MPTCP; + } =20 if (check_ruleset_scope(ENV_SCOPED_NAME, &ruleset_attr)) return 1; @@ -684,6 +720,18 @@ int main(const int argc, char *const argv[], char *con= st *const envp) 0)) { goto err_close_ruleset; } + if (populate_ruleset_net(ENV_MPTCP_BIND_NAME, ruleset_fd, + ruleset_attr.handled_access_net & + LANDLOCK_ACCESS_NET_BIND_MPTCP, + 0)) { + goto err_close_ruleset; + } + if (populate_ruleset_net(ENV_MPTCP_CONNECT_NAME, ruleset_fd, + ruleset_attr.handled_access_net & + LANDLOCK_ACCESS_NET_CONNECT_MPTCP, + 0)) { + goto err_close_ruleset; + } =20 if (quiet_supported) { if (populate_ruleset_net(ENV_NET_QUIET_NAME, ruleset_fd, 0, --=20 2.55.0 From nobody Sat Sep 5 05:48:52 2026 Received: from mail-wm1-f53.google.com (mail-wm1-f53.google.com [209.85.128.53]) (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 5A67D320393 for ; Sun, 30 Aug 2026 20:17:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788121035; cv=none; b=oVf5pGACvE1bM5qXsvRdqe+HdJh+siWA0/tvBMuB9/N1X60IpLWo9efvX7L0bfDllJITXqTUK9zWPQBpFAR7eXXYbxl/JZdAtGiEYpQstXkU68aVAAp/imQlvbOQtqPP0cykg55eARchuozrEom/rsAyZL9hLvldHHXU2XpCmvM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788121035; c=relaxed/simple; bh=qnBuxHRm0ZKAQlNWrNsQLPpAatqA7MRJqtCeBnPdJco=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=jI0GNmxRkz8W8yQ5VVGds3XAl5JhsAFrQ1wZ1hk50UqD7vMVs91x4Q3fMjWKkhE5NGZN6sXLnDmojaMCXMPUhTu63RgoeUnPqdK0ZW1GUHUPQhUhEWU2fP2WqS3BOzg0Y+mU/6h6aq8Iz/8MidkUXpGn+ir62U9e0kK2PBNmr7c= 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=S54bghdt; arc=none smtp.client-ip=209.85.128.53 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="S54bghdt" Received: by mail-wm1-f53.google.com with SMTP id 5b1f17b1804b1-49954b88fffso19072235e9.0 for ; Sun, 30 Aug 2026 13:17:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788121031; x=1788725831; darn=lists.linux.dev; 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=WuLxHG99e7u2lGKea2+n10AjWQDCxmpN+ylQ+0r2DPw=; b=S54bghdta5Qq8/pKC4NiyMEidHvfOvALE8tTYAEwrFd93mC+81nSZrzNvlgikolIFq S+S/cgc2dT2ir92bKz7JkqAwar0XLfMIqB/fYCqdJHS/VE+EdyBpGvJaqrWC+d94Vi3w oWNVxKF5VlkzFAAxrOXFypiO31Fj2JxhjVLUwWmwnhhlWgit3dL37z0mIOpVs7wMze0j hn7TSEafX/NuBe0qF74/IQIgYSMNNoijBZ4Lb/kWlUd0djaiz1UsVghp/QX/FAnbJzvG NGJS6SitMwc+iPOw/6KWmMC9hXatcn5bcNeRU03/lL2iFo8HjUvMIbsQkrBgLuo+aGXv ZmQw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788121031; x=1788725831; 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=WuLxHG99e7u2lGKea2+n10AjWQDCxmpN+ylQ+0r2DPw=; b=qfwUsG7rv+ZZ5/MmFzUXSI7OZ5ncj4ks4mU4O6ghN2ZZeZFRXUrzVNmOcFPWhUO2Oo ENqGRhNuHxo9vfNkuSDi9jJwoEg6GKMAFghq4Q/xvSQqC8s88vbzb7+4rt9Ya3R3KC4t o3HQBAcP3qp4pFbAJmeT4EftRRvRj/Xud9vM3FbXTAc5tO/o4a5CeWfPIQlhOi5KA2Ds yZBGeAQvlrJWPGCIrOHSdpUKVMvp2UcHz6e1Ab4LlR4vQ/qSsFqnUlSPLuFeGuZwLklP J4Izljw/3AxA4OwHjwg1AQy5UV8jEuir6RSvoJW2qjNCWLWYySpfwfj/ks+f3XeDMBHw CvBg== X-Forwarded-Encrypted: i=1; AHgh+RrdbDGDmkCWRwc2eat2gjoGQj6bVoCK6U8ov+Yj7SV0aul2w0LTsXFt830uipneOx0ThN56WA==@lists.linux.dev X-Gm-Message-State: AFuF++lGvvud+RNlcXw9Q0DnT/LZSi4cy91TbgZvYr46UnW+4IkvmKlE p2NzGYkArKaBn+X8ltGFZztWF7KhuKjKCvTNkb+yPBjoTHPAkTL6yZe8 X-Gm-Gg: AR+sD128s9m8NAnapYydNP3xaHxeeGo+MOlKW2NX/7VQyT4pLafr+Okd2V176Kp1ru1 HrjLiLykhKbcQ9OXkclKhlqsgBB9yuUVGL2ZuuhP8cBzeI9ZwZtOZXmjVvwXZ1d3Tgnw8PuSNO5 AFCsM0ZvumrqGcejtAbKr8hxanm8PxikSIZ1OWc5IV9CdvDPVLhZNQmICVc3Y/ebeFFy8XjqISw nNFVTxkI5p+nzBF5j4MqIFGmgL3K7QsOBPQNzobctQWPE3BjqG/WCrMyas0kOMBUDf+64PqSNla Y1z3C2hwV+atHOwqKanumbWoUKvyVp5SvfkxxNFuY5W4sYL+SggXzAwNAesJAKD801Dk+0laniE L1xZxLTpIsd+dBo/7YtqDP6MPbt66tg57anif0f73y5zBGbGcmDASb8MYSgU/w8/2w8sxcX1CS8 P3tbYJdetTOEV48U3lzEmZ68A00R1eRBJz66l9o0BUl+367uUKNsaKSDt4u8l50WVa456Wbem/S uW7c7YwvLD3IA== X-Received: by 2002:a05:600c:c4ac:b0:499:a5fc:2087 with SMTP id 5b1f17b1804b1-49b91c20e36mr318733065e9.6.1788121031326; Sun, 30 Aug 2026 13:17:11 -0700 (PDT) Received: from localhost (ip87-106-108-193.pbiaas.com. [87.106.108.193]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-49cd2922ebdsm100498265e9.3.2026.08.30.13.17.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 30 Aug 2026 13:17:11 -0700 (PDT) From: =?UTF-8?q?G=C3=BCnther=20Noack?= To: =?UTF-8?q?Micka=C3=ABl=20Sala=C3=BCn?= Cc: Matthieu Baerts , Mat Martineau , Geliang Tang , Mikhail Ivanov , mptcp@lists.linux.dev, netdev@vger.kernel.org, linux-security-module@vger.kernel.org, =?UTF-8?q?G=C3=BCnther=20Noack?= Subject: [PATCH 6/6] landlock: Document MPTCP access rights Date: Sun, 30 Aug 2026 22:16:50 +0200 Message-ID: <20260830201650.67050-7-gnoack3000@gmail.com> X-Mailer: git-send-email 2.55.0 In-Reply-To: <20260830201650.67050-1-gnoack3000@gmail.com> References: <20260830201650.67050-1-gnoack3000@gmail.com> Precedence: bulk X-Mailing-List: mptcp@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Describe LANDLOCK_ACCESS_NET_BIND_MPTCP and LANDLOCK_ACCESS_NET_CONNECT_MPTCP in the userspace API documentation. Extend the tutorial to handle the new access rights. Describe MPTCP restrictions in "previous limitations". Signed-off-by: G=C3=BCnther Noack --- Documentation/userspace-api/landlock.rst | 27 +++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/Documentation/userspace-api/landlock.rst b/Documentation/users= pace-api/landlock.rst index 84cb7bf6b3ed..8bd99430514b 100644 --- a/Documentation/userspace-api/landlock.rst +++ b/Documentation/userspace-api/landlock.rst @@ -40,7 +40,7 @@ Filesystem rules and the related filesystem actions are defined with `filesystem access rights`. =20 -Network rules (since ABI v4 for TCP and v10 for UDP) +Network rules (since ABI v4 for TCP, v10 for UDP, and v12 for MPTCP) For these rules, the object is a TCP or UDP port, and the related actions are defined with `network access rights`. =20 @@ -51,7 +51,7 @@ We first need to define the ruleset that will contain our= rules. =20 For this example, the ruleset will contain rules that only allow some filesystem read actions and some specific UDP and TCP actions. Filesystem -write actions and other TCP/UDP actions will be denied. +write actions and other TCP/UDP/MPTCP actions will be denied. =20 The ruleset then needs to handle all these kinds of actions. This is required for backward and forward compatibility (i.e. the kernel and user @@ -83,7 +83,9 @@ to be explicit about the denied-by-default access rights. LANDLOCK_ACCESS_NET_BIND_TCP | LANDLOCK_ACCESS_NET_CONNECT_TCP | LANDLOCK_ACCESS_NET_BIND_UDP | - LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP, + LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP | + LANDLOCK_ACCESS_NET_BIND_MPTCP | + LANDLOCK_ACCESS_NET_CONNECT_MPTCP, .scoped =3D LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET | LANDLOCK_SCOPE_SIGNAL, @@ -140,6 +142,12 @@ version, and only use the available subset of access r= ights: ruleset_attr.handled_access_net &=3D ~(LANDLOCK_ACCESS_NET_BIND_UDP | LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP); + __attribute__((fallthrough)); + case 10 ... 11: + /* Removes LANDLOCK_ACCESS_NET_*_MPTCP for ABI < 12 */ + ruleset_attr.handled_access_net &=3D + ~(LANDLOCK_ACCESS_NET_BIND_MPTCP | + LANDLOCK_ACCESS_NET_CONNECT_MPTCP); } =20 This enables the creation of an inclusive ruleset that will contain our ru= les. @@ -834,6 +842,19 @@ 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. =20 +MPTCP bind and connect (ABI < 12) +--------------------------------- + +Starting with the Landlock ABI version 12, it is possible to restrict MPTCP +bind and connect actions with the ``LANDLOCK_ACCESS_NET_BIND_MPTCP`` and +``LANDLOCK_ACCESS_NET_CONNECT_MPTCP`` access rights. + +Because MPTCP works on the same TCP port number space as plain TCP, it +is recommended that rulesets denying TCP operations should also deny +the equivalent MPTCP operations. In particular, a listening port +created through an ``IPPROTO_MPTCP`` socket is compatible with plain +TCP clients as well. + .. _kernel_support: =20 Kernel support --=20 2.55.0