Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F146589763
D55601.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D55601.diff
View Options
diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c
--- a/sys/kern/vfs_mount.c
+++ b/sys/kern/vfs_mount.c
@@ -1152,6 +1152,17 @@
error = VOP_GETATTR(vp, &va, td->td_ucred);
if (error == 0 && va.va_uid != td->td_ucred->cr_uid)
error = priv_check_cred(td->td_ucred, PRIV_VFS_ADMIN);
+#ifdef MAC
+ /*
+ * XXX XNU also has a check_mount_late variant, which takes the
+ * struct mount instead and gives MAC visibility into, e.g.,
+ * f_mntfromname and other facts.
+ */
+ if (error == 0) {
+ error = mac_mount_check_mount(td->td_ucred, vp, vfsp,
+ optlist, fsflags);
+ }
+#endif
if (error == 0)
error = vinvalbuf(vp, V_SAVE, 0, 0);
if (vfsp->vfc_flags & VFCF_FILEMOUNT) {
@@ -1371,6 +1382,12 @@
error = 0;
vfs_suser_failed = true;
}
+#ifdef MAC
+ if (error == 0) {
+ error = mac_mount_check_update(td->td_ucred, mp, optlist,
+ fsflags);
+ }
+#endif
if (error != 0) {
vput(vp);
return (error);
@@ -1750,7 +1767,6 @@
if (error)
return (error);
}
-
if (flags & MNT_BYFSID) {
fsidbuf = malloc(MNAMELEN, M_TEMP, M_WAITOK);
error = copyinstr(path, fsidbuf, MNAMELEN, NULL);
@@ -1818,6 +1834,13 @@
vfs_rel(mp);
return (EINVAL);
}
+#ifdef MAC
+ error = mac_mount_check_unmount(td->td_ucred, mp, flags);
+ if (error != 0) {
+ vfs_rel(mp);
+ return (error);
+ }
+#endif
error = dounmount(mp, flags, td);
return (error);
}
diff --git a/sys/security/mac/mac_framework.h b/sys/security/mac/mac_framework.h
--- a/sys/security/mac/mac_framework.h
+++ b/sys/security/mac/mac_framework.h
@@ -86,6 +86,7 @@
struct timespec;
struct ucred;
struct vattr;
+struct vfsconf;
struct vfsoptlist;
struct vnode;
struct vop_setlabel_args;
@@ -248,6 +249,12 @@
void mac_mount_create(struct ucred *cred, struct mount *mp);
void mac_mount_destroy(struct mount *);
void mac_mount_init(struct mount *);
+int mac_mount_check_mount(struct ucred *cred, struct vnode *vp,
+ struct vfsconf *, struct vfsoptlist **optlist, uint64_t fsflags);
+int mac_mount_check_update(struct ucred *cred, struct mount *mp,
+ struct vfsoptlist **optlist, uint64_t fsflags);
+int mac_mount_check_unmount(struct ucred *cred, struct mount *mp,
+ uint64_t flags);
void mac_netinet_arp_send(struct ifnet *ifp, struct mbuf *m);
void mac_netinet_firewall_reply(struct mbuf *mrecv, struct mbuf *msend);
diff --git a/sys/security/mac/mac_policy.h b/sys/security/mac/mac_policy.h
--- a/sys/security/mac/mac_policy.h
+++ b/sys/security/mac/mac_policy.h
@@ -101,6 +101,7 @@
struct thread;
struct ucred;
struct vattr;
+struct vfsconf;
struct vfsoptlist;
struct vnode;
@@ -295,6 +296,14 @@
struct label *mplabel);
typedef void (*mpo_mount_destroy_label_t)(struct label *label);
typedef void (*mpo_mount_init_label_t)(struct label *label);
+typedef int (*mpo_mount_check_mount_t)(struct ucred *cred, struct vnode *vp,
+ struct label *vplabel, struct vfsconf *vfsp,
+ struct vfsoptlist **optlist, uint64_t fsflags);
+typedef int (*mpo_mount_check_update_t)(struct ucred *cred,
+ struct mount *mp, struct label *mplabel,
+ struct vfsoptlist **optlist, uint64_t fsflags);
+typedef int (*mpo_mount_check_unmount_t)(struct ucred *cred,
+ struct mount *mp, struct label *mplabel, uint64_t flags);
typedef void (*mpo_netinet_arp_send_t)(struct ifnet *ifp,
struct label *ifplabel, struct mbuf *m,
@@ -846,6 +855,9 @@
mpo_mount_create_t mpo_mount_create;
mpo_mount_destroy_label_t mpo_mount_destroy_label;
mpo_mount_init_label_t mpo_mount_init_label;
+ mpo_mount_check_mount_t mpo_mount_check_mount;
+ mpo_mount_check_update_t mpo_mount_check_update;
+ mpo_mount_check_unmount_t mpo_mount_check_unmount;
mpo_netinet_arp_send_t mpo_netinet_arp_send;
mpo_netinet_firewall_reply_t mpo_netinet_firewall_reply;
diff --git a/sys/security/mac/mac_vfs.c b/sys/security/mac/mac_vfs.c
--- a/sys/security/mac/mac_vfs.c
+++ b/sys/security/mac/mac_vfs.c
@@ -123,6 +123,56 @@
mp->mnt_label = NULL;
}
+/*
+ * SDT doesn't have a PROBE7 version anymore, so we just drop the label.
+ */
+MAC_CHECK_PROBE_DEFINE5(mount_check_mount, "struct ucred *",
+ "struct vnode *", "struct vfsconf *",
+ "struct vfsoptlist **", "uint64_t");
+int
+mac_mount_check_mount(struct ucred *cred, struct vnode *vp,
+ struct vfsconf *vfsp, struct vfsoptlist **optlist, uint64_t fsflags)
+{
+ int error;
+
+ MAC_POLICY_CHECK(mount_check_mount, cred, vp, vp->v_label, vfsp,
+ optlist, fsflags);
+ MAC_CHECK_PROBE5(mount_check_mount, error, cred, vp, vfsp, optlist,
+ fsflags);
+
+ return (error);
+}
+
+MAC_CHECK_PROBE_DEFINE5(mount_check_update, "struct ucred *",
+ "struct mount *", "struct label *", "struct vfsoptlist **", "uint64_t");
+int
+mac_mount_check_update(struct ucred *cred, struct mount *mp,
+ struct vfsoptlist **optlist, uint64_t fsflags)
+{
+ int error;
+
+ MAC_POLICY_CHECK(mount_check_update, cred, mp, mp->mnt_label,
+ optlist, fsflags);
+ MAC_CHECK_PROBE5(mount_check_update, error, cred, mp, mp->mnt_label,
+ optlist, fsflags);
+
+ return (error);
+}
+
+MAC_CHECK_PROBE_DEFINE4(mount_check_unmount, "struct ucred *",
+ "struct mount *", "struct label *", "uint64_t");
+int
+mac_mount_check_unmount(struct ucred *cred, struct mount *mp, uint64_t flags)
+{
+ int error;
+
+ MAC_POLICY_CHECK(mount_check_unmount, cred, mp, mp->mnt_label, flags);
+ MAC_CHECK_PROBE4(mount_check_unmount, error, cred, mp, mp->mnt_label,
+ flags);
+
+ return (error);
+}
+
struct label *
mac_vnode_label_alloc(void)
{
diff --git a/sys/security/mac_stub/mac_stub.c b/sys/security/mac_stub/mac_stub.c
--- a/sys/security/mac_stub/mac_stub.c
+++ b/sys/security/mac_stub/mac_stub.c
@@ -574,6 +574,31 @@
}
+static int
+stub_mount_check_mount(struct ucred *cred, struct vnode *vp,
+ struct label *vplabel, struct vfsconf *vfsconf,
+ struct vfsoptlist **optlist, uint64_t fsflags)
+{
+
+ return (0);
+}
+
+static int
+stub_mount_check_update(struct ucred *cred, struct mount *mp,
+ struct label *mplabel, struct vfsoptlist **optlist, uint64_t fsflags)
+{
+
+ return (0);
+}
+
+static int
+stub_mount_check_unmount(struct ucred *cred, struct mount *mp,
+ struct label *mplabel, uint64_t flags)
+{
+
+ return (0);
+}
+
static void
stub_netinet_arp_send(struct ifnet *ifp, struct label *iflpabel,
struct mbuf *m, struct label *mlabel)
@@ -1864,6 +1889,9 @@
.mpo_mount_create = stub_mount_create,
.mpo_mount_destroy_label = stub_destroy_label,
.mpo_mount_init_label = stub_init_label,
+ .mpo_mount_check_mount = stub_mount_check_mount,
+ .mpo_mount_check_update = stub_mount_check_update,
+ .mpo_mount_check_unmount = stub_mount_check_unmount,
.mpo_netinet_arp_send = stub_netinet_arp_send,
.mpo_netinet_firewall_reply = stub_netinet_firewall_reply,
diff --git a/sys/security/mac_test/mac_test.c b/sys/security/mac_test/mac_test.c
--- a/sys/security/mac_test/mac_test.c
+++ b/sys/security/mac_test/mac_test.c
@@ -1078,6 +1078,40 @@
COUNTER_INC(mount_init_label);
}
+COUNTER_DECL(mount_check_mount);
+static int
+test_mount_check_mount(struct ucred *cred, struct vnode *vp,
+ struct label *vplabel, struct vfsconf *vfsconf,
+ struct vfsoptlist **optlist, uint64_t fsflags)
+{
+
+ LABEL_CHECK(vplabel, MAGIC_VNODE);
+ COUNTER_INC(mount_check_mount);
+ return (0);
+}
+
+COUNTER_DECL(mount_check_update);
+static int
+test_mount_check_update(struct ucred *cred, struct mount *mp,
+ struct label *mplabel, struct vfsoptlist **optlist, uint64_t fsflags)
+{
+
+ LABEL_CHECK(mplabel, MAGIC_MOUNT);
+ COUNTER_INC(mount_check_update);
+ return (0);
+}
+
+COUNTER_DECL(mount_check_unmount);
+static int
+test_mount_check_unmount(struct ucred *cred, struct mount *mp,
+ struct label *mplabel, uint64_t flags)
+{
+
+ LABEL_CHECK(mplabel, MAGIC_MOUNT);
+ COUNTER_INC(mount_check_unmount);
+ return (0);
+}
+
COUNTER_DECL(netinet_arp_send);
static void
test_netinet_arp_send(struct ifnet *ifp, struct label *ifplabel,
@@ -3323,6 +3357,9 @@
.mpo_mount_create = test_mount_create,
.mpo_mount_destroy_label = test_mount_destroy_label,
.mpo_mount_init_label = test_mount_init_label,
+ .mpo_mount_check_mount = test_mount_check_mount,
+ .mpo_mount_check_update = test_mount_check_update,
+ .mpo_mount_check_unmount = test_mount_check_unmount,
.mpo_netinet_arp_send = test_netinet_arp_send,
.mpo_netinet_fragment = test_netinet_fragment,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Mar 4, 9:59 PM (3 h, 8 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29257521
Default Alt Text
D55601.diff (8 KB)
Attached To
Mode
D55601: kern: vfs: add MAC checks for mount/unmount/update
Attached
Detach File
Event Timeline
Log In to Comment