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.