So SELinux is meant to say "I am going to run this program, and I want to limit it to these things. Landlock / pledge / unveil are meant to say "I am writing this software, and I want my software to never be able to do X". This way developers can reduce the impact of any vulnerabilities in their own software. It is defense in depth on the development side.
SELinux can be used if you don't trust a piece of software. But it is generally applied by people who do not know about the internals of the software. In some sense it is treating the software as a black-box, and limiting what the black-box can do.
Landlock / pledge / unveil are implemented by the developer. If you don't trust the developer's intent, then these are not going to help. However, this is a great way for developers with good intentions to limit the impact of any mistakes they made. Notably, since this system is implemented by the developers, the implementers generally have deep knowledge of how their software works. They can consider the internals of their own software.
I expect that, on balance, systems like these are probably more useful. Black-box approaches are inherently limited, and notably expensive to implement. Moreover, it seems like exploiting bugs is a bigger problem than software that is intentionally malicious. Both of these points mean it makes sense to help developers limit the impact of bugs. It seems cheaper, and it targets an apparently bigger problem.
This is the weird part to me: if you're a developer, you already control how your app works. You can put any kind of restriction you want in place without landlock. You just program it. Don't want user to access a character device? Test if the file you're about to open is a character device, refuse to open it. Don't want your user to open something in /etc/? Check the file path, don't open that file.
My guess is that Landlock and its ilk are basically abstractions to allow programmers to be lazy? I'm still trying to understand the use case because it feels very much like a "webapp firewall", where the developer doesn't want to be bothered with understanding security, so they slap a thing on their app and tell themselves it's secure, when in reality it's still far from secure. Sandboxes get popped all the time.
The problem that solutions like Landlock are trying to solve is "given that this piece of software is going to be compromised, what can we do to mitigate the damage?".
Solutions like Landlock (unlike SELinux/AppArmor/Traditional UNIX) make the additional assumption that if the software gets compromised, the compromise will happen after some set point in its execution (such as after it begins processing untrusted data). Once the program is compromised, the attacker controls the program, not the original programmer. This allows them to bypass any checks programmer put in, since those checks were only ever enforced by the program itself. Landlock solves this by moving enforcement outside of the program and into the kernel. Now, once a program has set up its restrictions, it is no longer possible for that program to bypass them (unless the attacker can also find a kernel exploit).
The idea is "make it impossible for my app to misbehave in certain ways". It is a lot easier to enforce this at the kernel (don't need to check every usage of e.g. open() ). Moreover, there isn't really a way to screw this up through a logic mistake.
But most of all, to say with absolute certainty your software does not allow unintended remote code execution is nigh impossible for anything complex. By adding this, you reduce the possible downsides of any such exploit. It also helps you detect such exploits earlier.
It's similar to the kernel using address layout randomization, compiling with stack-guards, having non-executable stack, etc. It is defense in depth.
First, it should be possible to use both this and SELinux as they are stackable.
The main benefit I see to Landlock over SELinux I see is that it is far more dynamic. With SELinux, you need to know what accesses a program will make when you write the policy. Since Landlock creates the rules at runtime, it can be used in cases where you do not know exactly what it needs to do ahead of time. Obviously, this can also be thought of as a drawback instead of a benefit.
For a toy usecase, consider a hex editor. You want to be able to open and edit any file on the system; however you are concerned that a maliciously crafted could compromise the editor. With Landlock, you can let the user select the file they want to use, then dynamically restrict your permissions before you actually open the file. With SELinux, you would need to give the editor access to the entire system because you do not know ahead of time which file the user will want to access.
Granted, this toy example is simple enough that I could come up with a workable SELinux solution if I had to, but sometimes the application actually knows best what it needs to do.
So the example isn't all that contrived. Run time dropping of privileges is very useful (and common for network daemons etc for a long time - like apache binding port 80, maybe opening log files, then dropping from root to nobody/www data).
But being able to say that "after this point I should never have to open a file" and having that pledge enforced - is really nice.
This is a tool for good programs to behave in the face of bugs, while static measures are a way to enforce access on potentially bad programs.
(not sure if these are possible with landlock)
Example 1: You start `tar` to unpack something to /foo/bar. Ideally you'd tell tar that whatever happens, it cannot write outside of /foo/bar. This is not possible to implement at runtime with selinux, without relabeling the filesystem.
Example 2: You start an app which will open a socket and then never open another connection again (just accept). You could do it with selinux or apparmor by changing context/hat, but you'd have to actually rely on one of them being enabled and setup with appropriate rules. Instead with things like seccomp and other app jails you can say "from now on, deny any listen/connect syscalls".
I always find it weird - linux’s security model obsesses about user accounts and user security. I don’t care about that - I’m the only user! But on the flip side there’s very little effort put in to application / developer specific access control. All applications I run can read, exfiltrate or ransomware all my stuff. That seems reckless and dangerous.
I’m a huge fan of efforts like this - security is never sexy, but it’s extremely important. Let’s make Linux as secure for end users as iOS.
For programs that do not require access to an X11 display, you could also work around the problem of not really trusting the code to not do anything that isn't in your best interest by using `sudo` (or `su` or `setpriv` or ...) to change to an unprivileged account.
Or by having the (non-script) executable file have the SUID bit set, and owned by an unprivileged account on the system.
Hence, kernel devs would like to increase adoption of something that's a little better designed - not SELinux.
IMO that's not true -- Android has done a pretty good job at it.
It allows you to drop privileges so that in the event there is a vulnerability in your application, it cannot be exploited to cause further damage outside the scope of the application's normal operations.