From 9a8ed15ce22472fe0363e33738b4317d06b13c3a Mon Sep 17 00:00:00 2001 From: Matthieu Buffet Date: Thu, 11 Jun 2026 18:21:01 +0200 Subject: landlock: Add UDP bind() access control MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for a first fine-grained UDP access right. LANDLOCK_ACCESS_NET_BIND_UDP controls the ability to set the local port of a UDP socket (via bind()). It will be useful for servers (to start receiving datagrams), and for some clients that need to use a specific source port (e.g. mDNS requires to use port 5353) For obvious performance concerns, access control is only enforced when configuring sockets, not when using them for common send/recv operations. Bump ABI to allow userspace to detect and use this new right. Signed-off-by: Matthieu Buffet Link: https://patch.msgid.link/20260611162107.49278-2-matthieu@buffet.re [mic: Fix comment formatting] Signed-off-by: Mickaël Salaün --- include/uapi/linux/landlock.h | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/landlock.h b/include/uapi/linux/landlock.h index 10a346e55e95..f2927681e92d 100644 --- a/include/uapi/linux/landlock.h +++ b/include/uapi/linux/landlock.h @@ -200,10 +200,10 @@ struct landlock_net_port_attr { * (also used for IPv6), and within that range, on a per-socket basis * with ``setsockopt(IP_LOCAL_PORT_RANGE)``. * - * A Landlock rule with port 0 and the %LANDLOCK_ACCESS_NET_BIND_TCP - * right means that requesting to bind on port 0 is allowed and it will - * automatically translate to binding on a kernel-assigned ephemeral - * port. + * A Landlock rule with port 0 and the %LANDLOCK_ACCESS_NET_BIND_TCP or + * %LANDLOCK_ACCESS_NET_BIND_UDP right means that requesting to bind on + * port 0 is allowed and it will automatically translate to binding on a + * kernel-assigned ephemeral port. */ __u64 port; }; @@ -373,10 +373,16 @@ struct landlock_net_port_attr { * port. Support added in Landlock ABI version 4. * - %LANDLOCK_ACCESS_NET_CONNECT_TCP: Connect TCP sockets to the given * remote port. Support added in Landlock ABI version 4. + * + * And similarly for UDP port numbers: + * + * - %LANDLOCK_ACCESS_NET_BIND_UDP: Bind UDP sockets to the given local + * port. Support added in Landlock ABI version 10. */ /* 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) /* clang-format on */ /** -- cgit v1.2.3 From e61247a2e694d17236149135b2d22f0f7d19578c Mon Sep 17 00:00:00 2001 From: Matthieu Buffet Date: Thu, 11 Jun 2026 18:21:02 +0200 Subject: landlock: Add UDP send+connect access control MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for a second fine-grained UDP access right. LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP controls the ability to set the remote port of a socket (via connect()) and to specify an explicit destination when sending a datagram, to override any remote peer set on a UDP socket (e.g. in sendto() or sendmsg()). It will be useful for applications that send datagrams, and for some servers too (those creating per-client sockets, which want to receive traffic only from a specific address). Similarly as for bind(), this access control is performed when configuring sockets, not in hot code paths. Add detection of when autobind is about to be required, and deny the operation if the process would not be allowed to call bind(0) explicitly. Autobind can only be performed in udp_lib_get_port() from code paths already controlled by LSM hooks: when connect()ing, sending a first datagram, and in some splice() EOF edge case which, afaiu, can only happen after a remote peer has been set. This invariant needs to be preserved to keep bind policies actually enforced. Signed-off-by: Matthieu Buffet Link: https://patch.msgid.link/20260611162107.49278-3-matthieu@buffet.re [mic: Add quick return for non-sandboxed tasks, fix sa_family dereferencing, fix comment formatting] Signed-off-by: Mickaël Salaün --- include/uapi/linux/landlock.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/landlock.h b/include/uapi/linux/landlock.h index f2927681e92d..811ec77f9105 100644 --- a/include/uapi/linux/landlock.h +++ b/include/uapi/linux/landlock.h @@ -378,11 +378,34 @@ struct landlock_net_port_attr { * * - %LANDLOCK_ACCESS_NET_BIND_UDP: Bind UDP sockets to the given local * port. Support added in Landlock ABI version 10. + * - %LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP: Set the remote port of UDP + * sockets to the given port, or send datagrams to the given remote port + * ignoring any destination pre-set on a socket. Support added in + * Landlock ABI version 10. + * + * .. note:: Setting a remote address or sending a first datagram + * auto-binds UDP sockets to an ephemeral local source port if not + * already bound. To allow this if both %LANDLOCK_ACCESS_NET_BIND_UDP + * and %LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP are handled, you need to + * either: + * + * - use a socket already bound to a port before the ruleset started + * being enforced; + * - or grant %LANDLOCK_ACCESS_NET_BIND_UDP on port 0, meaning "any + * port in the ephemeral port range"; + * - or grant %LANDLOCK_ACCESS_NET_BIND_UDP on a specific port, and + * call :manpage:`bind(2)` on that port before trying to + * :manpage:`connect(2)` or send datagrams. + * + * .. 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. */ /* 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) /* clang-format on */ /** -- cgit v1.2.3 From 29752205db5ff1793437b352c9e343b8e41fb184 Mon Sep 17 00:00:00 2001 From: Tingmao Wang Date: Fri, 12 Jun 2026 02:48:48 +0100 Subject: landlock: Add API support and docs for the quiet flags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds the UAPI for the quiet flags feature (but not the implementation yet). Even though currently LANDLOCK_ADD_RULE_QUIET only affects audit logging, in the future this can also be used as part of a supervisor mechanism, where it will also suppress denial notifications on a per-object basis. Thus the name is deliberately generic, as opposed to e.g. LANDLOCK_ADD_RULE_LOG_QUIET. According to pahole, even after adding the struct access_masks quiet_masks in struct landlock_hierarchy, the u32 log_* bitfield still only has a size of 2 bytes, so there's minimal wasted space. Assisted-by: GitHub-Copilot:claude-opus-4.8 Signed-off-by: Tingmao Wang [mic: Update date, fix comment formatting] Link: https://patch.msgid.link/031184748a8e74c0bb02f1fa13d7a3f10918c627.1781228815.git.m@maowtm.org Signed-off-by: Mickaël Salaün --- include/uapi/linux/landlock.h | 60 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'include/uapi/linux') diff --git a/include/uapi/linux/landlock.h b/include/uapi/linux/landlock.h index 811ec77f9105..7ffe2ef127ee 100644 --- a/include/uapi/linux/landlock.h +++ b/include/uapi/linux/landlock.h @@ -32,6 +32,19 @@ * *handle* a wide range or all access rights that they know about at build time * (and that they have tested with a kernel that supported them all). * + * @quiet_access_fs and @quiet_access_net are bitmasks of actions for which a + * denial by this layer will not trigger a log if the corresponding object (or + * its children, for filesystem rules) is marked with the "quiet" bit via + * %LANDLOCK_ADD_RULE_QUIET, even if logging would normally take place per + * landlock_restrict_self() flags. @quiet_scoped is similar, except that it + * does not require marking any objects as quiet - if the ruleset is created + * with any bits set in @quiet_scoped, then denial of such scoped resources will + * not trigger any log. These 3 fields are available since Landlock ABI version + * 10. + * + * @quiet_access_fs, @quiet_access_net and @quiet_scoped must be a subset of + * @handled_access_fs, @handled_access_net and @scoped respectively. + * * This structure can grow in future Landlock versions. */ struct landlock_ruleset_attr { @@ -51,6 +64,20 @@ struct landlock_ruleset_attr { * resources (e.g. IPCs). */ __u64 scoped; + /** + * @quiet_access_fs: Bitmask of filesystem actions which should not be + * logged if per-object quiet flag is set. + */ + __u64 quiet_access_fs; + /** + * @quiet_access_net: Bitmask of network actions which should not be + * logged if per-object quiet flag is set. + */ + __u64 quiet_access_net; + /** + * @quiet_scoped: Bitmask of scoped actions which should not be logged. + */ + __u64 quiet_scoped; }; /** @@ -69,6 +96,39 @@ struct landlock_ruleset_attr { #define LANDLOCK_CREATE_RULESET_ERRATA (1U << 1) /* clang-format on */ +/** + * DOC: landlock_add_rule_flags + * + * **Flags** + * + * %LANDLOCK_ADD_RULE_QUIET + * Together with the quiet_* fields in struct landlock_ruleset_attr, + * this flag controls whether Landlock will log audit messages when + * access to the objects covered by this rule is denied by this layer. + * + * If logging is enabled, when Landlock denies an access, it will + * suppress the log if all of the following are true: + * + * - this layer is the innermost layer that denied the access; + * - all accesses denied by this layer are part of the quiet_* fields + * in the related struct landlock_ruleset_attr; + * - the object (or one of its parents, for filesystem rules) is + * marked as "quiet" via %LANDLOCK_ADD_RULE_QUIET. + * + * Because logging is only suppressed by a layer if the layer denies + * access, a sandboxed program cannot use this flag to "hide" access + * denials, without denying itself the access in the first place. + * + * The effect of this flag does not depend on the value of + * allowed_access in the passed in rule_attr. When this flag is + * present, the caller is also allowed to pass in an empty + * allowed_access. + */ + +/* clang-format off */ +#define LANDLOCK_ADD_RULE_QUIET (1U << 0) +/* clang-format on */ + /** * DOC: landlock_restrict_self_flags * -- cgit v1.2.3