>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     r...@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:
_______________________________________________
freebsd-bugs@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"

Reply via email to