 Hello, everyone. My name is Mikael Salin. I started working on Linux and security long-time job, and particularly on Unlock more than five years ago. At first, it was a personal project attributed by personal needs. I wanted to take control of my own data to be able to know which applications were able to access some specific files. Then I continued this work with my previous employer, the French National Cyber Safety Agency, and now with Microsoft. This is KCD. Can you illustrate what is a common issue with current traditional Linux workstation? If someone steals my laptop while I'm logged in, they can read my email, take my money, and impersonate me to my friends, but they can't install drivers with my permission. That is very true. And you can think about your restaurant pictures, your bank document, your estate key, bgb keys, email, and so on. The thing is, the security for traditional system is designed to protect the system, not the user and his or her data. So what is it about? This talk is not about current protection. Backfixing, security, handling, can attack the situation. All this stuff is very important, of course, but this talk is focused on access control and risk mitigation for user space developers to protect their users. The idea is to limit damage of expected bugs, which may be known or not, fixed by an ongoing update or not. The audience is mainly application developers, system admin status, poor users, hackers, privacy testing people. As a developer, we are responsible for what we put in the end of our user. So here's the plan. This talk focuses on the user log by user space, explaining the rationale behind the design, how that one for what ability are handled, what features are currently available, and what could come next. State of security for application developers. The initial assumption is mainly the trusted computing base, TCB. Abjecting chosen by users or system managerator are trusted, trusted from the user point of view. In a system, unless some user specification must be trusted, otherwise you cannot build on anything. Trust means that we trust the honesty and well intention of the developers. There's multiple and different level of trust and different consequences in case of a breach, particularly on the system, on the user, and on application data. Trust doesn't mean that applications are bulletproof, not safe to use in any condition. And last but not least, supply chains are deemed secure. The conviction is secure enough, and other critical parts of the system are trusted and deemed uncompromising. So here are the threats we are talking. An in-accused and trusted process can become malicious during its lifetime because of bugs exported by attackers or just triggered by users. And application can be misused by user, but this should not be considered malicious, of course, because here we want to protect these users. What is sun mixing? And sun mixing can be used for different meanings, but in this talk, it is used as a security approach, not a binary state. The threat models for sun doting are, well, protecting from vulnerable code maintained by the developer, sorry, self, protecting from malicious third party codes that may be trusted of the case, but sometimes accidents happen. And last but not least, the threat model can be defined by the developers as it fit best for a specific application. Why do we need sun boxing? Perfect security doesn't fit with pragmatic development. Bulletproof and useful software is costly, not only with money, but with time, developer, and skills. And, in fact, it is very difficult to achieve, if ever possible, and the need to add an application. Because we don't want as developer to participate in malicious actions through our software, which might come from an explicit bug, a vulnerability leveraged by an attacker. It is also important to note that the responsibility of huge data is kind of overseen by developers. There's a multiple solution to answer these issues. One of them is the next thing that says multiple ones. First, of course, and what is a reactive solution, which is to fix bugs quickly and pressure dates. But more importantly, there is practical solutions to look for bugs and fix them, of course, to do some testing, to add more tests and use them to use safety languages, libraries, complexion, and so on. And in this case, we should consider our software as potentially malicious and protect the rest of the system from them. That is sandboxing. State of the art. There's here a partial list of non-linux systems. The new sandbox is used by iOS and macOS. There's also the app container using Windows, which is, for example, used in web browsers. Here is the implementing Capsicum, which is a capability system, which is a way to delegate access-wide of physical services. And OpenBSD developed Pledge and Unveil, which enable to, well, create sandboxes, especially for the faster. So this is pretty similar to Linux. But what about Linux? There's a lot of features available in traditional Linux itself. We can identify a set of security features, which are available to the system. And by system here, I mean the system and the setter of a vendor, for example, of an appliance. There is authentication system, firewall with net filter, common access control system, which call the disk-referencing access control system, DAC. There's also mandatory access control system, for example, SNNX, Secum, that may be used by OpenSSH, for example, and no luck. But here, there's only a subset of these features, which are available to the end user. And here, I'm talking about an invalid user, that's a hood user, statistically. So there's still the disk-referencing access control system, Secum and Unlock. And if you want to take a look at what is available to app developers, well, app developer can safely use Secum and no Linux, but the systems may not be independent enough from the application. We can now compare different kind of sandboxing implementation. There's four categories here. The first one is performance. Performance is relative performance, for example, to exchange data between sandboxes or between the OS system in a sandbox, for example, to exchange files. The fine-grained control category is to identify a system that enable to set specific access rights on specific resources, for example, to be able to read files, to list directories, to do specific items, and so on. The embedded policy category means to be able to embed a full standard policy in an application. So that is really targeting app developers. And the unfreeze use category is to identify mechanism that can be used in an unfreeze way, which means that they don't need special Linux capabilities, or system configuration, or S2ID binaries. So when we think about compact monetization, we may think about virtual machine. These are great tools, but they are not what we're looking for sandboxing. There is no easy way to exchange data between virtual machines, except if you rely on the network, or if you share a full block device, or if you share a specific file system between virtual machines or between machine in the host. Well, virtual machine are not designed to do access control with fine-grained control. Well, you cannot embed a virtual machine in an application. And most of the time, running virtual machine requires some privileges. And this thing, as control system, is S1NX. But that may be the same for APAMOS, MAC, or two-way. These are implemented in the Linux scandal, so they are peppermint. There is a fine-grained control way to set permission on processes, chooser, and file. You cannot directly embed a security policy in an application because, well, security policy is designed to be enforced at the system level, most of the time at good time. And S1NX, well, we can work privileges to be able to enforce the security on all the processes of the system. Then there is containers, and especially line spaces. Well, as well, they're designed to be peppermints. There are some issues, potentially, with network line spaces. Well, line spaces are not an access control system per se. So you cannot indicate that a specific file can be accessed with a specific set of actual, for example. You cannot embed policies in an application. And this may require to use, and let's use a line spaces. And this kind of user line spaces come with limitations. And there's also maybe kind of a risk for the kind, because there's a lot of complexity there. And, well, that may not be a good idea. Second BPF is a really interesting feature. In actual, it is a firewall for system calls. So it is designed to be quite patterned. Well, it does not access control system per se. So there's no fine-drained control of accesses to files. It is designed to be embedded in application. So that's really good. And it's designed to be used in an unfinished way. And finally, there is now Landlock. The idea with Landlock is to check all these boxes to be performance, to be able to express fine-drained control for an access control system, to embed a Landlock security policy in an application, and to use it without requiring specific privileges, like FID binaries. But what is Landlock exactly? Landlock is a set of features available since Linux 5.13 to create syntaxes. It is a way to restrict ambient write, according to the kind of semantic, as well as the access to the file system, for a set of processes, because second is not an access control system. Landlock is a way to create safe security sandboxes as new security layers, in addition to the existing system-wide access control. For example, DAG system or S&MX. With Landlock, we can compose access controls from multiple tenants, for example, a stem and a set of developers, or even cloud clients. The limitation is that it is a cloud feature. So there is no use-space semantic here. For example, there is no way to filter any encryption where there are bus communications. This should be implemented in use-space. Here are some use cases. Landlock is interesting for building application sandboxing and sandbox management. With the current features, it is only possible to harden passers, which is really important, because they take interested inputs, most of them done. With the current implementation, it is also possible to restrict application with limited fire renaming and linking. We'll see later specific limitations here. And it's also interesting for monolith application dealing with different level of confidentiality, which may be the case for web browsers dealing with different websites, different domains. And, for example, for traffic services dealing with different user accounts. What could come next will enable to use Landlock for system services in a general way, but also for generic container and sandbox managers, for example, Docker, Papak, or even Finder. The current access control features are focused on the function. The idea is to allow thread and its future children to access a set of file access. There's some declarations, which are kind of common. For example, to be able to execute, read, or write, to fight, to be able to list a directory or remove files from specific set of directories, or be able to create files with basic kind of. There's some limitation with the current implementation. And this is due to the minimum variable product approach, which was used to match the current co-part of Landlock in the container. First limitation is fire rebranding, which means to name or link a file to a different directory. This kind of action is always denied in a sandbox created with Landlock. And kind of similar limitation, there's no way to change the file to them topology from inside a sandbox, for example, to do arbitrary mount points and stuff like that. However, a sandbox could still use the Shrout system code, which may be useful for security purposes. Automatic hierarchy restriction. Because Landlock is designed to be used in an unprolet way, we need to handle composition of layer of policies, which means to have multiple sandbox layers. All application, including shells, are allowed to create their own sandbox, which may create a case of sandbox. For example, if your desktop shell created a sandbox, then you want to launch WebRather, which may create its own sandbox too. Then there is two levels of sandbox. Then there is a hierarchy. And what is important here is that a sandbox can only drop more accesses, not gain more accesses, of course. Otherwise, it would be a privilege escalation. And to avoid other privilege escalation, it is also forbidden to access parent or sibling sandbox processes. Introspection, well, mainly using P-trails of process not in child sandbox or same sandbox, is forbidden. Indeed, introspection could lead to impersonation. This may be used to bypass a sandbox, if you please. Let's see an example. There's the first process here, P1, which may create a new process P2. And then this process P1, one to sandbox itself. So it can create a new sandbox. So it is a sandbox creator which creates a sandbox domain. But in this case, P2, which was created before the sandbox, is not in the sandbox. The sandbox hierarchy is different from the process hierarchy. If P1 now creates a new process, P3, then this process will automatically be restricted by the sandbox domain created by P1. But this P3 process can also create a new sandbox, nested one. And in this case, restriction from the first sandbox and second sandbox are all enforced on P3 and all its new children. For example, here, P4. So now let's see a demo. This is a virtual machine running with slendog enabled. We can see that by looking at the bootlog messages. So I'm logged as root. And I will do this demo as root. But I can do the same with other users. But it is interesting because root, most of the time, can do anything. In his case, I will be able to restrict even the root user. I will use a sandbox manager which is available with the Linux source code. So you can't use it freely. This sandbox manager is a simple helper which can take multiple arguments as an environment Bible. If I run this command, it will launch a shell, bash, which will then only be allowed to access in a read-only way slash bin, slash pro, and so on. And in a read-wide way, slash def null, slash def full, and slash team. OK, we are now in a new shell. Let's look at some properties of this process. You can see here that the new please bit is set. So this does not mean that the log is enabled, but in our case, sandboxer set this bit. We are still in the root directory. However, because it's not listed in the directory, as it will be allowed to have access, we cannot list the content of this directory. And it is the same for the slash directory. We can also try to create a new file on the current directory, and this is not possible. However, we can list the slash team in the directory and create a new file there. Last on the list, we can test if we can impersonate some important processes. For example, any process. And you can see that it is not allowed anymore. If we go out of the sandbox, we can try to set up a group, which may not be a good idea anyway. Thanks to security policy consultation, we gain a lot less control and development. There is no bottleneck because of one global policy, which may, for example, be the case with a global SLNX policy. It's also easier to maintain a set of small policies. And because policies can be embedded within the code, we get security policies tailored to an application. Developers know how it works and what is required. So that makes sense. And of course, this can be kept in think with developing business strategies over time with updates. And this can also enable to dynamically build security policies according to application configuration. And then be able to adapt to this configuration. And finally, because it is a standard user space feature, can be tested like any other features. That is very good. Now, let's go a bit deeper in another. First, a bit of vocabulary. An object in Unlock is a cannot resource. Maybe a file, hierarchy, process, socket, and so on. An action on Unlock. Maybe, for example, to list the content of a directory, to write a file, to create a file, and so on. The Unlock rule is a set of action on Unlock. And the rule set is a set of rules. In Unlock, the subject enforcing a CTVC on itself is the coding process. It's implicit. So how to use Unlock? Well, there's three system calls that are available now. The Unlock create will set this call. The Unlock add will this call. And the Unlock restricts self this call. The first step is to create a rule set. You need to define a set of access that will be denied by default. Then you call the CIS call that creates a rule set. And you gain a new file selector, which is a rule set file selector. The second step is to add rules. Here, we define a path binis rule, which contain a set of allowed accesses. And identify a file hierarchy thanks to a file descriptor. Then we add this rule to the rule set file descriptor thanks to the Unlock add will CIS call. The third step is to enforce this rule set. And because Unlock is an unredaged access control system, we first need to apply it to a system, to a camera, that will not gain new privileges, for example, by executing an SOID binary. This is the key thanks to the new previews command. And then we can enforce the rule set on the coding process thanks to the unlocked access with the rule set file descriptor. There's multiple developer tools. First, Lipsies. There's JLipsy 2.34, and soon there's a Lipsy, which includes the unlocked CIS call ID. Astrace, which is really useful for debugging, and now supports unlocked access call arguments. And there's two interesting libraries, one written in Go and for Go development. And another written in REST for REST developments. And one important point is the compatibility. Canal compatibility. The problem here is that application developer may not be aware of the canal on which the application will run. It is better for users to implement best for security, which means to use available sandbox features as much as possible. But if there is none, well, most of the time you want your application to run anyway. Then I will gain new features of the time, so application must be prepared to run on your canal. The solution was designed in Llanlock C-Schools as backward and forward compatible with previous and future canal versions. Let's see what is backward compatibility. Backward compatibility is, for example, running application developer new canal on an old canal. The solution is to rely on the ability to prop the canal to get the Llanlock API version, which indicates the sandbox features supported by the linker. And then your space library can map can features according to this Llanlock API version. The other side is a future proofness. Running application developed from old canal on a new canal. The solution, well, is mainly imposed by the Llanlock canal API. One must always be compatible with previous version. With Llanlock, we also use extensible structs as C-Schools argument to enable a flexible addition of future features. A struct can be larger than expected, but the unknown fields must contain zeros. This is why we not only add the rule set attribute structure, but also specify the size of the structure. And another important point for future proofness is to add optional flags, which are here. And also to view the canal on map for Llanlock is an end-going default. But here is assembly. In the first time, the idea is to improve canal performance for the current features, but also to add the ability to change the trajectory, to rebound the file like we saw in previous slide. The medium term roadmap is to add all the features with debugging, to extend first-time access control types to address current mutations, and to add the ability to follow a deny listing approach, which is required for some use cases. In the long term, well, this is a lot of features. But some of these features are to add minimal data access control types. And as you will see, create a list of capabilities compatible with Capsicum. Of course, I'm sure you have a long wish list. Please, shit. Let's wrap up. Llanlock empowers developers to add on the application and protect user data by managing tailored and compatible security policies. New canal policies will lift current limitations, improve performance, and bring you some mixing features. There are also high-level Go and Rust libraries, a main list, and a website. Thank you for your attention. And feel free to ask any questions in the chat.