Following up Bryan Henderson's idea of invisible mounts and my conviction that you don't need per-process selection for visibility, here's a proof of concept patch.
It adds a new mount flag MNT_NOOTHER/MS_NOOTHER. If this flag is set, then the mount is only visible to it's "owner". The owner is set to current->fsuid at mount time (hack). I tested it with a primitive mount utility (included at the end), and everything seems to work as expected. If something like this is acceptable, it would be a perfect replacement for the current permission based mount hiding in FUSE. Comments? Thanks, Miklos fs/namespace.c | 21 +++++++++++++++++++-- include/linux/fs.h | 1 + include/linux/mount.h | 2 ++ 3 files changed, 22 insertions(+), 2 deletions(-) diff -rup orig/linux-2.6.11/fs/namespace.c linux-2.6.11/fs/namespace.c --- orig/linux-2.6.11/fs/namespace.c 2005-03-04 14:59:24.000000000 +0100 +++ linux-2.6.11/fs/namespace.c 2005-04-21 15:26:03.000000000 +0200 @@ -81,6 +81,15 @@ void free_vfsmnt(struct vfsmount *mnt) } /* + * Check if this mount should be skipped or not + */ +static inline int mnt_visible(struct vfsmount *mnt) +{ + return !(mnt->mnt_flags & MNT_NOOTHER) || + mnt->mnt_uid == current->fsuid; +} + +/* * Now, lookup_mnt increments the ref count before returning * the vfsmount struct. */ @@ -97,7 +106,8 @@ struct vfsmount *lookup_mnt(struct vfsmo if (tmp == head) break; p = list_entry(tmp, struct vfsmount, mnt_hash); - if (p->mnt_parent == mnt && p->mnt_mountpoint == dentry) { + if (p->mnt_parent == mnt && p->mnt_mountpoint == dentry && + mnt_visible(p)) { found = mntget(p); break; } @@ -234,6 +244,7 @@ static int show_vfsmnt(struct seq_file * { MNT_NOSUID, ",nosuid" }, { MNT_NODEV, ",nodev" }, { MNT_NOEXEC, ",noexec" }, + { MNT_NOOTHER, ",noother" }, { 0, NULL } }; struct proc_fs_info *fs_infop; @@ -252,6 +263,8 @@ static int show_vfsmnt(struct seq_file * if (mnt->mnt_flags & fs_infop->flag) seq_puts(m, fs_infop->str); } + if (mnt->mnt_flags & MNT_NOOTHER) + seq_printf(m, ",mnt_uid=%u", mnt->mnt_uid); if (mnt->mnt_sb->s_op->show_options) err = mnt->mnt_sb->s_op->show_options(m, mnt); seq_puts(m, " 0 0\n"); @@ -807,6 +820,8 @@ int do_add_mount(struct vfsmount *newmnt goto unlock; newmnt->mnt_flags = mnt_flags; + if (mnt_flags & MNT_NOOTHER) + newmnt->mnt_uid = current->fsuid; err = graft_tree(newmnt, nd); if (err == 0 && fslist) { @@ -1033,7 +1048,9 @@ long do_mount(char * dev_name, char * di mnt_flags |= MNT_NODEV; if (flags & MS_NOEXEC) mnt_flags |= MNT_NOEXEC; - flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_ACTIVE); + if (flags & MS_NOOTHER) + mnt_flags |= MNT_NOOTHER; + flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_NOOTHER|MS_ACTIVE); /* ... and get the mountpoint */ retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd); diff -rup orig/linux-2.6.11/include/linux/fs.h linux-2.6.11/include/linux/fs.h --- orig/linux-2.6.11/include/linux/fs.h 2005-03-04 14:59:29.000000000 +0100 +++ linux-2.6.11/include/linux/fs.h 2005-04-21 13:32:41.000000000 +0200 @@ -96,6 +96,7 @@ extern int dir_notify_enable; #define MS_REMOUNT 32 /* Alter flags of a mounted FS */ #define MS_MANDLOCK 64 /* Allow mandatory locks on an FS */ #define MS_DIRSYNC 128 /* Directory modifications are synchronous */ +#define MS_NOOTHER 256 #define MS_NOATIME 1024 /* Do not update access times. */ #define MS_NODIRATIME 2048 /* Do not update directory access times */ #define MS_BIND 4096 diff -rup orig/linux-2.6.11/include/linux/mount.h linux-2.6.11/include/linux/mount.h --- orig/linux-2.6.11/include/linux/mount.h 2004-12-24 22:33:51.000000000 +0100 +++ linux-2.6.11/include/linux/mount.h 2005-04-21 12:50:42.000000000 +0200 @@ -19,6 +19,7 @@ #define MNT_NOSUID 1 #define MNT_NODEV 2 #define MNT_NOEXEC 4 +#define MNT_NOOTHER 8 struct vfsmount { @@ -31,6 +32,7 @@ struct vfsmount struct list_head mnt_child; /* and going through their mnt_child */ atomic_t mnt_count; int mnt_flags; + uid_t mnt_uid; int mnt_expiry_mark; /* true if marked for expiry */ char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */ struct list_head mnt_list; ===File ~/cc/mounttest.c==================================== #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/mount.h> #include <sys/fsuid.h> int main(int argc, char *argv[]) { if(argc != 6) { fprintf(stderr, "usage: %s dev dir type flags opts\n", argv[0]); return 1; } setfsuid(getuid()); if(mount(argv[1], argv[2], argv[3], atoi(argv[4]), argv[5]) == -1) { perror("mount"); return 1; } return 0; } ============================================================ - To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html