Re: [bitbake-devel] [PATCH [RFC] 1/2] utils: Add landlock_restrict_network function

Paul Barker <[email protected]> Mon, 15 Jun 2026 09:28:12 +0100
Newsgroups org.openembedded.lists.bitbake-devel
Message-ID <[email protected]>
On Fri, 2026-06-12 at 13:38 +0200, David Nyström wrote:
> Add landlock_restrict_network() which blocks TCP bind/connect using
> Landlock LSM (ABI v4+, kernel 6.7+). Designed to stack with the
> existing disable_network() namespace isolation, covering the case
> where disable_network() is skipped for non-local UIDs.
> 
> Gracefully returns False on older kernels (ABI < 4).
> 
> Signed-off-by: David Nyström <[email protected]>

Hi David,

I think adding this is a good idea, but the code needs a few changes to
ensure it is maintainable.

> ---
>  lib/bb/utils.py | 26 ++++++++++++++++++++++++++
>  1 file changed, 26 insertions(+)
> 
> diff --git a/lib/bb/utils.py b/lib/bb/utils.py
> index 181082c95..1347c29d0 100644
> --- a/lib/bb/utils.py
> +++ b/lib/bb/utils.py
> @@ -2054,6 +2054,32 @@ def disable_network(uid=None, gid=None):
>      with open("/proc/self/gid_map", "w") as f:
>          f.write("%s %s 1" % (gid, gid))
>  
> +def landlock_restrict_network():
> +    """Block TCP bind/connect using Landlock LSM (ABI v4+, kernel 6.7+).
> +    Gracefully skipped on older kernels. Stacks with disable_network()."""
> +
> +    NR_CREATE = 444  # landlock_create_ruleset
> +    NR_SELF   = 446  # landlock_restrict_self
> +    NET_TCP   = 0x3  # BIND_TCP | CONNECT_TCP

We should base these on the names used in the Linux kernel so it's easy
to search for things and compare with example C code in the docs. So,

    NR_landlock_create_ruleset = 444
    NR_landlock_add_rule = 445

    LANDLOCK_ACCESS_NET_BIND_TCP = 0x1
    LANDLOCK_ACCESS_NET_CONNECT_TCP = 0x2

    LANDLOCK_CREATE_RULESET_VERSION = 1

> +
> +    libc = ctypes.CDLL('libc.so.6')
> +
> +    abi = libc.syscall(NR_CREATE, 0, 0, 1)
> +    if abi < 4:
> +        return False

    # Check that landlock is enabled and supports network access
    # restriction (added in ABI version 4)
    abi = libc.syscall(NR_landlock_create_ruleset,
                       0, 0,
                       LANDLOCK_CREATE_RULESET_VERSION)
    if abi < 4:
        logger.debug("System doesn't support disabling network via landlock")
        return False

That's a little more verbose, but much clearer.

> +
> +    attr = struct.pack("QQ", 0, NET_TCP)
> +    buf = ctypes.create_string_buffer(attr)
> +    fd = libc.syscall(NR_CREATE, buf, len(attr), 0)
> +    if fd < 0:
> +        return False

We probably also want a logger.debug() call to log the failure here as
well.

> +
> +    libc.prctl(38, 1, 0, 0, 0)  # PR_SET_NO_NEW_PRIVS

The commit message only describes use of landlock, not no_new_privs. We
need constants for this call as well.

> +    r = libc.syscall(NR_SELF, fd, 0)
> +    os.close(fd)
> +    return r == 0
> +
> +
>  def export_proxies(d):
>      from bb.fetch2 import get_fetcher_environment
>      """ export common proxies variables from datastore to environment """

Thanks,

-- 
Paul Barker
signature.asc (application/pgp-signature, 252 B)
-----BEGIN PGP SIGNATURE-----

iIcEABYKAC8WIQSzjPXf5Y1BDWhU2iCrY1Tsnbr0bgUCai+3nBEccGF1bEBwYmFy
a2VyLmRldgAKCRCrY1Tsnbr0bpsCAQDcS3mR8up3qIDULC2BNelDMWQcK6zP9OQD
cauEld0NTgEAzCqWY55hjhD+wp7S/5rr8ZaB6BxThhlDuBW1DSHVeQQ=
=3v2U
-----END PGP SIGNATURE-----