Re: [RFC PATCH 5/9] Define user structure for events and responses.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 3/12/25 11:49, Mickaël Salaün wrote:
On Tue, Mar 11, 2025 at 11:18:49PM +0000, Tingmao Wang wrote:
On 3/11/25 19:28, Mickaël Salaün wrote:
On Mon, Mar 10, 2025 at 12:39:04AM +0000, Tingmao Wang wrote:
On 3/6/25 03:05, Tingmao Wang wrote:
[...]
This is also motivated by the potential UX I'm thinking of. For example,
if a newly installed application tries to create ~/.app-name, it will be
much more reassuring and convenient to the user if we can show something
like

       [program] wants to mkdir ~/.app-name. Allow this and future
       access to the new directory?

rather than just "[program] wants to mkdir under ~". (The "Allow this
and future access to the new directory" bit is made possible by the
supervisor knowing the name of the file/directory being created, and can
remember them / write them out to a persistent profile etc)

Another significant motivation, which I forgot to mention, is to auto-grant
access to newly created files/sockets etc under things like /tmp,
$XDG_RUNTIME_DIR, or ~/Downloads.

What do you mean?  What is not currently possible?

It is not currently possible with landlock to say "I will allow this
application access to create and open new file/folders under this directory,
change or delete the files it creates, but not touch any existing files".
Landlock supervisor can make this possible (keeping track via its own state
to allow future requests on the new file, or modifying the domain if we
support that), but for that the supervisor has to know what file the
application tried to create, hence motivating sending filename.

This capability would be at least inconsistent, and dangerous at worse,
because of policy inconsistencies over time.  A sandbox policy should be
seen over several invocations of the same sandbox.  See related deny
listing issues: https://github.com/landlock-lsm/linux/issues/28

Let's say a first instance of the sandbox can create files and access
them, but not other existing files in the same directory.  A second
instance of this sandbox would not be able to access the files the same
application created, so it will not be able to clean them if required.
That could be OK in the case of the ~/Downloads directory but I think it
would be weird for users to not be able to open their previous
downloaded files from the browser, whereas it was allowed before.

For such use case, if we want to avoid new browser instances to access
old downloaded files, I'd recommand to create a new download directory
per browser/sandbox launch.


I had some more thoughts on this - In terms of inconsistency / security implications of such a supervisor behaviour, I think I can identify two aspects:

First is policy inconsistency over different instances / restarts (like the example you mentioned about not being able to open previously downloaded files). I think in this case, this is fine and would not be dangerous, because it will only result in extra permission requests (potentially the user having to allow the access again, or maybe the sandboxer can remember it from last time and auto-allow it internally). (whereas an inconsistent deny rule is more problematic because it opens up the access on the next restart / for other instances, if done wrong)

The second problem is that if the supervisor wants to automatically permit further access to the newly created files, it can only do so by remembering and comparing file names, since the new inode doesn't exist yet*, and so even with mutable domains there is nothing to attach new rules to. This means that there is a potential for files/dirs to be moved/created/linked behind its back onto the destination by someone outside the sandbox, and this may result in the supervisor unintentionally allowing access to files it doesn't want to? (like, if it approves the request based solely on the belief that the file is new)

*: Assuming we don't want to lock the parent dir forever until the supervisor replies.

While this does seem like a problem, I'm not sure how practical it would be to exploit, since any further action by the sandboxed app itself on the destination can/would also be blocked by landlock, and in some sense we're already dead if the sandboxed app can somehow convince something outside of the sandbox to create arbitrary links or move arbitrary files to a destination path that would appear to belong legitimately to the malicious app. But this does raises more questions than I initially thought, and shows how an overly creative supervisor may shoot itself in the foot -- when filenames are involved in permission decisions the semantics starts becoming a bit fuzzy, and is different from current landlock which is entirely inode-based.

With that said, I would still really like to make the mentioned UX possible tho - allowing an app to create a file/dir and any further access to it as well _feels very intuitive_, and is especially convenient for cases where the first launch of an app is sandboxed. But I do recognize that this capability is less important for self-sandbox scenarios (since the supervisor can pre-create all the scaffolding directories it knows the app would need).

I have some thoughts, none of which are perfect, and not doing any of them is also an option (i.e. the supervisor just have to decide whether to give permission to create files of arbitrary names or not, and can't find out about any new files/dirs created (unless with some other Linux mechanism)):

1. Maybe there can be a mechanism for the supervisor to be invoked post-creation (passing in a fd for the new file directly), then it can prompt the user and either allow and optionally add the new inode to the mutable domain, or it can "undo" the operation by deleting the new file/dir then reject the "request". I recognize that this is a bit weird and is also only applicable to supervise mode, but it might be acceptable since merely creating an empty file/dir is relatively harmless (ignoring symlinks and device nodes for the moment).

2. The supervisor can create the file/dir/device-node/symlink on behalf of the sandboxed app, if we can pass all the relevant arguments to it in the request. Then there needs to be a mechanism for it to tell the kernel to return a custom error code to the invoking program.
(seccomp-unotify deja vu)

3. We find a way to implement "allow once" which will only allow this particular create request, with this name. At least this way the supervisor can implement the above mentioned feature, with the caveat mentioned above.

(For other's reference, I had a discussion with Mickaël and it looks like we will want to have mutable domains and base the implementation of landlock supervise off that, returning a -ERESTARTNOINTR from the hook when access is allowed. I will write up the discussion tomorrow / later)



(I can see this kind of policy being applied to dirs like /tmp or my
Downloads folder. $XDG_RUNTIME_DIR is also a sensible place for this
behaviour due to the common pattern of creating a lock/pid file/socket
there, although on second thought a GUI sandbox probably will want to create
a private copy of that dir anyway for each app, to do dbus filtering etc)

An $XDG_RUNTIME_DIR per sandbox looks reasonable, but in practice we
also need secure proxies/portals to still share some user's resources.
This part should be implemented in user space because the kernel doesn't
know about this semantic (e.g. DBus requests).





[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux