25 comments

[ 3.0 ms ] story [ 43.5 ms ] thread
So like using seccomp with a whitelist (fairly easy to do) with per-object access rights.

I'd love to see a comparison of landlock to restricted containers.

So it works also by using some cli utility to run my software for example?
LandLock is a Minor LSM intended for software developers. They incorporate it into their source code to limit where the programs may read/write. Here's a simple Go example:

    package main

    import (
     "flag"
     "fmt"
     "github.com/landlock-lsm/go-landlock/landlock"
     "io/ioutil"
     "log"
     "os"
    )

    // simple program that demonstrates how landlock works in Go on Linux systems.
    // Requires 5.13 or newer kernel and .config should look something like this:
    // CONFIG_SECURITY_LANDLOCK=y
    //  CONFIG_LSM="landlock,lockdown,yama,loadpin,safesetid,integrity,apparmor,selinux,smack,tomoyo"
    func main() {
     var help = flag.Bool("help", false, "landlock-example -f /path/to/file.txt")
     var file = flag.String("f", "", "the file path to read")

    flag.Parse()
     if *help || len(os.Args) == 1 {
      flag.PrintDefaults()
      return
     }
    
    // allow the program to read files in /home/user/tmp
     err := landlock.V1.RestrictPaths(landlock.RODirs("/home/user/tmp"))
     if err != nil {
     log.Fatal(err)
     }
    
    // attempt to read a file
     bytes, err := ioutil.ReadFile(*file)
     if err != nil {
     log.Fatal(err)
     }
    
    fmt.Println(string(bytes))
    }
Interesting they added new syscalls, instead of handling configuration via /sys like with SELinux and AppArmor. I suppose it must be because of the no privilege principle.

Can sysadmins disable access to Landlock syscalls via seccomp? Not that I can see why they'd want to, just wondering how this is layered.

I suppose the problem might be if the system has been set up at some earlier point in time to whitelist a set of syscalls for a process and, as Landlock is newer, its syscall numbers won't be included. A program that has been updated to use Landlock while a seccomp policy that predates Landlock is applied would presumably be terminated with SIGSYS due to this?

How can a program determine if Landlock is present without just trying the syscalls and seeing if they work?

I am puzzled by this:

> A official c library doesn’t exist yet unfortunately, but there’s several out there you can try.

> Landlock is a Linux Security Module (LSM) available since Linux 5.13

Since when is not a C API the first and foremost interface for developers when it comes to Linux kernel stuff?

Because C is not the primary interface language for kernel syscalls. There is no language specific primary interface as the syscall is the primary interface and it is language agnostic. This is one of Linux's great strengths, a stable syscall API that doesn't rely on a system library.
What's the status of Landlock in container runtimes? A quick search makes it seem like CRIs are trying to define their own custom Landlock interface.

That will inevitably lag behind what the kernel supports, but more importantly I don't foresee many container image packagers, Helm recipe maintainers and other YAML wranglers getting into the business of maintaining a Landlock sandbox policy.

It makes sense for an application to use Landlock directly to sandbox some parser or other sensitive component. But if the CRI just blocks the syscalls by default, no infra person is going to take on the maintainance of their own sandbox policy for every app. The app will just see ENOSYS and not be sandboxed.

I might be missing the whole idea here, but I really don't see why we need some custom layer in the middle instead of having container runtimes let the security syscalls through?

For a cool practical example, check out Nomad's (flexible workload orchestrator) exec2 task driver: https://github.com/hashicorp/nomad-driver-exec2

It allows running non/semi-trusted workloads with isolation. Pretty useful to onboard applications into a proper scheduler with all bells and whistles without having to containerise, but still with decent levels of isolation between them.

i have zero experience with linux system programming so i'm probably missing something, but what's the point of an application restricting itself at runtime? if the application were compromised in some way, wouldn't it simply un-restrict itself?
I've been messing with sandboxing using "bwrap" for random itch.io games I download to play and it isn't trivial to get it working with least privileges. I have so far been unable to get "Microlandia" to run, but other Unity games are running just fine under "bwrap". I am excited to see more Landlock tools emerge that make this task easier.

- https://github.com/containers/bubblewrap

- https://codeberg.org/dannyfritz/dotfiles/src/commit/38343008...

- https://explodi.itch.io/microlandia

As a noob in this space, why is this needed when every job already runs inside a VM or a container? Again, a noob so please bear with me
Medical device developer here: this is precisely the kind of work we need in highly regulated industries. We use an internal version of something with a similar API to manage our critical threads/processes. Keep it up!
I'm very slowly taking an interest in Linux security as I'm starting to disentangle from my Mac and preparing to get a Linux workstation and make it my forever home for personal and work computing. So I'm very new to all this.

My questions are:

- How does this help with malware? I want to craft an environment where any program trying to read f.ex. anything inside ~/.ssh is automatically denied. I don't want a malicious build script to exfiltrate all my sensitive data!

- It seems that this software is well-positioned for us to write application launchers with, is that true? If so, well, I like the idea but it seems too manual.

Maybe I'm looking at the wrong thing. I strongly prefer deny-by-default in an invisible manner i.e. my system to refuse most requests to access this or that. Not opting in to it. Bad actors will not graciously limit their own program with Landlock. They'll try to get anything before I can even blink my eyes.

I feel I'm missing crucially important context. Can somebody help?

If you're trying to deny internet access to a program, beware that landlock only restricts tcp sockets. Programs are free to setup udp or just raw sockets.
Well you need root access, or at least the CAP_NET_RAW capability to use raw sockets. UDP seems pretty bad though.
Thanks for sharing.

I did not know of this and I am looking for simple ways to isolate processes for multiple reasons. I am building a coding agent, https://github.com/brainless/nocodo, that runs (headless) on a Linux instance. Generated code is immediately available for demo.

I am new to isolation and not looking for a container based approach. Isolation from a security standpoint but I do not know enough. This approach looks like a great start for me.

Wait until the author discovers FreeBSD’s Capsicum. I believe it’s superior to most of the APIs provided by other major OSs.
I've used Landlock to detect and stop unwanted telemetry. I wrote some C that stopped networking except to accept connections on a single port, no outgoing connections and no accepting connections on any other port.

`dmesg` shows the connections it blocks (I think this is maybe the audit feature). I used an example sandboxer.c as a base (https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux...) except I just set mine up to not touch file restricting, just networking so that it has that one whitelisted incoming port.

    ./network-sandboxer-tool 8000 some-program arg1 arg2 etc.
I like it because it just works as an unprivileged usermode program without setting anything up. A tiny C program. It works inside containers without having to set up any firewalls. Aside from having to compile a small C program, there is little fuss. I found the whole Landlock thing trying to find out alternatives to bubblewrap because I couldn't figure out how to do the same thing in bwrap conveniently.

The "unprivileged" in "Landlock: unprivileged access control" for me was the selling point for this use case.

I don't consider this effective against actively adversarial programs though.

its kind of funny to say: "A official c library doesn’t exist yet unfortunately, but there’s several out there you can try." if its litterally in the standard library...

https://man7.org/linux/man-pages/man7/landlock.7.html

But i suppose i am missing somehting then people would like...

What would you want an library to do here? abstract over it to make it easier? (relatively simple api already)

legit question, not trying to poke anyone here.. trying to find out what ppl expect from libraries which wrap around these syscalls or stdlib things.

It's not all roses unfortunately. See discussions https://github.com/landlock-lsm/linux/issues/28 and https://lore.kernel.org/all/CAG48ez1O0VTwEiRd3KqexoF78WR+cmP...

Even the example code builds a somewhat questionable 'sandbox' that hits a problem discussed in those threads. Say we're ok with an app having r-w access to home except for a couple of places such as ~/.ssh. Now you could try to add a rule to exclude access to ~/.ssh, but the security object must exist when the policy is being established (the rules refer to directories by fds). As such, no .ssh directory, means not rules denying access. You start a sandboxed app thinking you've set up a tight sandbox, at some point ~/.ssh gets created, and now the untrusted app can read your ssh keys.

Valid concern. Maybe this can be addressed with a patch...

Seems solvable by perhaps storing paths that don't exist yet on the filesystem in landlock's red black tree.

Workaround might be creating .ssh ahead of time

This approach is stupid.

That's like relying on criminals to cuff themselves when they have committed a crime.

Not really. It's more like wearing seatbelts: the car is not supposed to crash, but in case something unforeseen happens, please don't let the passengers exit through the windshield.