From: "Günther Noack" <gnoack3000@gmail.com>
To: Cai Xinchen <caixinchen1@huawei.com>
Cc: mic@digikod.net, gnoack@google.com, paul@paul-moore.com,
jmorris@namei.org, serge@hallyn.com, corbet@lwn.net,
skhan@linuxfoundation.org, rdunlap@infradead.org,
gregkh@linuxfoundation.org, rafael@kernel.org, dakr@kernel.org,
dlemoal@kernel.org, hch@lst.de, axboe@kernel.dk,
viro@zeniv.linux.org.uk, brauner@kernel.org, jack@suse.cz,
dhowells@redhat.com, code@tyhicks.com, linkinjeon@kernel.org,
sj1557.seo@samsung.com, yuezhang.mo@sony.com,
hirofumi@mail.parknet.co.jp, cel@kernel.org, jlayton@kernel.org,
neil@brown.name, okorniev@redhat.com, Dai.Ngo@oracle.com,
tom@talpey.com, miklos@szeredi.hu, amir73il@gmail.com,
senozhatsky@chromium.org, chenxiaosong@chenxiaosong.com,
zohar@linux.ibm.com, roberto.sassu@huawei.com,
dmitry.kasatkin@gmail.com, eric.snowberg@oracle.com,
stephen.smalley.work@gmail.com, omosnacek@gmail.com,
casey@schaufler-ca.com, nanx95726@gmail.com, djwong@kernel.org,
daniel@iogearbox.net, linux-security-module@vger.kernel.org,
linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org,
driver-core@lists.linux.dev, linux-block@vger.kernel.org,
linux-fsdevel@vger.kernel.org, netfs@lists.linux.dev,
ecryptfs@vger.kernel.org, exfat@lists.linux.dev,
linux-nfs@vger.kernel.org, linux-unionfs@vger.kernel.org,
linux-cifs@vger.kernel.org, linux-integrity@vger.kernel.org,
selinux@vger.kernel.org, linux-kselftest@vger.kernel.org,
xiujianfeng@huawei.com, lujialin4@huawei.com
Subject: Re: [PATCH RFC -next 09/12] landlock: Implement metadata access hooks
Date: Sat, 26 Sep 2026 10:38:24 +0200 [thread overview]
Message-ID: <20260926.a96402fcbd4b@gnoack.org> (raw)
In-Reply-To: <20260924104831.1081137-10-caixinchen1@huawei.com>
On Thu, Sep 24, 2026 at 06:48:28PM +0800, Cai Xinchen wrote:
> Implement the LANDLOCK_ACCESS_FS_READ_METADATA and
> LANDLOCK_ACCESS_FS_WRITE_METADATA access rights by hooking the
> inode_getattr, inode_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, and POSIX ACL reads via
> inode_getattr, inode_getxattr, inode_listxattr and inode_get_acl
> (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, and
> POSIX ACL set and remove via inode_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.
>
> 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.
>
> Assisted-by: opencode: glm-5.3
> Signed-off-by: Cai Xinchen <caixinchen1@huawei.com>
> ---
> security/landlock/fs.c | 86 ++++++++++++++++++++++++++++++++++++++++++
> 1 file changed, 86 insertions(+)
>
> diff --git a/security/landlock/fs.c b/security/landlock/fs.c
> index cab43892ec2f..e58b2aa0da65 100644
> --- a/security/landlock/fs.c
> +++ b/security/landlock/fs.c
> @@ -318,6 +318,8 @@ static struct landlock_object *get_inode_object(struct inode *const inode)
> LANDLOCK_ACCESS_FS_EXECUTE | \
> LANDLOCK_ACCESS_FS_WRITE_FILE | \
> LANDLOCK_ACCESS_FS_READ_FILE | \
> + LANDLOCK_ACCESS_FS_READ_METADATA | \
> + LANDLOCK_ACCESS_FS_WRITE_METADATA | \
> LANDLOCK_ACCESS_FS_TRUNCATE | \
> LANDLOCK_ACCESS_FS_IOCTL_DEV | \
> LANDLOCK_ACCESS_FS_RESOLVE_UNIX)
> @@ -1676,6 +1678,81 @@ static int hook_path_truncate(const struct path *const path)
> return current_check_access_path(path, LANDLOCK_ACCESS_FS_TRUNCATE);
> }
>
> +static int hook_inode_getattr(const struct path *const path)
> +{
> + return current_check_access_path(path,
> + LANDLOCK_ACCESS_FS_READ_METADATA);
> +}
> +
> +static int hook_inode_setattr(const struct path *const path,
> + struct iattr *const attr)
> +{
> + /*
> + * Explicit metadata changes (i.e. mode, ownership, and timestamps
> + * set with utimes() and friends) require
> + * LANDLOCK_ACCESS_FS_WRITE_METADATA. Implicit timestamp updates
> + * (e.g. ATTR_CTIME set for a write) and size changes (handled by
> + * the truncate hooks) are not restricted.
Nit: It feels like this comment about implicit timestamp updates
(especially the size change) should go in the top-level documentation
for the WRITE_METADATA right? setattr() can not result in a size
change, after all, AFAIK?
Remark on the side, apart from truncation, normal writes into the file
can of course also change its size ;-) and ATTR_ATIME and ATTR_MTIME
also come to mind as implicit metadata changes.
> + */
> + if (!(attr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID |
> + ATTR_TIMES_SET | ATTR_TOUCH)))
> + return 0;
> +
> + return current_check_access_path(path,
> + LANDLOCK_ACCESS_FS_WRITE_METADATA);
> +}
> +
> +static int hook_inode_setxattr(const struct path *const path,
> + const char *const name,
> + const void *const value, const size_t size,
> + const int flags)
> +{
> + return current_check_access_path(path,
> + LANDLOCK_ACCESS_FS_WRITE_METADATA);
> +}
> +
> +static int hook_inode_getxattr(const struct path *const path,
> + const char *const name)
> +{
> + return current_check_access_path(path,
> + LANDLOCK_ACCESS_FS_READ_METADATA);
> +}
> +
> +static int hook_inode_listxattr(const struct path *const path)
> +{
> + return current_check_access_path(path,
> + LANDLOCK_ACCESS_FS_READ_METADATA);
> +}
> +
> +static int hook_inode_removexattr(const struct path *const path,
> + const char *const name)
> +{
> + return current_check_access_path(path,
> + LANDLOCK_ACCESS_FS_WRITE_METADATA);
> +}
> +
> +static int hook_inode_set_acl(const struct path *const path,
> + const char *const acl_name,
> + struct posix_acl *const kacl)
> +{
> + return current_check_access_path(path,
> + LANDLOCK_ACCESS_FS_WRITE_METADATA);
> +}
> +
> +static int hook_inode_get_acl(const struct path *const path,
> + const char *const acl_name)
> +{
> + return current_check_access_path(path,
> + LANDLOCK_ACCESS_FS_READ_METADATA);
> +}
> +
> +static int hook_inode_remove_acl(const struct path *const path,
> + const char *const acl_name)
> +{
> + return current_check_access_path(path,
> + LANDLOCK_ACCESS_FS_WRITE_METADATA);
> +}
> +
> /**
> * unmask_scoped_access - Remove access right bits in @masks in all layers
> * where @client and @server have the same domain
> @@ -2100,6 +2177,15 @@ static struct security_hook_list landlock_hooks[] __ro_after_init = {
> LSM_HOOK_INIT(path_unlink, hook_path_unlink),
> LSM_HOOK_INIT(path_rmdir, hook_path_rmdir),
> LSM_HOOK_INIT(path_truncate, hook_path_truncate),
> + LSM_HOOK_INIT(inode_getattr, hook_inode_getattr),
> + LSM_HOOK_INIT(inode_setattr, hook_inode_setattr),
> + LSM_HOOK_INIT(inode_setxattr, hook_inode_setxattr),
> + LSM_HOOK_INIT(inode_getxattr, hook_inode_getxattr),
> + LSM_HOOK_INIT(inode_listxattr, hook_inode_listxattr),
> + LSM_HOOK_INIT(inode_removexattr, hook_inode_removexattr),
> + LSM_HOOK_INIT(inode_set_acl, hook_inode_set_acl),
> + LSM_HOOK_INIT(inode_get_acl, hook_inode_get_acl),
> + LSM_HOOK_INIT(inode_remove_acl, hook_inode_remove_acl),
> LSM_HOOK_INIT(unix_find, hook_unix_find),
>
> LSM_HOOK_INIT(file_alloc_security, hook_file_alloc_security),
> --
> 2.18.0.huawei.25
>
On the Landlock side, the implementation looks quite straightforward,
without having double checked for missing hooks now. This commit is
probably fine as soon as we have agreement on the LSM hook changes.
–Günther
next prev parent reply other threads:[~2026-09-26 8:38 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-24 10:48 [PATCH RFC -next 00/12] landlock: Add READ_METADATA and WRITE_METADATA access rights Cai Xinchen
2026-09-24 10:48 ` [PATCH RFC -next 01/12] fs: pass struct path to notify_change() Cai Xinchen
2026-09-24 10:48 ` [PATCH RFC -next 02/12] LSM: pass struct path to the inode_setsecctx hook Cai Xinchen
2026-09-24 10:48 ` [PATCH RFC -next 03/12] fs: pass struct path to xattr helpers Cai Xinchen
2026-09-24 11:12 ` Amir Goldstein
2026-09-24 10:48 ` [PATCH RFC -next 04/12] fs: pass struct path to POSIX ACL helpers Cai Xinchen
2026-09-24 10:48 ` [PATCH RFC -next 05/12] LSM: pass struct path to the inode_setattr hook Cai Xinchen
2026-09-24 10:48 ` [PATCH RFC -next 06/12] LSM: pass struct path to the inode xattr hooks Cai Xinchen
2026-09-24 10:48 ` [PATCH RFC -next 07/12] LSM: pass struct path to the inode posix acl hooks Cai Xinchen
2026-09-24 10:48 ` [PATCH RFC -next 08/12] landlock: Add READ_METADATA and WRITE_METADATA access rights Cai Xinchen
2026-09-24 10:48 ` [PATCH RFC -next 09/12] landlock: Implement metadata access hooks Cai Xinchen
2026-09-26 8:38 ` Günther Noack [this message]
2026-09-24 10:48 ` [PATCH RFC -next 10/12] selftests/landlock: Add tests for metadata access rights Cai Xinchen
2026-09-24 10:48 ` [PATCH RFC -next 11/12] samples/landlock: Add metadata rights to sandboxer Cai Xinchen
2026-09-24 10:48 ` [PATCH RFC -next 12/12] Documentation: Update landlock doc for metadata rights Cai Xinchen
2026-09-25 15:33 ` [PATCH RFC -next 00/12] landlock: Add READ_METADATA and WRITE_METADATA access rights Christian Brauner
2026-09-25 17:07 ` Paul Moore
2026-09-25 18:03 ` Justin Suess
2026-09-26 7:56 ` Günther Noack
2026-09-26 8:27 ` Günther Noack
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260926.a96402fcbd4b@gnoack.org \
--to=gnoack3000@gmail.com \
--cc=Dai.Ngo@oracle.com \
--cc=amir73il@gmail.com \
--cc=axboe@kernel.dk \
--cc=brauner@kernel.org \
--cc=caixinchen1@huawei.com \
--cc=casey@schaufler-ca.com \
--cc=cel@kernel.org \
--cc=chenxiaosong@chenxiaosong.com \
--cc=code@tyhicks.com \
--cc=corbet@lwn.net \
--cc=dakr@kernel.org \
--cc=daniel@iogearbox.net \
--cc=dhowells@redhat.com \
--cc=djwong@kernel.org \
--cc=dlemoal@kernel.org \
--cc=dmitry.kasatkin@gmail.com \
--cc=driver-core@lists.linux.dev \
--cc=ecryptfs@vger.kernel.org \
--cc=eric.snowberg@oracle.com \
--cc=exfat@lists.linux.dev \
--cc=gnoack@google.com \
--cc=gregkh@linuxfoundation.org \
--cc=hch@lst.de \
--cc=hirofumi@mail.parknet.co.jp \
--cc=jack@suse.cz \
--cc=jlayton@kernel.org \
--cc=jmorris@namei.org \
--cc=linkinjeon@kernel.org \
--cc=linux-block@vger.kernel.org \
--cc=linux-cifs@vger.kernel.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-integrity@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=linux-security-module@vger.kernel.org \
--cc=linux-unionfs@vger.kernel.org \
--cc=lujialin4@huawei.com \
--cc=mic@digikod.net \
--cc=miklos@szeredi.hu \
--cc=nanx95726@gmail.com \
--cc=neil@brown.name \
--cc=netfs@lists.linux.dev \
--cc=okorniev@redhat.com \
--cc=omosnacek@gmail.com \
--cc=paul@paul-moore.com \
--cc=rafael@kernel.org \
--cc=rdunlap@infradead.org \
--cc=roberto.sassu@huawei.com \
--cc=selinux@vger.kernel.org \
--cc=senozhatsky@chromium.org \
--cc=serge@hallyn.com \
--cc=sj1557.seo@samsung.com \
--cc=skhan@linuxfoundation.org \
--cc=stephen.smalley.work@gmail.com \
--cc=tom@talpey.com \
--cc=viro@zeniv.linux.org.uk \
--cc=xiujianfeng@huawei.com \
--cc=yuezhang.mo@sony.com \
--cc=zohar@linux.ibm.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®