kern/146543: securelevel does not affect mount (duplicate of kern/22142)

Sebastian Baberowski sebastian
Thu May 13 11:30:08 UTC 2010


>Number:         146543
>Category:       kern
>Synopsis:       securelevel does not affect mount (duplicate of kern/22142)
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Thu May 13 11:30:07 UTC 2010
>Closed-Date:
>Last-Modified:
>Originator:     Sebastian Baberowski
>Release:        8.0-RELEASE-p2
>Organization:
>Environment:
FreeBSD dwarf-fbsd 8.0-RELEASE-p2 FreeBSD 8.0-RELEASE-p2 #7: Wed May 12 23:11:36 CEST 2010     root at dwarf-fbsd:/usr/obj/usr/src/sys/GENERIC  i386
>Description:
Securelevel doesn't affect mount at all, so ro filesystem can be remounted to rw or unmounted in any securelevel.

It will be very convenient if mount -uw and unmount can be forbidden in higher (>=2) securelevels. With that it will be possible to protect the whole system by just read-only mount without dealing with immutable flags.
>How-To-Repeat:
mount -o ro /dev/da1 /mnt
sysctl kern.securelevel=2
mount -uw /mnt
>Fix:
Somebody may want to be still able to mount/unmount/update in any secure level, so IMHO it would be the best if we can mark particular mount as protected/locked. To do that new mount option can be added.

Initial patch attached.

TODO/known bugs:
- code review/check (I'm not an FreeBSD expert/developer)
- decide if securelevel=1 should be considered
- update manuals (mount(8), mount(2), security(7), any other?)
- update handbook
- "-u -o locked" is not working
- check/implement with other fs'es than ufs2
- implement patch for mount_* commands

Patch attached with submission follows:

diff -ru sbin.orig/mount/mntopts.h sbin/mount/mntopts.h
--- sbin.orig/mount/mntopts.h	2010-05-13 12:53:52.000000000 +0200
+++ sbin/mount/mntopts.h	2010-05-12 17:45:14.000000000 +0200
@@ -54,6 +54,7 @@
 #define MOPT_SNAPSHOT		{ "snapshot",	0, MNT_SNAPSHOT, 0 }
 #define MOPT_MULTILABEL		{ "multilabel",	0, MNT_MULTILABEL, 0 }
 #define MOPT_ACLS		{ "acls",	0, MNT_ACLS, 0 }
+#define MOPT_LOCKED		{ "locked",	0, MNT_LOCKED, 0 }
 
 /* Control flags. */
 #define MOPT_FORCE		{ "force",	0, MNT_FORCE, 0 }
@@ -87,6 +88,7 @@
 	MOPT_NOCLUSTERR,						\
 	MOPT_NOCLUSTERW,						\
 	MOPT_MULTILABEL,						\
+  MOPT_LOCKED,               \
 	MOPT_ACLS
 
 void getmntopts(const char *, const struct mntopt *, int *, int *);
diff -ru sbin.orig/mount/mount.c sbin/mount/mount.c
--- sbin.orig/mount/mount.c	2010-05-13 12:53:15.000000000 +0200
+++ sbin/mount/mount.c	2010-05-12 18:00:02.000000000 +0200
@@ -111,6 +111,7 @@
 	{ MNT_SOFTDEP,		"soft-updates" },
 	{ MNT_MULTILABEL,	"multilabel" },
 	{ MNT_ACLS,		"acls" },
+	{ MNT_LOCKED,		"locked" },
 	{ MNT_GJOURNAL,		"gjournal" },
 	{ 0, NULL }
 };
@@ -918,6 +921,7 @@
 	if (flags & MNT_SUIDDIR)	res = catopt(res, "suiddir");
 	if (flags & MNT_MULTILABEL)	res = catopt(res, "multilabel");
 	if (flags & MNT_ACLS)		res = catopt(res, "acls");
+	if (flags & MNT_LOCKED)		res = catopt(res, "locked");
 
 	return (res);
 }
diff -ru sys.orig/kern/vfs_mount.c sys/kern/vfs_mount.c
--- sys.orig/kern/vfs_mount.c	2010-05-13 12:55:02.000000000 +0200
+++ sys/kern/vfs_mount.c	2010-05-12 23:11:01.000000000 +0200
@@ -126,6 +126,7 @@
 	"rw",
 	"nosuid",
 	"noexec",
+  "locked",
 	NULL
 };
 
@@ -878,6 +894,15 @@
 		mp = vp->v_mount;
 		MNT_ILOCK(mp);
 		flag = mp->mnt_flag;
+
+		/* Do not allow any update in securelevel>1 if locked flag is set */
+		if ((mp->mnt_flag & MNT_LOCKED) &&
+			(error = securelevel_gt(td->td_ucred,1)) )
+		{
+			MNT_IUNLOCK(mp);
+			vput(vp);
+			return (error);
+		}
 		/*
 		 * We only allow the filesystem to be reloaded if it
 		 * is currently mounted read-only.
@@ -1220,6 +1245,19 @@
 		return (error);
 	}
 
+	/*
+	 * Do not allow unmounting locked filesystem
+	 * if securelevel>1
+	 */
+	if ( (mp->mnt_flag & MNT_LOCKED) &&
+		(error = securelevel_gt(td->td_ucred,1)) )
+	{
+		if (coveredvp)
+			VOP_UNLOCK(coveredvp, 0);
+
+		return (error);
+	}
+
 	MNT_ILOCK(mp);
 	if (mp->mnt_kern_flag & MNTK_UNMOUNT) {
 		MNT_IUNLOCK(mp);
diff -ru sys.orig/sys/mount.h sys/sys/mount.h
--- sys.orig/sys/mount.h	2010-05-13 12:54:40.000000000 +0200
+++ sys/sys/mount.h	2010-05-12 17:42:01.000000000 +0200
@@ -233,6 +233,7 @@
 #define	MNT_SUIDDIR	0x00100000	/* special handling of SUID on dirs */
 #define	MNT_SOFTDEP	0x00200000	/* soft updates being done */
 #define	MNT_NOSYMFOLLOW	0x00400000	/* do not follow symlinks */
+#define	MNT_LOCKED	0x01000000 /* locked, cannot be changed in securelevel>1 */
 #define	MNT_GJOURNAL	0x02000000	/* GEOM journal support enabled */
 #define	MNT_MULTILABEL	0x04000000	/* MAC support for individual objects */
 #define	MNT_ACLS	0x08000000	/* ACL support enabled */
@@ -274,7 +275,8 @@
 			MNT_ROOTFS	| MNT_NOATIME	| MNT_NOCLUSTERR| \
 			MNT_NOCLUSTERW	| MNT_SUIDDIR	| MNT_SOFTDEP	| \
 			MNT_IGNORE	| MNT_EXPUBLIC	| MNT_NOSYMFOLLOW | \
-			MNT_GJOURNAL	| MNT_MULTILABEL | MNT_ACLS)
+			MNT_LOCKED | MNT_GJOURNAL	| MNT_MULTILABEL | \
+      MNT_ACLS)
 
 /* Mask of flags that can be updated. */
 #define	MNT_UPDATEMASK (MNT_NOSUID	| MNT_NOEXEC	| \
@@ -282,7 +284,7 @@
 			MNT_NOATIME | \
 			MNT_NOSYMFOLLOW	| MNT_IGNORE	| \
 			MNT_NOCLUSTERR	| MNT_NOCLUSTERW | MNT_SUIDDIR	| \
-			MNT_ACLS	| MNT_USER)
+			MNT_ACLS	| MNT_USER | MNT_LOCKED)
 
 /*
  * External filesystem command modifier flags.


>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list