[PATCH 3/6] landlock: Add MPTCP bind and connect access rights

Günther Noack gnoack at google.com
Wed Sep 23 14:27:07 UTC 2026


On Wed, Sep 23, 2026 at 01:04:40PM +0800, Geliang Tang wrote:
> On Mon, 2026-08-31 at 12:09 +0800, Geliang Tang wrote:
> > On Sun, 2026-08-30 at 22:16 +0200, Günther Noack wrote:
> > > 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ünther Noack <gnoack3000 at gmail.com>
> > > ---
> > >  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")
> > >  
> > >  #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 though
> > > + *   they refer to the same port number space. Handling only
> > > + *   %LANDLOCK_ACCESS_NET_BIND_TCP and
> > > %LANDLOCK_ACCESS_NET_CONNECT_TCP leaves
> > > + *   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 not
> > > + *   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 */
> > >  
> > >  /**
> > > 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_AC
> > > CESS_FS)
> > >  
> > > -#define
> > > LANDLOCK_LAST_ACCESS_NET	LANDLOCK_ACCESS_NET_CONNECT_SEND_U
> > > DP
> > > +#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_AC
> > > CESS_NET)
> > >  
> > > 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 <linux/net.h>
> > >  #include <linux/socket.h>
> > >  #include <net/ipv6.h>
> > > +#include <net/mptcp.h>
> > >  
> > >  #include "common.h"
> > >  #include "cred.h"
> > > @@ -53,6 +54,26 @@ int landlock_append_net_rule(struct
> > > landlock_ruleset *const ruleset,
> > >  	return err;
> > >  }
> > >  
> > > +static bool sk_is_mptcp_socket(const struct sock *sk)
> > > +{
> > > +	return sk_is_inet(sk) && sk->sk_type == SOCK_STREAM &&
> > > +	       sk->sk_protocol == IPPROTO_MPTCP;
> > > +}
> > 
> > This helper should be placed in include/net/mptcp.h. I had already
> > implemented one in [1], called sk_is_msk(), to differentiate it from
> > sk_is_mptcp(). If you have no concerns with my implementation, please
> > feel free to pick it up and use it in your series.
> 
> Sorry, let me correct myself. I thought about this more carefully, and
> the ideal place to define sk_is_msk() is in include/net/sock.h, between
> sk_is_tcp() and sk_is_udp():
> 
> static inline bool sk_is_tcp(const struct sock *sk) 
> {
>         return sk_is_inet(sk) &&
>                sk->sk_type == SOCK_STREAM &&
>                sk->sk_protocol == IPPROTO_TCP;
> }
> 
> static inline bool sk_is_msk(const struct sock *sk) 
> {
>         return sk_is_inet(sk) &&
>                sk->sk_type == SOCK_STREAM &&
>                sk->sk_protocol == IPPROTO_MPTCP;
> }
> 
> static inline bool sk_is_udp(const struct sock *sk) 
> {
>         return sk_is_inet(sk) &&
>                sk->sk_type == SOCK_DGRAM &&
>                sk->sk_protocol == IPPROTO_UDP;
> }
> 
> If possible, please fold this code into this patch.

Thank you for the review, Geliang!

I'll include something like this in the next review round.
(We are a bit bottlenecked on doing Landlock code reviews at the moment,
so some delays are unfortunately expected.)

Small question about the function name sk_is_msk(): Is "msk" the right
name for this?  It seems to be used as abbreviation for "MPTCP" in
net/mptcp, but it's also used in net/mctp as an abbreviation, and I
could not find a function name in include/net/mptcp.h which used "msk"
to mean "MPTCP".  Should that say sk_is_mptcp() instead?

Thanks,
—Günther



More information about the Linux-security-module-archive mailing list