Add the new granular mount hook declarations and implementations to the LSM framework:
mount_bind - bind mount (pre-resolved source path) mount_new - new filesystem mount (with fs_context) mount_remount - filesystem remount (with fs_context) mount_reconfigure - mount flag reconfiguration (MS_REMOUNT|MS_BIND) mount_move - move mount (pre-resolved paths) mount_change_type - propagation type changes These hooks are added alongside the existing security_sb_mount() and security_move_mount() hooks, which remain in place until all LSMs are converted. Code generated with the assistance of Claude, reviewed by human. Reviewed-by: Stephen Smalley <[email protected]> Tested-by: Stephen Smalley <[email protected]> # for selinux only Signed-off-by: Song Liu <[email protected]> --- include/linux/lsm_hook_defs.h | 12 ++++ include/linux/security.h | 50 +++++++++++++++++ kernel/bpf/bpf_lsm.c | 7 +++ security/security.c | 101 ++++++++++++++++++++++++++++++++++ 4 files changed, 170 insertions(+) diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h index 2b8dfb35caed..98f0fe382665 100644 --- a/include/linux/lsm_hook_defs.h +++ b/include/linux/lsm_hook_defs.h @@ -81,6 +81,18 @@ LSM_HOOK(int, 0, sb_clone_mnt_opts, const struct super_block *oldsb, unsigned long *set_kern_flags) LSM_HOOK(int, 0, move_mount, const struct path *from_path, const struct path *to_path) +LSM_HOOK(int, 0, mount_bind, const struct path *from, const struct path *to, + bool recurse) +LSM_HOOK(int, 0, mount_new, struct fs_context *fc, const struct path *mp, + int mnt_flags, unsigned long flags, void *data) +LSM_HOOK(int, 0, mount_remount, struct fs_context *fc, + const struct path *mp, int mnt_flags, unsigned long flags, + void *data) +LSM_HOOK(int, 0, mount_reconfigure, const struct path *mp, + unsigned int mnt_flags, unsigned long flags) +LSM_HOOK(int, 0, mount_move, const struct path *from_path, + const struct path *to_path) +LSM_HOOK(int, 0, mount_change_type, const struct path *mp, int ms_flags) LSM_HOOK(int, -EOPNOTSUPP, dentry_init_security, struct dentry *dentry, int mode, const struct qstr *name, const char **xattr_name, struct lsm_context *cp) diff --git a/include/linux/security.h b/include/linux/security.h index 41d7367cf403..b1b3da51a88d 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -386,6 +386,17 @@ int security_sb_clone_mnt_opts(const struct super_block *oldsb, unsigned long kern_flags, unsigned long *set_kern_flags); int security_move_mount(const struct path *from_path, const struct path *to_path); +int security_mount_bind(const struct path *from, const struct path *to, + bool recurse); +int security_mount_new(struct fs_context *fc, const struct path *mp, + int mnt_flags, unsigned long flags, void *data); +int security_mount_remount(struct fs_context *fc, const struct path *mp, + int mnt_flags, unsigned long flags, void *data); +int security_mount_reconfigure(const struct path *mp, unsigned int mnt_flags, + unsigned long flags); +int security_mount_move(const struct path *from_path, + const struct path *to_path); +int security_mount_change_type(const struct path *mp, int ms_flags); int security_dentry_init_security(struct dentry *dentry, int mode, const struct qstr *name, const char **xattr_name, @@ -854,6 +865,45 @@ static inline int security_move_mount(const struct path *from_path, return 0; } +static inline int security_mount_bind(const struct path *from, + const struct path *to, bool recurse) +{ + return 0; +} + +static inline int security_mount_new(struct fs_context *fc, + const struct path *mp, int mnt_flags, + unsigned long flags, void *data) +{ + return 0; +} + +static inline int security_mount_remount(struct fs_context *fc, + const struct path *mp, int mnt_flags, + unsigned long flags, void *data) +{ + return 0; +} + +static inline int security_mount_reconfigure(const struct path *mp, + unsigned int mnt_flags, + unsigned long flags) +{ + return 0; +} + +static inline int security_mount_move(const struct path *from_path, + const struct path *to_path) +{ + return 0; +} + +static inline int security_mount_change_type(const struct path *mp, + int ms_flags) +{ + return 0; +} + static inline int security_path_notify(const struct path *path, u64 mask, unsigned int obj_type) { diff --git a/kernel/bpf/bpf_lsm.c b/kernel/bpf/bpf_lsm.c index c5c925f00202..aa228372cfb4 100644 --- a/kernel/bpf/bpf_lsm.c +++ b/kernel/bpf/bpf_lsm.c @@ -382,6 +382,13 @@ BTF_ID(func, bpf_lsm_task_setscheduler) BTF_ID(func, bpf_lsm_userns_create) BTF_ID(func, bpf_lsm_bdev_alloc_security) BTF_ID(func, bpf_lsm_bdev_setintegrity) +BTF_ID(func, bpf_lsm_move_mount) +BTF_ID(func, bpf_lsm_mount_bind) +BTF_ID(func, bpf_lsm_mount_new) +BTF_ID(func, bpf_lsm_mount_remount) +BTF_ID(func, bpf_lsm_mount_reconfigure) +BTF_ID(func, bpf_lsm_mount_move) +BTF_ID(func, bpf_lsm_mount_change_type) BTF_SET_END(sleepable_lsm_hooks) BTF_SET_START(untrusted_lsm_hooks) diff --git a/security/security.c b/security/security.c index 4e999f023651..b7ec0ec7af26 100644 --- a/security/security.c +++ b/security/security.c @@ -1182,6 +1182,107 @@ int security_move_mount(const struct path *from_path, return call_int_hook(move_mount, from_path, to_path); } +/** + * security_mount_bind() - Check permissions for a bind mount + * @from: source path + * @to: destination mount point + * @recurse: whether this is a recursive bind mount + * + * Check permission before a bind mount is performed. Called with the + * source path already resolved, eliminating TOCTOU issues with + * string-based dev_name in security_sb_mount(). + * + * Return: Returns 0 if permission is granted. + */ +int security_mount_bind(const struct path *from, const struct path *to, + bool recurse) +{ + return call_int_hook(mount_bind, from, to, recurse); +} + +/** + * security_mount_new() - Check permissions for a new mount + * @fc: filesystem context with parsed options + * @mp: mount point path + * @mnt_flags: mount flags (MNT_*) + * @flags: original mount flags (MS_*, used by AppArmor/Tomoyo) + * @data: filesystem specific data (used by AppArmor) + * + * Check permission before a new filesystem is mounted. Called after + * mount options are parsed, providing access to the fs_context. + * + * Return: Returns 0 if permission is granted. + */ +int security_mount_new(struct fs_context *fc, const struct path *mp, + int mnt_flags, unsigned long flags, void *data) +{ + return call_int_hook(mount_new, fc, mp, mnt_flags, flags, data); +} + +/** + * security_mount_remount() - Check permissions for a remount + * @fc: filesystem context with parsed options + * @mp: mount point path + * @mnt_flags: mount flags (MNT_*) + * @flags: original mount flags (MS_*, used by AppArmor/Tomoyo) + * @data: filesystem specific data (used by AppArmor) + * + * Check permission before a filesystem is remounted. Called after + * mount options are parsed, providing access to the fs_context. + * + * Return: Returns 0 if permission is granted. + */ +int security_mount_remount(struct fs_context *fc, const struct path *mp, + int mnt_flags, unsigned long flags, void *data) +{ + return call_int_hook(mount_remount, fc, mp, mnt_flags, flags, data); +} + +/** + * security_mount_reconfigure() - Check permissions for mount reconfiguration + * @mp: mount point path + * @mnt_flags: new mount flags (MNT_*) + * @flags: original mount flags (MS_*, used by AppArmor/Tomoyo) + * + * Check permission before mount flags are reconfigured (MS_REMOUNT|MS_BIND). + * + * Return: Returns 0 if permission is granted. + */ +int security_mount_reconfigure(const struct path *mp, unsigned int mnt_flags, + unsigned long flags) +{ + return call_int_hook(mount_reconfigure, mp, mnt_flags, flags); +} + +/** + * security_mount_move() - Check permissions for moving a mount + * @from_path: source mount path + * @to_path: destination mount point path + * + * Check permission before a mount is moved. + * + * Return: Returns 0 if permission is granted. + */ +int security_mount_move(const struct path *from_path, + const struct path *to_path) +{ + return call_int_hook(mount_move, from_path, to_path); +} + +/** + * security_mount_change_type() - Check permissions for propagation changes + * @mp: mount point path + * @ms_flags: propagation flags (MS_SHARED, MS_PRIVATE, etc.) + * + * Check permission before mount propagation type is changed. + * + * Return: Returns 0 if permission is granted. + */ +int security_mount_change_type(const struct path *mp, int ms_flags) +{ + return call_int_hook(mount_change_type, mp, ms_flags); +} + /** * security_path_notify() - Check if setting a watch is allowed * @path: file path -- 2.53.0-Meta
