Add two new filesystem access rights to control file metadata access:
- LANDLOCK_ACCESS_FS_READ_METADATA: Read file or directory metadata
(e.g. inode attributes, extended attributes and POSIX ACLs) through
stat(2), fstat(2), lstat(2), newfstatat(2), getxattr(2) and
friends, listxattr(2) and friends, and the POSIX ACL read
operations.
- LANDLOCK_ACCESS_FS_WRITE_METADATA: Change file or directory
metadata through chmod(2) and friends, chown(2) and friends,
utimensat(2) and friends, setxattr(2) and friends, removexattr(2)
and friends, and the POSIX ACL set and remove operations.
This follows the coarse-grained grouping approach discussed in the
mailing list [1], where file metadata operations are grouped by
security relevance rather than by individual syscall.
Implement the two rights by hooking the inode_getattr,
inode_file_getattr, inode_setattr, inode_file_setattr,
inode_setxattr, inode_getxattr, inode_listxattr, inode_removexattr,
inode_set_acl, inode_get_acl and inode_remove_acl LSM hooks, which
now receive a struct path thanks to the preceding VFS and LSM
refactoring. The following system calls are now controlled:
- stat(2), fstat(2), lstat(2), newfstatat(2), getxattr(2) and
friends, listxattr(2) and friends, POSIX ACL reads, and the
chattr(1)/xfs_io style reads: ioctl(FS_IOC_GETFLAGS),
ioctl(FS_IOC_FSGETXATTR) and file_getattr(2) via inode_getattr,
inode_getxattr, inode_listxattr, inode_get_acl and
inode_file_getattr (READ_METADATA)
- chmod(2), fchmod(2), fchmodat(2), fchmodat2(2), chown(2), fchown(2),
lchown(2), fchownat(2), chgrp(2), utimensat(2), futimens(2),
utime(2), setxattr(2) and friends, removexattr(2) and friends,
POSIX ACL set and remove, and the chattr(1)/xfs_io style writes:
ioctl(FS_IOC_SETFLAGS), ioctl(FS_IOC_FSSETXATTR) and
file_setattr(2) via inode_setattr, inode_file_setattr,
inode_setxattr, inode_removexattr, inode_set_acl and
inode_remove_acl (WRITE_METADATA)
Both new rights are added to ACCESS_FILE as they apply to both files
and directories.
hook_inode_setattr only restricts explicit metadata changes, i.e. it
checks WRITE_METADATA only when the ia_valid mask contains
ATTR_MODE, ATTR_UID, ATTR_GID, ATTR_TIMES_SET or ATTR_TOUCH.
Metadata changes that the kernel performs implicitly, such as
timestamp updates on write(2) or size changes on truncate(2), are
therefore not restricted, and neither are chmod(2)/chown(2) calls
that do not change any attribute (e.g. chown(2) with -1/-1, which is
a no-op that never reaches the hook), matching the behavior of the
SELinux inode_setattr hook.
Stacking filesystems forward fileattr operations to underlying inodes
without calling the LSM hooks again (see the preceding patch), so a
fileattr operation on an overlayfs file is checked once on the
user-facing merged path and is not spuriously denied because of the
kernel-side creator credentials used for the forward.
Kernel-internal accesses performed with override_creds() (e.g.
overlayfs and cachefiles) are not affected because Landlock domains
are attached to credentials, and kernel threads without a Landlock
domain (e.g. nfsd and ksmbd) are not restricted either.
Remove stat(2), chmod(2), chown(2), setxattr(2) and utime(2) from the
list of file-related actions that cannot be restricted yet, and add
the names of the new rights to _LANDLOCK_ACCESS_FS_NAMES in
include/linux/landlock.h, which is shared by audit records and trace
events, so that denied accesses can be reported with a human-readable
name and the static assertion on fs_access_strings in
security/landlock/audit.c stays valid.
Increment the Landlock ABI version from 12 to 13, and update the ABI
version check in tools/testing/selftests/landlock/base_test.c
accordingly.