landlock-unveil - experimental unveil(2) for Linux

OpenBSD's unveil(2) is a great tool to protect the system in case a program gets compromised. Linux has (almost) nothing like it. You can do something close with seccomp and BPF. But it's waaaay out of the scope for any ordinary developer. Linux 5.13 introduces landlock, which provides more or less the same functionality. But there's no libc function for it (access via systemcall). And the API is not easy to use at the least.

So I wrote llunveil (landlock-unveil[1]), in about a day. It's a thin wrapper around landlock to make it look like unveil(2). With the same API and almost the same semantics. You give it 2 strings as parameter. First is the path to a directory or file. Second is the permissions. rwxc for read, write, execute and create. Finally, unlike unveil(2) which starts protection immediately, you can call llunveil(NULL, NULL) to commit the protection.

// create a macro called `unveil`. Prevent symbol conflict
#include <llunveil.h>

unveil("/home/user/", "r");
// Not activated until calling unveil(NULL, NULL);
assert(fopen("/tmp/some_text.txt", "r") != NULL);

unveil(NULL, NULL); // activate!
assert(fopen("/tmp/some_text.txt", "r") == NULL);

For me, I use this in my blog/gemlog. In case there's a directory traversal bug, or someone found a buffer overflow and ROPed into the system.

#if defined(__linux__) || defined(__OpenBSD__)
// Lockdown the server to only access the files in the document directory
// after done initializing.
unveil(drogon::app().getDocumentRoot().c_str(), "r");
unveil(drogon::app().getUploadPath().c_str(), "rwc");
unveil(nullptr, nullptr);

// Start the server

That's it. unveil is really simple to use. I'm gonna be the first one to say. This is experimental code. It needs many updates to be as effectice and correct as unveil. And I wish someone could implement pledge(2) for Linux. I tried it. It's tough. But I think an collaborative effort could make it. And it'll be worth it.

I hope people would find this useful and start using and experiment with it. Hopefully one day unveil will also be standard on Linux.

Author's profile. Photo taken in VRChat by my friend Tast+
Martin Chang
Systems software, HPC, GPGPU and AI. I mostly write stupid C++ code. Sometimes does AI research. Chronic VRChat addict

I run TLGS, a major search engine on Gemini. Used by Buran by default.

  • marty1885 \at
  • Matrix:
  • Jami: a72b62ac04a958ca57739247aa1ed4fe0d11d2df