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,