Implement mac_check_system_sysctl(), a MAC Framework entry point to

permit MAC policies to augment the security protections on sysctl()
operations.  This is not really a wonderful entry point, as we
only have access to the MIB of the target sysctl entry, rather than
the more useful entry name, but this is sufficient for policies
like Biba that wish to use their notions of privilege or integrity
to prevent inappropriate sysctl modification.  Affects MAC kernels
only.  Since SYSCTL_LOCK isn't in sysctl.h, just kern_sysctl.c,
we can't assert the SYSCTL subsystem lockin the MAC Framework.

Approved by:	re
Obtained from:	TrustedBSD Project
Sponsored by:	DARPA, Network Associates Laboratories
This commit is contained in:
rwatson 2002-10-27 07:12:34 +00:00
parent be98961ae9
commit 653f637c44
14 changed files with 277 additions and 0 deletions

View File

@ -151,6 +151,11 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW,
&mac_enforce_socket, 0, "Enforce MAC policy on socket operations");
TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket);
static int mac_enforce_sysctl = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_sysctl, CTLFLAG_RW,
&mac_enforce_sysctl, 0, "Enforce MAC policy on sysctl operations");
TUNABLE_INT("security.mac.enforce_sysctl", &mac_enforce_sysctl);
static int mac_enforce_vm = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW,
&mac_enforce_vm, 0, "Enforce MAC policy on vm operations");
@ -912,6 +917,10 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_check_system_swapon =
mpe->mpe_function;
break;
case MAC_CHECK_SYSTEM_SYSCTL:
mpc->mpc_ops->mpo_check_system_sysctl =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_ACCESS:
mpc->mpc_ops->mpo_check_vnode_access =
mpe->mpe_function;
@ -3033,6 +3042,25 @@ mac_check_system_swapon(struct ucred *cred, struct vnode *vp)
return (error);
}
int
mac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
{
int error;
/*
* XXXMAC: We're very much like to assert the SYSCTL_LOCK here,
* but since it's not exported from kern_sysctl.c, we can't.
*/
if (!mac_enforce_sysctl)
return (0);
MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp,
inkernel, new, newlen);
return (error);
}
int
mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
struct ifnet *ifnet)

View File

@ -41,11 +41,13 @@
*/
#include "opt_compat.h"
#include "opt_mac.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
#include <sys/mac.h>
#include <sys/malloc.h>
#include <sys/proc.h>
#include <sys/lock.h>
@ -1238,6 +1240,15 @@ userland_sysctl(struct thread *td, int *name, u_int namelen, void *old,
SYSCTL_LOCK();
#ifdef MAC
error = mac_check_system_sysctl(td->td_ucred, name, namelen, old,
oldlenp, inkernel, new, newlen);
if (error) {
SYSCTL_UNLOCK();
return (error);
}
#endif
do {
req2 = req;
error = sysctl_root(0, name, namelen, &req2);

View File

@ -151,6 +151,11 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW,
&mac_enforce_socket, 0, "Enforce MAC policy on socket operations");
TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket);
static int mac_enforce_sysctl = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_sysctl, CTLFLAG_RW,
&mac_enforce_sysctl, 0, "Enforce MAC policy on sysctl operations");
TUNABLE_INT("security.mac.enforce_sysctl", &mac_enforce_sysctl);
static int mac_enforce_vm = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW,
&mac_enforce_vm, 0, "Enforce MAC policy on vm operations");
@ -912,6 +917,10 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_check_system_swapon =
mpe->mpe_function;
break;
case MAC_CHECK_SYSTEM_SYSCTL:
mpc->mpc_ops->mpo_check_system_sysctl =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_ACCESS:
mpc->mpc_ops->mpo_check_vnode_access =
mpe->mpe_function;
@ -3033,6 +3042,25 @@ mac_check_system_swapon(struct ucred *cred, struct vnode *vp)
return (error);
}
int
mac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
{
int error;
/*
* XXXMAC: We're very much like to assert the SYSCTL_LOCK here,
* but since it's not exported from kern_sysctl.c, we can't.
*/
if (!mac_enforce_sysctl)
return (0);
MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp,
inkernel, new, newlen);
return (error);
}
int
mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
struct ifnet *ifnet)

View File

@ -299,6 +299,9 @@ 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_reboot(struct ucred *cred, int howto);
int mac_check_system_swapon(struct ucred *cred, struct vnode *vp);
int mac_check_system_sysctl(struct ucred *cred, int *name,
u_int namelen, void *old, size_t *oldlenp, int inkernel,
void *new, size_t newlen);
int mac_check_vnode_access(struct ucred *cred, struct vnode *vp,
int flags);
int mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp);

View File

@ -151,6 +151,11 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW,
&mac_enforce_socket, 0, "Enforce MAC policy on socket operations");
TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket);
static int mac_enforce_sysctl = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_sysctl, CTLFLAG_RW,
&mac_enforce_sysctl, 0, "Enforce MAC policy on sysctl operations");
TUNABLE_INT("security.mac.enforce_sysctl", &mac_enforce_sysctl);
static int mac_enforce_vm = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW,
&mac_enforce_vm, 0, "Enforce MAC policy on vm operations");
@ -912,6 +917,10 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_check_system_swapon =
mpe->mpe_function;
break;
case MAC_CHECK_SYSTEM_SYSCTL:
mpc->mpc_ops->mpo_check_system_sysctl =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_ACCESS:
mpc->mpc_ops->mpo_check_vnode_access =
mpe->mpe_function;
@ -3033,6 +3042,25 @@ mac_check_system_swapon(struct ucred *cred, struct vnode *vp)
return (error);
}
int
mac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
{
int error;
/*
* XXXMAC: We're very much like to assert the SYSCTL_LOCK here,
* but since it's not exported from kern_sysctl.c, we can't.
*/
if (!mac_enforce_sysctl)
return (0);
MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp,
inkernel, new, newlen);
return (error);
}
int
mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
struct ifnet *ifnet)

View File

@ -151,6 +151,11 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW,
&mac_enforce_socket, 0, "Enforce MAC policy on socket operations");
TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket);
static int mac_enforce_sysctl = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_sysctl, CTLFLAG_RW,
&mac_enforce_sysctl, 0, "Enforce MAC policy on sysctl operations");
TUNABLE_INT("security.mac.enforce_sysctl", &mac_enforce_sysctl);
static int mac_enforce_vm = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW,
&mac_enforce_vm, 0, "Enforce MAC policy on vm operations");
@ -912,6 +917,10 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_check_system_swapon =
mpe->mpe_function;
break;
case MAC_CHECK_SYSTEM_SYSCTL:
mpc->mpc_ops->mpo_check_system_sysctl =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_ACCESS:
mpc->mpc_ops->mpo_check_vnode_access =
mpe->mpe_function;
@ -3033,6 +3042,25 @@ mac_check_system_swapon(struct ucred *cred, struct vnode *vp)
return (error);
}
int
mac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
{
int error;
/*
* XXXMAC: We're very much like to assert the SYSCTL_LOCK here,
* but since it's not exported from kern_sysctl.c, we can't.
*/
if (!mac_enforce_sysctl)
return (0);
MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp,
inkernel, new, newlen);
return (error);
}
int
mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
struct ifnet *ifnet)

View File

@ -151,6 +151,11 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW,
&mac_enforce_socket, 0, "Enforce MAC policy on socket operations");
TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket);
static int mac_enforce_sysctl = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_sysctl, CTLFLAG_RW,
&mac_enforce_sysctl, 0, "Enforce MAC policy on sysctl operations");
TUNABLE_INT("security.mac.enforce_sysctl", &mac_enforce_sysctl);
static int mac_enforce_vm = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW,
&mac_enforce_vm, 0, "Enforce MAC policy on vm operations");
@ -912,6 +917,10 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_check_system_swapon =
mpe->mpe_function;
break;
case MAC_CHECK_SYSTEM_SYSCTL:
mpc->mpc_ops->mpo_check_system_sysctl =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_ACCESS:
mpc->mpc_ops->mpo_check_vnode_access =
mpe->mpe_function;
@ -3033,6 +3042,25 @@ mac_check_system_swapon(struct ucred *cred, struct vnode *vp)
return (error);
}
int
mac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
{
int error;
/*
* XXXMAC: We're very much like to assert the SYSCTL_LOCK here,
* but since it's not exported from kern_sysctl.c, we can't.
*/
if (!mac_enforce_sysctl)
return (0);
MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp,
inkernel, new, newlen);
return (error);
}
int
mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
struct ifnet *ifnet)

View File

@ -313,6 +313,9 @@ struct mac_policy_ops {
int (*mpo_check_system_reboot)(struct ucred *cred, int howto);
int (*mpo_check_system_swapon)(struct ucred *cred,
struct vnode *vp, struct label *label);
int (*mpo_check_system_sysctl)(struct ucred *cred, int *name,
u_int namelen, void *old, size_t *oldlenp, int inkernel,
void *new, size_t newlen);
int (*mpo_check_vnode_access)(struct ucred *cred,
struct vnode *vp, struct label *label, int flags);
int (*mpo_check_vnode_chdir)(struct ucred *cred,
@ -505,6 +508,7 @@ enum mac_op_constant {
MAC_CHECK_SOCKET_VISIBLE,
MAC_CHECK_SYSTEM_REBOOT,
MAC_CHECK_SYSTEM_SWAPON,
MAC_CHECK_SYSTEM_SYSCTL,
MAC_CHECK_VNODE_ACCESS,
MAC_CHECK_VNODE_CHDIR,
MAC_CHECK_VNODE_CHROOT,

View File

@ -151,6 +151,11 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW,
&mac_enforce_socket, 0, "Enforce MAC policy on socket operations");
TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket);
static int mac_enforce_sysctl = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_sysctl, CTLFLAG_RW,
&mac_enforce_sysctl, 0, "Enforce MAC policy on sysctl operations");
TUNABLE_INT("security.mac.enforce_sysctl", &mac_enforce_sysctl);
static int mac_enforce_vm = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW,
&mac_enforce_vm, 0, "Enforce MAC policy on vm operations");
@ -912,6 +917,10 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_check_system_swapon =
mpe->mpe_function;
break;
case MAC_CHECK_SYSTEM_SYSCTL:
mpc->mpc_ops->mpo_check_system_sysctl =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_ACCESS:
mpc->mpc_ops->mpo_check_vnode_access =
mpe->mpe_function;
@ -3033,6 +3042,25 @@ mac_check_system_swapon(struct ucred *cred, struct vnode *vp)
return (error);
}
int
mac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
{
int error;
/*
* XXXMAC: We're very much like to assert the SYSCTL_LOCK here,
* but since it's not exported from kern_sysctl.c, we can't.
*/
if (!mac_enforce_sysctl)
return (0);
MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp,
inkernel, new, newlen);
return (error);
}
int
mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
struct ifnet *ifnet)

View File

@ -151,6 +151,11 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW,
&mac_enforce_socket, 0, "Enforce MAC policy on socket operations");
TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket);
static int mac_enforce_sysctl = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_sysctl, CTLFLAG_RW,
&mac_enforce_sysctl, 0, "Enforce MAC policy on sysctl operations");
TUNABLE_INT("security.mac.enforce_sysctl", &mac_enforce_sysctl);
static int mac_enforce_vm = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW,
&mac_enforce_vm, 0, "Enforce MAC policy on vm operations");
@ -912,6 +917,10 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_check_system_swapon =
mpe->mpe_function;
break;
case MAC_CHECK_SYSTEM_SYSCTL:
mpc->mpc_ops->mpo_check_system_sysctl =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_ACCESS:
mpc->mpc_ops->mpo_check_vnode_access =
mpe->mpe_function;
@ -3033,6 +3042,25 @@ mac_check_system_swapon(struct ucred *cred, struct vnode *vp)
return (error);
}
int
mac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
{
int error;
/*
* XXXMAC: We're very much like to assert the SYSCTL_LOCK here,
* but since it's not exported from kern_sysctl.c, we can't.
*/
if (!mac_enforce_sysctl)
return (0);
MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp,
inkernel, new, newlen);
return (error);
}
int
mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
struct ifnet *ifnet)

View File

@ -151,6 +151,11 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW,
&mac_enforce_socket, 0, "Enforce MAC policy on socket operations");
TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket);
static int mac_enforce_sysctl = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_sysctl, CTLFLAG_RW,
&mac_enforce_sysctl, 0, "Enforce MAC policy on sysctl operations");
TUNABLE_INT("security.mac.enforce_sysctl", &mac_enforce_sysctl);
static int mac_enforce_vm = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW,
&mac_enforce_vm, 0, "Enforce MAC policy on vm operations");
@ -912,6 +917,10 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_check_system_swapon =
mpe->mpe_function;
break;
case MAC_CHECK_SYSTEM_SYSCTL:
mpc->mpc_ops->mpo_check_system_sysctl =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_ACCESS:
mpc->mpc_ops->mpo_check_vnode_access =
mpe->mpe_function;
@ -3033,6 +3042,25 @@ mac_check_system_swapon(struct ucred *cred, struct vnode *vp)
return (error);
}
int
mac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
{
int error;
/*
* XXXMAC: We're very much like to assert the SYSCTL_LOCK here,
* but since it's not exported from kern_sysctl.c, we can't.
*/
if (!mac_enforce_sysctl)
return (0);
MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp,
inkernel, new, newlen);
return (error);
}
int
mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
struct ifnet *ifnet)

View File

@ -151,6 +151,11 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_socket, CTLFLAG_RW,
&mac_enforce_socket, 0, "Enforce MAC policy on socket operations");
TUNABLE_INT("security.mac.enforce_socket", &mac_enforce_socket);
static int mac_enforce_sysctl = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_sysctl, CTLFLAG_RW,
&mac_enforce_sysctl, 0, "Enforce MAC policy on sysctl operations");
TUNABLE_INT("security.mac.enforce_sysctl", &mac_enforce_sysctl);
static int mac_enforce_vm = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_vm, CTLFLAG_RW,
&mac_enforce_vm, 0, "Enforce MAC policy on vm operations");
@ -912,6 +917,10 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_check_system_swapon =
mpe->mpe_function;
break;
case MAC_CHECK_SYSTEM_SYSCTL:
mpc->mpc_ops->mpo_check_system_sysctl =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_ACCESS:
mpc->mpc_ops->mpo_check_vnode_access =
mpe->mpe_function;
@ -3033,6 +3042,25 @@ mac_check_system_swapon(struct ucred *cred, struct vnode *vp)
return (error);
}
int
mac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
{
int error;
/*
* XXXMAC: We're very much like to assert the SYSCTL_LOCK here,
* but since it's not exported from kern_sysctl.c, we can't.
*/
if (!mac_enforce_sysctl)
return (0);
MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp,
inkernel, new, newlen);
return (error);
}
int
mac_ioctl_ifnet_get(struct ucred *cred, struct ifreq *ifr,
struct ifnet *ifnet)

View File

@ -299,6 +299,9 @@ 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_reboot(struct ucred *cred, int howto);
int mac_check_system_swapon(struct ucred *cred, struct vnode *vp);
int mac_check_system_sysctl(struct ucred *cred, int *name,
u_int namelen, void *old, size_t *oldlenp, int inkernel,
void *new, size_t newlen);
int mac_check_vnode_access(struct ucred *cred, struct vnode *vp,
int flags);
int mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp);

View File

@ -313,6 +313,9 @@ struct mac_policy_ops {
int (*mpo_check_system_reboot)(struct ucred *cred, int howto);
int (*mpo_check_system_swapon)(struct ucred *cred,
struct vnode *vp, struct label *label);
int (*mpo_check_system_sysctl)(struct ucred *cred, int *name,
u_int namelen, void *old, size_t *oldlenp, int inkernel,
void *new, size_t newlen);
int (*mpo_check_vnode_access)(struct ucred *cred,
struct vnode *vp, struct label *label, int flags);
int (*mpo_check_vnode_chdir)(struct ucred *cred,
@ -505,6 +508,7 @@ enum mac_op_constant {
MAC_CHECK_SOCKET_VISIBLE,
MAC_CHECK_SYSTEM_REBOOT,
MAC_CHECK_SYSTEM_SWAPON,
MAC_CHECK_SYSTEM_SYSCTL,
MAC_CHECK_VNODE_ACCESS,
MAC_CHECK_VNODE_CHDIR,
MAC_CHECK_VNODE_CHROOT,