[PATCH 17/28] VFS: Mountpoint file descriptor walking

From: Mike Waychison
Date: Mon Oct 25 2004 - 19:28:00 EST


This patch allows one to walk the mountpoint tree given a mountfd. There are
two operations permitted:

MOUNTFD_IOC_GETFIRSTCHILD - Given a mountfd, return the first child mountpoint
as a mountfd.
MOUNTFD_IOC_GETNEXTCHILD - Given a mountfd, return the next mountpoint sibling
to it. (*)

(*) XXX: This should be modified to also take a parent mountfd so that you
can't walk out of a chroot.

We explicitly don't allow walks to the parent of a mountpoint as that would
allow for a user to easily walk out of a chroot.

Signed-off-by: Mike Waychison <michael.waychison@xxxxxxx>
---

fs/mountfd.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
include/linux/fs.h | 3 +++
2 files changed, 49 insertions(+)

Index: linux-2.6.9-quilt/include/linux/fs.h
===================================================================
--- linux-2.6.9-quilt.orig/include/linux/fs.h 2004-10-22 17:17:42.012077336 -0400
+++ linux-2.6.9-quilt/include/linux/fs.h 2004-10-22 17:17:42.625984008 -0400
@@ -219,6 +219,9 @@ extern int leases_enable, dir_notify_ena
#define MOUNTFD_IOC_DETACH _IO('p', 0xa2)
#define MOUNTFD_IOC_FORCEDUNMOUNT _IO('p', 0xa3)
#define MOUNTFD_IOC_ATTACH _IOW('p', 0xa4, int)
+#define MOUNTFD_IOC_GETFIRSTCHILD _IO('p', 0xa5)
+/* TODO: change this interface to require the parent mfd as well */
+#define MOUNTFD_IOC_GETNEXTCHILD _IO('p', 0xa6)

#ifdef __KERNEL__

Index: linux-2.6.9-quilt/fs/mountfd.c
===================================================================
--- linux-2.6.9-quilt.orig/fs/mountfd.c 2004-10-22 17:17:42.011077488 -0400
+++ linux-2.6.9-quilt/fs/mountfd.c 2004-10-22 17:17:42.625984008 -0400
@@ -284,6 +284,48 @@ out:
return ret;
}

+static long mfd_firstchild(struct file *mountfilp)
+{
+ struct vfsmount *mnt, *childmnt = NULL;
+ int ret;
+
+ mnt = mntget(VFSMOUNT(mountfilp));
+
+ spin_lock(&vfsmount_lock);
+ if (!list_empty(&mnt->mnt_mounts))
+ childmnt = mntget(container_of(mnt->mnt_mounts.next, struct vfsmount, mnt_child));
+ spin_unlock(&vfsmount_lock);
+
+ ret = -ENOENT;
+ if (childmnt)
+ ret = open_mfd(childmnt);
+
+ mntput(childmnt);
+ mntput(mnt);
+ return ret;
+}
+
+static long mfd_nextchild(struct file *mountfilp)
+{
+ struct vfsmount *mnt, *nextmnt = NULL;
+ int ret;
+
+ mnt = mntget(VFSMOUNT(mountfilp));
+
+ spin_lock(&vfsmount_lock);
+ if (mnt->mnt_child.next != &mnt->mnt_parent->mnt_mounts)
+ nextmnt = mntget(container_of(mnt->mnt_child.next, struct vfsmount, mnt_child));
+ spin_unlock(&vfsmount_lock);
+
+ ret = -ENOENT;
+ if (nextmnt)
+ ret = open_mfd(nextmnt);
+
+ mntput(nextmnt);
+ mntput(mnt);
+ return ret;
+}
+
static int mfd_ioctl(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
@@ -298,6 +340,10 @@ static int mfd_ioctl(struct inode *inode
return mfd_umount(filp, MNT_FORCE);
case MOUNTFD_IOC_ATTACH:
return mfd_attach(filp, arg);
+ case MOUNTFD_IOC_GETFIRSTCHILD:
+ return mfd_firstchild(filp);
+ case MOUNTFD_IOC_GETNEXTCHILD:
+ return mfd_nextchild(filp);
}
return -ENOTTY;
}

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/