[PATCH RFC -next 00/12] landlock: Add READ_METADATA and WRITE_METADATA access rights
Cai Xinchen
caixinchen1 at huawei.com
Mon Sep 28 06:52:02 UTC 2026
Thank you for review!
I will link the feature request
(https://github.com/landlock-lsm/linux/issues/11) in the v2 cover letter.
For https://github.com/landlock-lsm/linux/issues/18, the current
READ_METADATA cannot solve this problem, and I don't have a good idea
for now.
For path_* rename, I'd rather keep the inode_* names:
* There is precedent for the mismatch: the inode_getattr hook
upstream already takes a "const struct path *" (this series just
aligns the other metadata hooks with it).
* The path_* prefix has an established meaning in the LSM hook
interface: it denotes the pathname-based (TOMOYO/AppArmor-style)
hooks that are invoked at the VFS path level *before* the
corresponding inode_* hook, as a paired, duplicate check
serving a different class of LSMs. For example, a chmod(2)
currently runs security_path_chmod() (fs/open.c, for TOMOYO and
AppArmor) and then, via notify_change(),
security_inode_setattr() (for SELinux, Smack and now Landlock);
vfs_mknod() similarly calls both security_path_mknod() and
security_inode_mknod(). Renaming inode_setattr to
path_setattr would put two path_-prefixed hooks with different
call contracts into the same syscall, and path_chown(path,
uid, gid) next to a path_setattr(path, attr) would read as a
redundant pair, even though they belong to different hook
families. Landlock itself already uses the path_* family for
its real path-level hooks (e.g. path_truncate for the TRUNCATE
right), so mixing renamed inode hooks into that prefix would
also blur its own hook table.
* If the consensus is that these hooks should be renamed, I think
that should be a standalone, tree-wide rename series (including
inode_getattr), so that BPF programs only break once instead of
twice.
On 9/26/2026 4:27 PM, Günther Noack wrote:
> On Thu, Sep 24, 2026 at 06:48:19PM +0800, Cai Xinchen wrote:
>> This series adds two new Landlock filesystem access rights,
>> LANDLOCK_ACCESS_FS_READ_METADATA and LANDLOCK_ACCESS_FS_WRITE_METADATA,
>> which control access to file and directory metadata such as inode
>> attributes (mode, ownership, timestamps), extended attributes and POSIX
>> ACLs. It picks up the work from the "landlock: add chmod and chown
>> support" series [1] and follows the coarse-grained grouping discussed in
>> that thread [2]: instead of separate chmod/chown rights, metadata
>> operations are grouped into one read and one write right.
>>
>> Landlock evaluates access rights on a per-path basis, but the metadata
>> related LSM hooks (inode_getattr, inode_setattr, inode_setxattr,
>> inode_getxattr, inode_listxattr, inode_removexattr, inode_set_acl,
>> inode_get_acl, inode_remove_acl) only receive the dentry of the accessed
>> object. Patches 1-7 therefore first pass struct path instead of dentry
>> through the metadata-related VFS helpers and LSM hooks. This is a pure
>> refactoring with no behavior change, split so that every patch builds
>> and works on its own:
>>
>> 1: notify_change() and its callers
>> 2: inode_setsecctx hook (must come before 3: the SELinux and Smack
>> implementations call __vfs_setxattr_locked internally)
>> 3: xattr helpers, which also drops a redundant EVM xattr size sanity
>> check whose vfs_getxattr() call only has a dentry and therefore
>> cannot be migrated to the new path-based signature
>> 4: POSIX ACL helpers
>> 5: inode_setattr hook
>> 6: inode xattr hooks
>> 7: inode POSIX ACL hooks
>>
>> Two deliberate scoping decisions for this refactor:
>>
>> - The hooks consistently take struct path rather than struct file. The
>> VFS call sites involved (chmod(2), chown(2), utimensat(2), xattr(2)
>> and ACL syscalls) operate on paths, and several of them (lstat(2),
>> lchown(2), llistxattr(2), ...) have no struct file to begin with.
>>
>> - struct inode_operations->setattr still receives (idmap, dentry, attr).
>> Only the VFS boundary (notify_change()) and the LSM hook layer see the
>> path, which keeps the refactor contained to fs/attr.c and the LSM
>> infrastructure instead of touching every filesystem.
>>
>> Patches 8-12 then implement the new rights, their tests, the sandboxer
>> sample and the documentation. Semantics:
>>
>> - READ_METADATA covers stat(2) and friends, getxattr(2) and friends,
>> listxattr(2) and friends, and POSIX ACL reads.
>> - WRITE_METADATA covers chmod(2), chown(2), utimensat(2), setxattr(2),
>> removexattr(2) and friends, and POSIX ACL set and remove.
>> - Only explicit metadata changes requested by user space are restricted.
>> Implicit changes performed by the kernel (e.g. timestamp updates on
>> write(2), size changes on truncate(2)) are not, and neither are
>> chmod(2)/chown(2) calls that change nothing (e.g. chown(2) with
>> (-1, -1), which never reaches the hook), matching the SELinux
>> inode_setattr behavior.
>> - Kernel-internal accesses performed with override_creds() (e.g.
>> overlayfs, cachefiles) and kernel threads without a Landlock domain
>> (e.g. nfsd, ksmbd) are not restricted.
>>
>> The Landlock ABI version is incremented from 11 to 12.
>>
>> The series is based on linux-next commit 5c4d4169604b ("Add linux-next
>> specific files for 20260921").
>>
>> Testing: each patch has been built for aarch64 (gcc, -Werror) and the
>> landlock selftests (445 tests, including the new ones) pass in QEMU on
>> aarch64; base_test reports ABI v12.
>>
>> [1] https://lore.kernel.org/all/20220827111215.131442-1-xiujianfeng@huawei.com/
>> [2] https://lore.kernel.org/all/abc960a1-e66e-792e-6869-cfd201c29dbe@digikod.net/
> Thank you for sending this patch set!
>
> Some meta-remarks at the beginning:
>
> * You might want to link the bugtracker feature request:
> https://github.com/landlock-lsm/linux/issues/11
> * In the final version, I think it's preferred to merge patches 8
> (adding the access right enums) and 9 (adding the LSM hooks that use
> them). Having the feature as an atomic commit makes it harder to
> accidentally mess it up during a backport, because you can't patch 8
> without 9.
> * As Paul alluded to, the changes to the LSM hook interface and to the
> existing callers in VFS are likely the hardest part of this patch
> set. Alexei from the BPF subsystem has also reiterated recently
> that he wants BPF to be looped into such changes. BPF hooks do not
> give the same backwards compatibility guarantees as the syscall
> layer, but there are existing users of LSM hooks specifically
> through the BPF LSM.
>
> * In https://github.com/landlock-lsm/linux/issues/18, we came across
> statfs(), which returns file system meta-information based for the
> file system that a given file belongs to. I have weak confidence
> that READ_METADATA would be the right access right to protect this
> with, but it's a somewhat related operation. Maybe you have some
> thoughts on this?
>
> More concrete questions:
>
> * If a "inode" LSM hook gets a "path" argument now, should it be
> renamed from "inode_..." to "path_..."?
>
> (Maybe the BPF people can chime in about to what extent that would
> cause additional churn for BPF users, in a situation where they
> anyway already need to make a change due to the changing function
> signature?)
>
> –Günther
More information about the Linux-security-module-archive
mailing list