summaryrefslogtreecommitdiff
path: root/security/landlock
diff options
context:
space:
mode:
authorMickaël Salaün <mic@digikod.net>2022-05-06 19:10:56 +0300
committerMickaël Salaün <mic@digikod.net>2022-05-23 14:27:58 +0300
commit100f59d964050020285f0c8264ce520f0c406c13 (patch)
tree037d009604dce35f82e15cdc324258d39dbaed9b /security/landlock
parent9da82b20fde95814af721a2a7b1796a5b4a3d78e (diff)
downloadlinux-100f59d964050020285f0c8264ce520f0c406c13.tar.xz
LSM: Remove double path_rename hook calls for RENAME_EXCHANGE
In order to be able to identify a file exchange with renameat2(2) and RENAME_EXCHANGE, which will be useful for Landlock [1], propagate the rename flags to LSMs. This may also improve performance because of the switch from two set of LSM hook calls to only one, and because LSMs using this hook may optimize the double check (e.g. only one lock, reduce the number of path walks). AppArmor, Landlock and Tomoyo are updated to leverage this change. This should not change the current behavior (same check order), except (different level of) speed boosts. [1] https://lore.kernel.org/r/20220221212522.320243-1-mic@digikod.net Cc: James Morris <jmorris@namei.org> Cc: Kentaro Takeda <takedakn@nttdata.co.jp> Cc: Serge E. Hallyn <serge@hallyn.com> Acked-by: John Johansen <john.johansen@canonical.com> Acked-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> Reviewed-by: Paul Moore <paul@paul-moore.com> Signed-off-by: Mickaël Salaün <mic@digikod.net> Link: https://lore.kernel.org/r/20220506161102.525323-7-mic@digikod.net
Diffstat (limited to 'security/landlock')
-rw-r--r--security/landlock/fs.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/security/landlock/fs.c b/security/landlock/fs.c
index 7b7860039a08..30b42cdee52e 100644
--- a/security/landlock/fs.c
+++ b/security/landlock/fs.c
@@ -622,10 +622,12 @@ static int hook_path_link(struct dentry *const old_dentry,
static int hook_path_rename(const struct path *const old_dir,
struct dentry *const old_dentry,
const struct path *const new_dir,
- struct dentry *const new_dentry)
+ struct dentry *const new_dentry,
+ const unsigned int flags)
{
const struct landlock_ruleset *const dom =
landlock_get_current_domain();
+ u32 exchange_access = 0;
if (!dom)
return 0;
@@ -633,12 +635,19 @@ static int hook_path_rename(const struct path *const old_dir,
if (old_dir->dentry != new_dir->dentry)
/* Gracefully forbids reparenting. */
return -EXDEV;
+ if (flags & RENAME_EXCHANGE) {
+ if (unlikely(d_is_negative(new_dentry)))
+ return -ENOENT;
+ exchange_access =
+ get_mode_access(d_backing_inode(new_dentry)->i_mode);
+ }
if (unlikely(d_is_negative(old_dentry)))
return -ENOENT;
/* RENAME_EXCHANGE is handled because directories are the same. */
return check_access_path(
dom, old_dir,
maybe_remove(old_dentry) | maybe_remove(new_dentry) |
+ exchange_access |
get_mode_access(d_backing_inode(old_dentry)->i_mode));
}