--- olpc-2.6-master.00/fs/namei.c 2007-02-28 20:05:28.000000000 -0500 +++ olpc-2.6-master-vs22x.02/fs/namei.c 2007-03-01 11:52:20.000000000 -0500 @@ -733,7 +767,8 @@ static __always_inline void follow_dotdo if (nd->dentry == fs->root && nd->mnt == fs->rootmnt) { read_unlock(&fs->lock); - break; + /* for sane '/' avoid follow_mount() */ + return; } read_unlock(&fs->lock); spin_lock(&dcache_lock); --- olpc-2.6-master.00/fs/namespace.c 2007-02-28 20:05:28.000000000 -0500 +++ olpc-2.6-master-vs22x.02/fs/namespace.c 2007-03-01 11:52:20.000000000 -0500 @@ -240,6 +245,7 @@ static struct vfsmount *clone_mnt(struct mnt->mnt_root = dget(root); mnt->mnt_mountpoint = mnt->mnt_root; mnt->mnt_parent = mnt; + mnt->mnt_tag = old->mnt_tag; if (flag & CL_SLAVE) { list_add(&mnt->mnt_slave, &old->mnt_slave_list); --- olpc-2.6-master.00/fs/namespace.c 2007-02-28 20:05:28.000000000 -0500 +++ olpc-2.6-master-vs22x.02/fs/namespace.c 2007-03-01 11:52:20.000000000 -0500 @@ -348,6 +354,32 @@ static inline void mangle(struct seq_fil seq_escape(m, s, " \t\n\\"); } +static int mnt_is_reachable(struct vfsmount *mnt) +{ + struct vfsmount *root_mnt; + struct dentry *root, *point; + int ret; + + if (mnt == mnt->mnt_ns->root) + return 1; + + spin_lock(&vfsmount_lock); + root_mnt = current->fs->rootmnt; + root = current->fs->root; + point = root; + + while ((mnt != mnt->mnt_parent) && (mnt != root_mnt)) { + point = mnt->mnt_mountpoint; + mnt = mnt->mnt_parent; + } + + ret = (mnt == root_mnt) && is_subdir(point, root); + + spin_unlock(&vfsmount_lock); + + return ret; +} + static int show_vfsmnt(struct seq_file *m, void *v) { struct vfsmount *mnt = v; --- olpc-2.6-master.00/fs/namespace.c 2007-02-28 20:05:28.000000000 -0500 +++ olpc-2.6-master-vs22x.02/fs/namespace.c 2007-03-01 11:52:20.000000000 -0500 @@ -404,17 +452,27 @@ static int show_vfsstat(struct seq_file struct vfsmount *mnt = v; int err = 0; - /* device */ - if (mnt->mnt_devname) { - seq_puts(m, "device "); - mangle(m, mnt->mnt_devname); - } else - seq_puts(m, "no device"); + if (vx_flags(VXF_HIDE_MOUNT, 0)) + return 0; + if (!mnt_is_reachable(mnt) && !vx_check(0, VS_WATCH_P)) + return 0; - /* mount point */ - seq_puts(m, " mounted on "); - seq_path(m, mnt, mnt->mnt_root, " \t\n\\"); - seq_putc(m, ' '); + if (!vx_check(0, VS_ADMIN|VS_WATCH) && + mnt == current->fs->rootmnt) { + seq_puts(m, "device /dev/root mounted on / "); + } else { + /* device */ + if (mnt->mnt_devname) { + seq_puts(m, "device "); + mangle(m, mnt->mnt_devname); + } else + seq_puts(m, "no device"); + + /* mount point */ + seq_puts(m, " mounted on "); + seq_path(m, mnt, mnt->mnt_root, " \t\n\\"); + seq_putc(m, ' '); + } /* file system type */ seq_puts(m, "with fstype "); --- olpc-2.6-master.00/fs/namespace.c 2007-02-28 20:05:28.000000000 -0500 +++ olpc-2.6-master-vs22x.02/fs/namespace.c 2007-03-01 11:52:20.000000000 -0500 @@ -668,7 +726,7 @@ asmlinkage long sys_oldumount(char __use static int mount_is_safe(struct nameidata *nd) { - if (capable(CAP_SYS_ADMIN)) + if (vx_capable(CAP_SYS_ADMIN, VXC_SECURE_MOUNT)) return 0; return -EPERM; #ifdef notyet --- olpc-2.6-master.00/fs/namespace.c 2007-02-28 20:05:28.000000000 -0500 +++ olpc-2.6-master-vs22x.02/fs/namespace.c 2007-03-01 11:52:20.000000000 -0500 @@ -897,7 +955,8 @@ static int do_change_type(struct nameida /* * do loopback mount. */ -static int do_loopback(struct nameidata *nd, char *old_name, int recurse) +static int do_loopback(struct nameidata *nd, char *old_name, tag_t tag, + unsigned long flags, int mnt_flags) { struct nameidata old_nd; struct vfsmount *mnt = NULL; --- olpc-2.6-master.00/fs/namespace.c 2007-02-28 20:05:28.000000000 -0500 +++ olpc-2.6-master-vs22x.02/fs/namespace.c 2007-03-01 11:52:20.000000000 -0500 @@ -902,6 +961,7 @@ ***** struct nameidata old_nd; struct vfsmount *mnt = NULL; int err = mount_is_safe(nd); + int recurse = flags & MS_REC; if (err) return err; if (!old_name || !*old_name) --- olpc-2.6-master.00/fs/namespace.c 2007-02-28 20:05:28.000000000 -0500 +++ olpc-2.6-master-vs22x.02/fs/namespace.c 2007-03-01 11:52:20.000000000 -0500 @@ -927,6 +987,12 @@ static int do_loopback(struct nameidata if (!mnt) goto out; + mnt->mnt_flags = mnt_flags; + if (flags & MS_TAGID) { + mnt->mnt_tag = tag; + mnt->mnt_flags |= MNT_TAGID; + } + err = graft_tree(mnt, nd); if (err) { LIST_HEAD(umount_list); --- olpc-2.6-master.00/fs/namespace.c 2007-02-28 20:05:28.000000000 -0500 +++ olpc-2.6-master-vs22x.02/fs/namespace.c 2007-03-01 11:52:20.000000000 -0500 @@ -935,6 +1001,7 @@ static int do_loopback(struct nameidata spin_unlock(&vfsmount_lock); release_mounts(&umount_list); } + mnt->mnt_flags = mnt_flags; out: up_write(&namespace_sem); --- olpc-2.6-master.00/fs/namespace.c 2007-02-28 20:05:28.000000000 -0500 +++ olpc-2.6-master-vs22x.02/fs/namespace.c 2007-03-01 11:52:20.000000000 -0500 @@ -948,7 +1015,7 @@ out: * on it - tough luck. */ static int do_remount(struct nameidata *nd, int flags, int mnt_flags, - void *data) + void *data, xid_t xid) { int err; struct super_block *sb = nd->mnt->mnt_sb; --- olpc-2.6-master.00/fs/namespace.c 2007-02-28 20:05:28.000000000 -0500 +++ olpc-2.6-master-vs22x.02/fs/namespace.c 2007-03-01 11:52:20.000000000 -0500 @@ -1379,6 +1446,7 @@ long do_mount(char *dev_name, char *dir_ struct nameidata nd; int retval = 0; int mnt_flags = 0; + tag_t tag = 0; /* Discard magic */ if ((flags & MS_MGC_MSK) == MS_MGC_VAL) --- olpc-2.6-master.00/fs/namespace.c 2007-02-28 20:05:28.000000000 -0500 +++ olpc-2.6-master-vs22x.02/fs/namespace.c 2007-03-01 11:52:20.000000000 -0500 @@ -1408,6 +1488,8 @@ long do_mount(char *dev_name, char *dir_ if (flags & MS_RELATIME) mnt_flags |= MNT_RELATIME; + if (!capable(CAP_SYS_ADMIN)) + mnt_flags |= MNT_NODEV; flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE | MS_NOATIME | MS_NODIRATIME | MS_RELATIME); --- olpc-2.6-master.00/fs/namespace.c 2007-02-28 20:05:28.000000000 -0500 +++ olpc-2.6-master-vs22x.02/fs/namespace.c 2007-03-01 11:52:20.000000000 -0500 @@ -1422,9 +1504,9 @@ long do_mount(char *dev_name, char *dir_ if (flags & MS_REMOUNT) retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags, - data_page); + data_page, tag); else if (flags & MS_BIND) - retval = do_loopback(&nd, dev_name, flags & MS_REC); + retval = do_loopback(&nd, dev_name, tag, flags, mnt_flags); else if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE)) retval = do_change_type(&nd, flags); else if (flags & MS_MOVE)