linux
linux copied to clipboard
Restrict executing on `memfd`
We can run executable files that are only given read but not execute access by copying them into a memfd and then call fexecve on the file descriptor. Should we restrict this?
The initial goal of Landlock is to control access to data, but yes, it makes sense to have more control over an execution environment.
We could leverage the scoped field in struct landlock_ruleset_attr (see #7) and add a dedicated flag to deny memfd execution if it was created in a Landlock domain with such flag set.
See chromeOS's memfd restriction: chromiumos_bprm_creds_for_exec().
A more generic approach would be to deny any memory from being mapped as executable, except when mmaping a file with the LANDLOCK_ACCESS_FS_EXECUTE right. This can be implemented with security_mmap_file() and security_file_mprotect().
A more generic approach would be to deny any memory from being mapped as executable, except when
mmaping a file with theLANDLOCK_ACCESS_FS_EXECUTEright. This can be implemented withsecurity_mmap_file()andsecurity_file_mprotect().
That is more generic and powerful, indeed.
Such an implementation would also change Landlock's hook_file_alloc_security() to remove the LANDLOCK_ACCESS_FS_EXECUTE right by default (when the caller's domain enforces such restriction). A new implementation of the security_bprm_creds_for_exec() hook would then check each FD's executability.
Hi there! I was looking into memfd related usage b/w apps in Android and somehow ended up here. I believe I can probably take a stab at this 🙂 . Afaik, an additional scope flag, LANDLOCK_SCOPE_MEMFD_EXECUTE can be added. From what I could gather from the docs, the scope pertains to domain-associated IPC restrictions b/w tasks.
As suggested here, memfd restrictions would need to consider both the creating process and the process attempting to execute/map the memory. With security_mmap_file() and security_file_mprotect(), I was thinking of getting the file associated domain (using file->f_cred), and then we can resolve scope using domain_is_scope(current_domain, file_domain, memfd_scope).
Thoughts? @l0kod
Commenting here from a "user" perspective (crablock).
Restricting W&X has three domains.
- memory. Creating
W&Xmemory withmmap/mprotect-family can be blocked withprctl(PR_SET_MDWE, PR_MDWE_REFUSE_EXEC_GAIN). - filesystem. Accessing filesystems in a
W&Xway can be blocked withMOUNT_ATTR_RDONLY/MOUNT_ATTR_NOEXECor Landlock (even if creating a policy is not trivial with symlinks, bind-mounts, ...). - memfd, the thing in-between, 50% memory and 50% filesystem. Creating
memfds withoutMFD_NOEXEC_SEALcan be blocked with seccomp-bpf at the cost of breaking old programs. Or with the pid namespacedvm.memfd_noexecsysctl which at level2deniesMFD_EXECand implicitly addsMFD_NOEXEC_SEAL. Unfortunately settingvm.memfd_noexecin a pid-namespace requiresCAP_SYS_ADMINin the initial user-namespace rather than the owning user-namespace. Maybe Landlock could do the same asvm.memfd_noexec=2but unprivileged, this would keep old programs working.
I sent in a v1: https://lore.kernel.org/all/[email protected]/
Hi @l0kod . Any updates on the review? 🙂 Honestly, there is stuff I would change from the patch series. But just wanted your thoughts if I was on the right track or not.
Btw: I had also raised another patch series [1] based on my understanding of how scoping works in landlock. Please have a look at it as well if you get the time 😅
[1] - Scoping Abstractions https://lore.kernel.org/all/[email protected]/
Hi, thanks for the reminder, I'll review them tomorrow.