Bug #794

Stacked mounts of procfs/linprocfs

Added by corecode over 6 years ago. Updated about 5 years ago.

Status:ClosedStart date:
Priority:NormalDue date:
Assignee:-% Done:

0%

Category:-
Target version:-

Description

Hey,

I just noticed that we can produce stacked mounts of procfs and linprocfs. Probably not what we want:

% mount|grep procfs
procfs on /proc (procfs, local)
procfs on /proc (procfs, local)

I tried looking into where to prevent this, probably in the vfsmount routine. However I'm a bit out of the loop concerning the namecache, so I'm not sure when I need to lock/release what.

Nevertheless I think we should prevent this behavior.

cheers
simon

History

#1 Updated by dillon over 6 years ago

:Hey,
:
:I just noticed that we can produce stacked mounts of procfs and linprocfs. Probably not what we want:
:
:% mount|grep procfs
:procfs on /proc (procfs, local)
:procfs on /proc (procfs, local)
:
:I tried looking into where to prevent this, probably in the vfsmount routine. However I'm a bit out of the loop concerning the namecache, so I'm not sure when I need to lock/release what.
:
:Nevertheless I think we should prevent this behavior.
:
:cheers
: simon

Yah, that wouldn't be good. procfs likes to destroy nodes dynamically
and that could lead to unmountable filesystems.

The easiest solution is to add a kernel mount flag (MNTK_*) to the
mount structure that tells the kernel not to allow mounts under a
particular mount (e.g. procfs), and just have the kernel check it when
a mount is attempted. Probably not more then 10 lines of code if you
would like to have a go at it.

-Matt

#2 Updated by nthery over 6 years ago

[snip]
> The easiest solution is to add a kernel mount flag (MNTK_*) to the
> mount structure that tells the kernel not to allow mounts under a
> particular mount (e.g. procfs), and just have the kernel check it when
> a mount is attempted. Probably not more then 10 lines of code if you
> would like to have a go at it.

Something along these lines?

Index: dfly/src/sys/emulation/linux/i386/linprocfs/linprocfs_vfsops.c
===================================================================
--- dfly.orig/src/sys/emulation/linux/i386/linprocfs/linprocfs_vfsops.c 2006-12-23
01:27:02.000000000 +0100
+++ dfly/src/sys/emulation/linux/i386/linprocfs/linprocfs_vfsops.c 2007-09-01
14:29:38.000000000 +0200
@@ -84,6 +84,7 @@
}

mp->mnt_flag |= MNT_LOCAL;
+ mp->mnt_kern_flag |= MNTK_NOSTKMNT;
mp->mnt_data = 0;
vfs_getnewfsid(mp);

Index: dfly/src/sys/kern/vfs_syscalls.c
===================================================================
--- dfly.orig/src/sys/kern/vfs_syscalls.c 2007-08-13 19:43:55.000000000 +0200
+++ dfly/src/sys/kern/vfs_syscalls.c 2007-09-01 14:20:53.000000000 +0200
@@ -248,6 +248,11 @@
vput(vp);
return (ENOTDIR);
}
+ if (vp->v_mount->mnt_kern_flag & MNTK_NOSTKMNT) {
+ cache_drop(&nch);
+ vput(vp);
+ return (EPERM);
+ }
if ((error = copyinstr(uap->type, fstypename, MFSNAMELEN, NULL)) != 0) {
cache_drop(&nch);
vput(vp);
Index: dfly/src/sys/sys/mount.h
===================================================================
--- dfly.orig/src/sys/sys/mount.h 2006-10-27 06:56:33.000000000 +0200
+++ dfly/src/sys/sys/mount.h 2007-09-01 14:50:36.000000000 +0200
@@ -243,6 +243,8 @@
* dounmount() is still waiting to lock the mountpoint. This allows
* the filesystem to cancel operations that might otherwise deadlock
* with the unmount attempt (used by NFS).
+ *
+ * MNTK_NOSTKMNT prevents mounting another filesystem inside the flagged one.
*/
#define MNTK_UNMOUNTF 0x00000001 /* forced unmount in progress */
#define MNTK_NCALIASED 0x00800000 /* namecached aliased */
@@ -250,6 +252,7 @@
#define MNTK_MWAIT 0x02000000 /* waiting for unmount to finish */
#define MNTK_WANTRDWR 0x04000000 /* upgrade to read/write requested */
#define MNTK_FSMID 0x08000000 /* getattr supports FSMIDs */
+#define MNTK_NOSTKMNT 0x10000000 /* no stacked mount point allowed */

/*
* mountlist_*() defines
Index: dfly/src/sys/vfs/procfs/procfs_vfsops.c
===================================================================
--- dfly.orig/src/sys/vfs/procfs/procfs_vfsops.c 2006-12-23
01:41:30.000000000 +0100
+++ dfly/src/sys/vfs/procfs/procfs_vfsops.c 2007-09-01 14:23:43.000000000 +0200
@@ -81,6 +81,7 @@
}

mp->mnt_flag |= MNT_LOCAL;
+ mp->mnt_kern_flag |= MNTK_NOSTKMNT;
mp->mnt_data = 0;
vfs_getnewfsid(mp);

Index: dfly/src/lib/libc/sys/mount.2
===================================================================
--- dfly.orig/src/lib/libc/sys/mount.2 2007-07-14 23:48:15.000000000 +0200
+++ dfly/src/lib/libc/sys/mount.2 2007-09-01 16:08:00.000000000 +0200
@@ -187,7 +187,10 @@
.Bl -tag -width Er
.It Bq Er EPERM
The caller is neither the super-user nor the owner of
-.Ar dir .
+.Ar dir ,
+or
+.Ar dir
+belongs to a filesystem that does not support stacked mounts.
.It Bq Er ENAMETOOLONG
A component of a pathname exceeded 255 characters,
or the entire length of a path name exceeded 1023 characters.

#3 Updated by dillon over 6 years ago

:Something along these lines?
:
:Index: dfly/src/sys/emulation/linux/i386/linprocfs/linprocfs_vfsops.c
:===================================================================
:--- dfly.orig/src/sys/emulation/linux/i386/linprocfs/linprocfs_vfsops.c 2006-12-23
:01:27:02.000000000 +0100
:+++ dfly/src/sys/emulation/linux/i386/linprocfs/linprocfs_vfsops.c 2007-09-01
:14:29:38.000000000 +0200
:@@ -84,6 +84,7 @@
: }

That looks good. If you tested it and it works, I'd say its commitable.

-Matt

#4 Updated by nthery over 6 years ago

I tested it roughly this way:

mount -t procfs proc /proc -> ok
mount -t procfs proc /proc -> ko
mount -t procfs proc /proc/1 ->ko
mount -t procfs proc /mnt -> ok

Then I repeated for linprocfs.

Cheers,
Nicolas

#5 Updated by dillon over 6 years ago

Committed!

-Matt

Also available in: Atom PDF