Skip to content

Commit 157a353

Browse files
committed
apparmor: Fix regression in mount mediation
commit 2db154b ("vfs: syscall: Add move_mount(2) to move mounts around") introduced a new move_mount(2) system call and a corresponding new LSM security_move_mount hook but did not implement this hook for any existing LSM. This creates a regression for AppArmor mediation of mount. This patch provides a base mapping of the move_mount syscall to the existing mount mediation. In the future we may introduce additional mediations around the new mount calls. Fixes: 2db154b ("vfs: syscall: Add move_mount(2) to move mounts around") CC: stable@vger.kernel.org Reported-by: Andreas Steinmetz <anstein99@googlemail.com> Signed-off-by: John Johansen <john.johansen@canonical.com>
1 parent ea9bae1 commit 157a353

File tree

3 files changed

+51
-22
lines changed

3 files changed

+51
-22
lines changed

security/apparmor/include/mount.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,12 @@ int aa_mount_change_type(const struct cred *subj_cred,
3838
struct aa_label *label, const struct path *path,
3939
unsigned long flags);
4040

41+
int aa_move_mount_old(const struct cred *subj_cred,
42+
struct aa_label *label, const struct path *path,
43+
const char *old_name);
4144
int aa_move_mount(const struct cred *subj_cred,
42-
struct aa_label *label, const struct path *path,
43-
const char *old_name);
45+
struct aa_label *label, const struct path *from_path,
46+
const struct path *to_path);
4447

4548
int aa_new_mount(const struct cred *subj_cred,
4649
struct aa_label *label, const char *dev_name,

security/apparmor/lsm.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -722,8 +722,8 @@ static int apparmor_sb_mount(const char *dev_name, const struct path *path,
722722
error = aa_mount_change_type(current_cred(), label,
723723
path, flags);
724724
else if (flags & MS_MOVE)
725-
error = aa_move_mount(current_cred(), label, path,
726-
dev_name);
725+
error = aa_move_mount_old(current_cred(), label, path,
726+
dev_name);
727727
else
728728
error = aa_new_mount(current_cred(), label, dev_name,
729729
path, type, flags, data);
@@ -733,6 +733,21 @@ static int apparmor_sb_mount(const char *dev_name, const struct path *path,
733733
return error;
734734
}
735735

736+
static int apparmor_move_mount(const struct path *from_path,
737+
const struct path *to_path)
738+
{
739+
struct aa_label *label;
740+
int error = 0;
741+
742+
label = __begin_current_label_crit_section();
743+
if (!unconfined(label))
744+
error = aa_move_mount(current_cred(), label, from_path,
745+
to_path);
746+
__end_current_label_crit_section(label);
747+
748+
return error;
749+
}
750+
736751
static int apparmor_sb_umount(struct vfsmount *mnt, int flags)
737752
{
738753
struct aa_label *label;
@@ -1376,6 +1391,7 @@ static struct security_hook_list apparmor_hooks[] __ro_after_init = {
13761391
LSM_HOOK_INIT(capget, apparmor_capget),
13771392
LSM_HOOK_INIT(capable, apparmor_capable),
13781393

1394+
LSM_HOOK_INIT(move_mount, apparmor_move_mount),
13791395
LSM_HOOK_INIT(sb_mount, apparmor_sb_mount),
13801396
LSM_HOOK_INIT(sb_umount, apparmor_sb_umount),
13811397
LSM_HOOK_INIT(sb_pivotroot, apparmor_sb_pivotroot),

security/apparmor/mount.c

Lines changed: 28 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -483,36 +483,46 @@ int aa_mount_change_type(const struct cred *subj_cred,
483483
}
484484

485485
int aa_move_mount(const struct cred *subj_cred,
486-
struct aa_label *label, const struct path *path,
487-
const char *orig_name)
486+
struct aa_label *label, const struct path *from_path,
487+
const struct path *to_path)
488488
{
489489
struct aa_profile *profile;
490-
char *buffer = NULL, *old_buffer = NULL;
491-
struct path old_path;
490+
char *to_buffer = NULL, *from_buffer = NULL;
492491
int error;
493492

494493
AA_BUG(!label);
495-
AA_BUG(!path);
494+
AA_BUG(!from_path);
495+
AA_BUG(!to_path);
496+
497+
to_buffer = aa_get_buffer(false);
498+
from_buffer = aa_get_buffer(false);
499+
error = -ENOMEM;
500+
if (!to_buffer || !from_buffer)
501+
goto out;
502+
error = fn_for_each_confined(label, profile,
503+
match_mnt(subj_cred, profile, to_path, to_buffer,
504+
from_path, from_buffer,
505+
NULL, MS_MOVE, NULL, false));
506+
out:
507+
aa_put_buffer(to_buffer);
508+
aa_put_buffer(from_buffer);
509+
510+
return error;
511+
}
512+
513+
int aa_move_mount_old(const struct cred *subj_cred, struct aa_label *label,
514+
const struct path *path, const char *orig_name)
515+
{
516+
struct path old_path;
517+
int error;
496518

497519
if (!orig_name || !*orig_name)
498520
return -EINVAL;
499-
500521
error = kern_path(orig_name, LOOKUP_FOLLOW, &old_path);
501522
if (error)
502523
return error;
503524

504-
buffer = aa_get_buffer(false);
505-
old_buffer = aa_get_buffer(false);
506-
error = -ENOMEM;
507-
if (!buffer || !old_buffer)
508-
goto out;
509-
error = fn_for_each_confined(label, profile,
510-
match_mnt(subj_cred, profile, path, buffer, &old_path,
511-
old_buffer,
512-
NULL, MS_MOVE, NULL, false));
513-
out:
514-
aa_put_buffer(buffer);
515-
aa_put_buffer(old_buffer);
525+
error = aa_move_mount(subj_cred, label, &old_path, path);
516526
path_put(&old_path);
517527

518528
return error;

0 commit comments

Comments
 (0)