From e5e820fd1f9a5d788798072f1d2a60f7cc798f70 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 4 Nov 2002 15:13:36 +0000 Subject: [PATCH] Permit MAC policies to instrument the access control decisions for system accounting configuration and for nfsd server thread attach. Policies might use this to protect the integrity or confidentiality of accounting data, limit the ability to turn on or off accounting, as well as to prevent inappropriately labeled threads from becoming nfs server threads. Obtained from: TrustedBSD Project Sponsored by: DARPA, Network Associates Laboratories --- sys/kern/kern_acct.c | 16 ++++++++++++++++ sys/kern/kern_mac.c | 31 +++++++++++++++++++++++++++++++ sys/modules/nfsserver/Makefile | 1 + sys/nfsserver/nfs_syscalls.c | 11 +++++++++-- sys/security/mac/mac_framework.c | 31 +++++++++++++++++++++++++++++++ sys/security/mac/mac_framework.h | 2 ++ sys/security/mac/mac_internal.h | 31 +++++++++++++++++++++++++++++++ sys/security/mac/mac_net.c | 31 +++++++++++++++++++++++++++++++ sys/security/mac/mac_pipe.c | 31 +++++++++++++++++++++++++++++++ sys/security/mac/mac_policy.h | 3 +++ sys/security/mac/mac_process.c | 31 +++++++++++++++++++++++++++++++ sys/security/mac/mac_syscalls.c | 31 +++++++++++++++++++++++++++++++ sys/security/mac/mac_system.c | 31 +++++++++++++++++++++++++++++++ sys/security/mac/mac_vfs.c | 31 +++++++++++++++++++++++++++++++ sys/sys/mac.h | 2 ++ sys/sys/mac_policy.h | 3 +++ 16 files changed, 315 insertions(+), 2 deletions(-) diff --git a/sys/kern/kern_acct.c b/sys/kern/kern_acct.c index 9707caf1d616..91b0748d877a 100644 --- a/sys/kern/kern_acct.c +++ b/sys/kern/kern_acct.c @@ -40,12 +40,15 @@ * $FreeBSD$ */ +#include "opt_mac.h" + #include #include #include #include #include #include +#include #include #include #include @@ -144,12 +147,25 @@ acct(td, uap) if (error) goto done2; NDFREE(&nd, NDF_ONLY_PNBUF); +#ifdef MAC + error = mac_check_system_acct(td->td_ucred, nd.ni_vp); + if (error) { + vn_close(nd.ni_vp, flags, td->td_ucred, td); + goto done2; + } +#endif VOP_UNLOCK(nd.ni_vp, 0, td); if (nd.ni_vp->v_type != VREG) { vn_close(nd.ni_vp, flags, td->td_ucred, td); error = EACCES; goto done2; } +#ifdef MAC + } else { + error = mac_check_system_acct(td->td_ucred, NULL); + if (error) + goto done2; +#endif } /* diff --git a/sys/kern/kern_mac.c b/sys/kern/kern_mac.c index d36fbea5096c..64b6f09ad5b7 100644 --- a/sys/kern/kern_mac.c +++ b/sys/kern/kern_mac.c @@ -2469,6 +2469,37 @@ mac_check_socket_visible(struct ucred *cred, struct socket *socket) return (error); } +int +mac_check_system_acct(struct ucred *cred, struct vnode *vp) +{ + int error; + + if (vp != NULL) { + ASSERT_VOP_LOCKED(vp, "mac_check_system_acct"); + } + + if (!mac_enforce_system) + return (0); + + MAC_CHECK(check_system_acct, cred, vp, + vp != NULL ? &vp->v_label : NULL); + + return (error); +} + +int +mac_check_system_nfsd(struct ucred *cred) +{ + int error; + + if (!mac_enforce_system) + return (0); + + MAC_CHECK(check_system_nfsd, cred); + + return (error); +} + int mac_check_system_reboot(struct ucred *cred, int howto) { diff --git a/sys/modules/nfsserver/Makefile b/sys/modules/nfsserver/Makefile index e57ac6eea88c..fb9d0f2dae09 100644 --- a/sys/modules/nfsserver/Makefile +++ b/sys/modules/nfsserver/Makefile @@ -5,6 +5,7 @@ KMOD= nfsserver SRCS= vnode_if.h \ nfs_serv.c nfs_srvsock.c nfs_srvcache.c nfs_srvsubs.c nfs_syscalls.c \ nfs_common.c \ + opt_mac.h \ opt_nfs.h SRCS+= opt_inet6.h NFS_INET6?= 1 # 0/1 - requires INET6 to be configured in kernel diff --git a/sys/nfsserver/nfs_syscalls.c b/sys/nfsserver/nfs_syscalls.c index 10e0ed2aced7..80271cd106b6 100644 --- a/sys/nfsserver/nfs_syscalls.c +++ b/sys/nfsserver/nfs_syscalls.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include "opt_inet6.h" +#include "opt_mac.h" #include #include @@ -50,6 +51,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -137,10 +139,15 @@ nfssvc(struct thread *td, struct nfssvc_args *uap) struct nfsd_args nfsdarg; int error; - mtx_lock(&Giant); +#ifdef MAC + error = mac_check_system_nfsd(td->td_ucred); + if (error) + return (error); +#endif error = suser(td); if (error) - goto done2; + return (error); + mtx_lock(&Giant); while (nfssvc_sockhead_flag & SLP_INIT) { nfssvc_sockhead_flag |= SLP_WANTINIT; (void) tsleep((caddr_t)&nfssvc_sockhead, PSOCK, "nfsd init", 0); diff --git a/sys/security/mac/mac_framework.c b/sys/security/mac/mac_framework.c index d36fbea5096c..64b6f09ad5b7 100644 --- a/sys/security/mac/mac_framework.c +++ b/sys/security/mac/mac_framework.c @@ -2469,6 +2469,37 @@ mac_check_socket_visible(struct ucred *cred, struct socket *socket) return (error); } +int +mac_check_system_acct(struct ucred *cred, struct vnode *vp) +{ + int error; + + if (vp != NULL) { + ASSERT_VOP_LOCKED(vp, "mac_check_system_acct"); + } + + if (!mac_enforce_system) + return (0); + + MAC_CHECK(check_system_acct, cred, vp, + vp != NULL ? &vp->v_label : NULL); + + return (error); +} + +int +mac_check_system_nfsd(struct ucred *cred) +{ + int error; + + if (!mac_enforce_system) + return (0); + + MAC_CHECK(check_system_nfsd, cred); + + return (error); +} + int mac_check_system_reboot(struct ucred *cred, int howto) { diff --git a/sys/security/mac/mac_framework.h b/sys/security/mac/mac_framework.h index 9a27097a9535..904ead3e223b 100644 --- a/sys/security/mac/mac_framework.h +++ b/sys/security/mac/mac_framework.h @@ -251,6 +251,8 @@ int mac_check_socket_listen(struct ucred *cred, struct socket *so); int mac_check_socket_receive(struct ucred *cred, struct socket *so); int mac_check_socket_send(struct ucred *cred, struct socket *so); int mac_check_socket_visible(struct ucred *cred, struct socket *so); +int mac_check_system_acct(struct ucred *cred, struct vnode *vp); +int mac_check_system_nfsd(struct ucred *cred); int mac_check_system_reboot(struct ucred *cred, int howto); int mac_check_system_settime(struct ucred *cred); int mac_check_system_swapon(struct ucred *cred, struct vnode *vp); diff --git a/sys/security/mac/mac_internal.h b/sys/security/mac/mac_internal.h index d36fbea5096c..64b6f09ad5b7 100644 --- a/sys/security/mac/mac_internal.h +++ b/sys/security/mac/mac_internal.h @@ -2469,6 +2469,37 @@ mac_check_socket_visible(struct ucred *cred, struct socket *socket) return (error); } +int +mac_check_system_acct(struct ucred *cred, struct vnode *vp) +{ + int error; + + if (vp != NULL) { + ASSERT_VOP_LOCKED(vp, "mac_check_system_acct"); + } + + if (!mac_enforce_system) + return (0); + + MAC_CHECK(check_system_acct, cred, vp, + vp != NULL ? &vp->v_label : NULL); + + return (error); +} + +int +mac_check_system_nfsd(struct ucred *cred) +{ + int error; + + if (!mac_enforce_system) + return (0); + + MAC_CHECK(check_system_nfsd, cred); + + return (error); +} + int mac_check_system_reboot(struct ucred *cred, int howto) { diff --git a/sys/security/mac/mac_net.c b/sys/security/mac/mac_net.c index d36fbea5096c..64b6f09ad5b7 100644 --- a/sys/security/mac/mac_net.c +++ b/sys/security/mac/mac_net.c @@ -2469,6 +2469,37 @@ mac_check_socket_visible(struct ucred *cred, struct socket *socket) return (error); } +int +mac_check_system_acct(struct ucred *cred, struct vnode *vp) +{ + int error; + + if (vp != NULL) { + ASSERT_VOP_LOCKED(vp, "mac_check_system_acct"); + } + + if (!mac_enforce_system) + return (0); + + MAC_CHECK(check_system_acct, cred, vp, + vp != NULL ? &vp->v_label : NULL); + + return (error); +} + +int +mac_check_system_nfsd(struct ucred *cred) +{ + int error; + + if (!mac_enforce_system) + return (0); + + MAC_CHECK(check_system_nfsd, cred); + + return (error); +} + int mac_check_system_reboot(struct ucred *cred, int howto) { diff --git a/sys/security/mac/mac_pipe.c b/sys/security/mac/mac_pipe.c index d36fbea5096c..64b6f09ad5b7 100644 --- a/sys/security/mac/mac_pipe.c +++ b/sys/security/mac/mac_pipe.c @@ -2469,6 +2469,37 @@ mac_check_socket_visible(struct ucred *cred, struct socket *socket) return (error); } +int +mac_check_system_acct(struct ucred *cred, struct vnode *vp) +{ + int error; + + if (vp != NULL) { + ASSERT_VOP_LOCKED(vp, "mac_check_system_acct"); + } + + if (!mac_enforce_system) + return (0); + + MAC_CHECK(check_system_acct, cred, vp, + vp != NULL ? &vp->v_label : NULL); + + return (error); +} + +int +mac_check_system_nfsd(struct ucred *cred) +{ + int error; + + if (!mac_enforce_system) + return (0); + + MAC_CHECK(check_system_nfsd, cred); + + return (error); +} + int mac_check_system_reboot(struct ucred *cred, int howto) { diff --git a/sys/security/mac/mac_policy.h b/sys/security/mac/mac_policy.h index 53bf0ac416f5..fff7845984cf 100644 --- a/sys/security/mac/mac_policy.h +++ b/sys/security/mac/mac_policy.h @@ -312,6 +312,9 @@ struct mac_policy_ops { struct socket *so, struct label *socketlabel); int (*mpo_check_socket_visible)(struct ucred *cred, struct socket *so, struct label *socketlabel); + int (*mpo_check_system_acct)(struct ucred *cred, + struct vnode *vp, struct label *vlabel); + int (*mpo_check_system_nfsd)(struct ucred *cred); int (*mpo_check_system_reboot)(struct ucred *cred, int howto); int (*mpo_check_system_settime)(struct ucred *cred); int (*mpo_check_system_swapon)(struct ucred *cred, diff --git a/sys/security/mac/mac_process.c b/sys/security/mac/mac_process.c index d36fbea5096c..64b6f09ad5b7 100644 --- a/sys/security/mac/mac_process.c +++ b/sys/security/mac/mac_process.c @@ -2469,6 +2469,37 @@ mac_check_socket_visible(struct ucred *cred, struct socket *socket) return (error); } +int +mac_check_system_acct(struct ucred *cred, struct vnode *vp) +{ + int error; + + if (vp != NULL) { + ASSERT_VOP_LOCKED(vp, "mac_check_system_acct"); + } + + if (!mac_enforce_system) + return (0); + + MAC_CHECK(check_system_acct, cred, vp, + vp != NULL ? &vp->v_label : NULL); + + return (error); +} + +int +mac_check_system_nfsd(struct ucred *cred) +{ + int error; + + if (!mac_enforce_system) + return (0); + + MAC_CHECK(check_system_nfsd, cred); + + return (error); +} + int mac_check_system_reboot(struct ucred *cred, int howto) { diff --git a/sys/security/mac/mac_syscalls.c b/sys/security/mac/mac_syscalls.c index d36fbea5096c..64b6f09ad5b7 100644 --- a/sys/security/mac/mac_syscalls.c +++ b/sys/security/mac/mac_syscalls.c @@ -2469,6 +2469,37 @@ mac_check_socket_visible(struct ucred *cred, struct socket *socket) return (error); } +int +mac_check_system_acct(struct ucred *cred, struct vnode *vp) +{ + int error; + + if (vp != NULL) { + ASSERT_VOP_LOCKED(vp, "mac_check_system_acct"); + } + + if (!mac_enforce_system) + return (0); + + MAC_CHECK(check_system_acct, cred, vp, + vp != NULL ? &vp->v_label : NULL); + + return (error); +} + +int +mac_check_system_nfsd(struct ucred *cred) +{ + int error; + + if (!mac_enforce_system) + return (0); + + MAC_CHECK(check_system_nfsd, cred); + + return (error); +} + int mac_check_system_reboot(struct ucred *cred, int howto) { diff --git a/sys/security/mac/mac_system.c b/sys/security/mac/mac_system.c index d36fbea5096c..64b6f09ad5b7 100644 --- a/sys/security/mac/mac_system.c +++ b/sys/security/mac/mac_system.c @@ -2469,6 +2469,37 @@ mac_check_socket_visible(struct ucred *cred, struct socket *socket) return (error); } +int +mac_check_system_acct(struct ucred *cred, struct vnode *vp) +{ + int error; + + if (vp != NULL) { + ASSERT_VOP_LOCKED(vp, "mac_check_system_acct"); + } + + if (!mac_enforce_system) + return (0); + + MAC_CHECK(check_system_acct, cred, vp, + vp != NULL ? &vp->v_label : NULL); + + return (error); +} + +int +mac_check_system_nfsd(struct ucred *cred) +{ + int error; + + if (!mac_enforce_system) + return (0); + + MAC_CHECK(check_system_nfsd, cred); + + return (error); +} + int mac_check_system_reboot(struct ucred *cred, int howto) { diff --git a/sys/security/mac/mac_vfs.c b/sys/security/mac/mac_vfs.c index d36fbea5096c..64b6f09ad5b7 100644 --- a/sys/security/mac/mac_vfs.c +++ b/sys/security/mac/mac_vfs.c @@ -2469,6 +2469,37 @@ mac_check_socket_visible(struct ucred *cred, struct socket *socket) return (error); } +int +mac_check_system_acct(struct ucred *cred, struct vnode *vp) +{ + int error; + + if (vp != NULL) { + ASSERT_VOP_LOCKED(vp, "mac_check_system_acct"); + } + + if (!mac_enforce_system) + return (0); + + MAC_CHECK(check_system_acct, cred, vp, + vp != NULL ? &vp->v_label : NULL); + + return (error); +} + +int +mac_check_system_nfsd(struct ucred *cred) +{ + int error; + + if (!mac_enforce_system) + return (0); + + MAC_CHECK(check_system_nfsd, cred); + + return (error); +} + int mac_check_system_reboot(struct ucred *cred, int howto) { diff --git a/sys/sys/mac.h b/sys/sys/mac.h index 9a27097a9535..904ead3e223b 100644 --- a/sys/sys/mac.h +++ b/sys/sys/mac.h @@ -251,6 +251,8 @@ int mac_check_socket_listen(struct ucred *cred, struct socket *so); int mac_check_socket_receive(struct ucred *cred, struct socket *so); int mac_check_socket_send(struct ucred *cred, struct socket *so); int mac_check_socket_visible(struct ucred *cred, struct socket *so); +int mac_check_system_acct(struct ucred *cred, struct vnode *vp); +int mac_check_system_nfsd(struct ucred *cred); int mac_check_system_reboot(struct ucred *cred, int howto); int mac_check_system_settime(struct ucred *cred); int mac_check_system_swapon(struct ucred *cred, struct vnode *vp); diff --git a/sys/sys/mac_policy.h b/sys/sys/mac_policy.h index 53bf0ac416f5..fff7845984cf 100644 --- a/sys/sys/mac_policy.h +++ b/sys/sys/mac_policy.h @@ -312,6 +312,9 @@ struct mac_policy_ops { struct socket *so, struct label *socketlabel); int (*mpo_check_socket_visible)(struct ucred *cred, struct socket *so, struct label *socketlabel); + int (*mpo_check_system_acct)(struct ucred *cred, + struct vnode *vp, struct label *vlabel); + int (*mpo_check_system_nfsd)(struct ucred *cred); int (*mpo_check_system_reboot)(struct ucred *cred, int howto); int (*mpo_check_system_settime)(struct ucred *cred); int (*mpo_check_system_swapon)(struct ucred *cred,