When path conditions are specified tomoyo tries to retrieve information about the parent dentry. It currently assumes that the parent dentry is always reachable from the child dentry's mount. This assumption is wrong when bind-mounts are in play: mkdir /foo touch /foo/file1 mkdir /bar touch /bar/file2 mount --bind /bar/file2 /foo/file1 file read /foo/file1 path1.parent.uid=12 Tomoyo will now call dget_parent(file1). This will yield "bar". But "bar" isn't reachable from the bind-mount of "file1". Handle this case by ensuring that the parent dentry is actually reachable from the child dentry's mount and if not skip it. Fixes: 8761afd49ebf ("TOMOYO: Allow using owner/group etc. of file objects as conditions.") Cc: stable@xxxxxxxxxxxxxxx # 4.9+ Cc: Kentaro Takeda <takedakn@xxxxxxxxxxxxx> Cc: Tetsuo Handa <penguin-kernel@xxxxxxxxxxxxxxxxxxx> Cc: tomoyo-dev-en@xxxxxxxxxxxxx Signed-off-by: Christian Brauner (Microsoft) <brauner@xxxxxxxxxx> --- Hey everyone, Spotted this while working on some other fixes. Just an fyi, I'm not subscribed on the mailing list. Thanks! Christian --- security/tomoyo/condition.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/security/tomoyo/condition.c b/security/tomoyo/condition.c index f8bcc083bb0d..7e14f8fadbeb 100644 --- a/security/tomoyo/condition.c +++ b/security/tomoyo/condition.c @@ -714,25 +714,35 @@ void tomoyo_get_attributes(struct tomoyo_obj_info *obj) { u8 i; struct dentry *dentry = NULL; + struct vfsmount *mnt = NULL; for (i = 0; i < TOMOYO_MAX_PATH_STAT; i++) { struct inode *inode; + struct dentry *parent; switch (i) { case TOMOYO_PATH1: dentry = obj->path1.dentry; if (!dentry) continue; + mnt = obj->path1.mnt; break; case TOMOYO_PATH2: dentry = obj->path2.dentry; if (!dentry) continue; + mnt = obj->path2.mnt; break; default: if (!dentry) continue; - dentry = dget_parent(dentry); + parent = dget_parent(dentry); + + /* Ensure that parent dentry is reachable. */ + if (mnt->mnt_root != dentry->d_sb->s_root && + !is_subdir(dentry, mnt->mnt_root)) + continue; + dentry = parent; break; } inode = d_backing_inode(dentry); base-commit: f2906aa863381afb0015a9eb7fefad885d4e5a56 -- 2.34.1