Reimplement sysctls handling by MAC framework.
Now I believe it is done in the right way. Removed some XXMAC cases, we now assume 'high' integrity level for all sysctls, except those with CTLFLAG_ANYBODY flag set. No more magic. Reviewed by: rwatson Approved by: rwatson, scottl (mentor) Tested with: LINT (compilation), mac_biba(4) (functionality)
This commit is contained in:
parent
47c524ddd4
commit
63dba32b76
@ -1175,12 +1175,21 @@ sysctl_root(SYSCTL_HANDLER_ARGS)
|
||||
if (!oid->oid_handler)
|
||||
return EINVAL;
|
||||
|
||||
if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE)
|
||||
error = oid->oid_handler(oid, (int *)arg1 + indx, arg2 - indx,
|
||||
req);
|
||||
else
|
||||
error = oid->oid_handler(oid, oid->oid_arg1, oid->oid_arg2,
|
||||
req);
|
||||
if ((oid->oid_kind & CTLTYPE) == CTLTYPE_NODE) {
|
||||
(int *)arg1 += indx;
|
||||
arg2 -= indx;
|
||||
} else {
|
||||
arg1 = oid->oid_arg1;
|
||||
arg2 = oid->oid_arg2;
|
||||
}
|
||||
#ifdef MAC
|
||||
error = mac_check_system_sysctl(req->td->td_ucred, oid, arg1, arg2,
|
||||
req);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
#endif
|
||||
error = oid->oid_handler(oid, arg1, arg2, req);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -1272,15 +1281,6 @@ 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);
|
||||
|
@ -120,6 +120,8 @@ struct mount;
|
||||
struct proc;
|
||||
struct sockaddr;
|
||||
struct socket;
|
||||
struct sysctl_oid;
|
||||
struct sysctl_req;
|
||||
struct pipepair;
|
||||
struct thread;
|
||||
struct timespec;
|
||||
@ -281,9 +283,8 @@ 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);
|
||||
int mac_check_system_swapoff(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_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
|
||||
void *arg1, int arg2, struct sysctl_req *req);
|
||||
int mac_check_vnode_access(struct ucred *cred, struct vnode *vp,
|
||||
int acc_mode);
|
||||
int mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp);
|
||||
|
@ -63,6 +63,8 @@ struct mount;
|
||||
struct pipepair;
|
||||
struct sbuf;
|
||||
struct socket;
|
||||
struct sysctl_oid;
|
||||
struct sysctl_req;
|
||||
struct ucred;
|
||||
struct uio;
|
||||
struct vnode;
|
||||
@ -362,9 +364,9 @@ struct mac_policy_ops {
|
||||
struct vnode *vp, struct label *label);
|
||||
int (*mpo_check_system_swapoff)(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_system_sysctl)(struct ucred *cred,
|
||||
struct sysctl_oid *oidp, void *arg1, int arg2,
|
||||
struct sysctl_req *req);
|
||||
int (*mpo_check_vnode_access)(struct ucred *cred,
|
||||
struct vnode *vp, struct label *label, int acc_mode);
|
||||
int (*mpo_check_vnode_chdir)(struct ucred *cred,
|
||||
|
@ -249,8 +249,8 @@ mac_check_system_swapoff(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)
|
||||
mac_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp, void *arg1,
|
||||
int arg2, struct sysctl_req *req)
|
||||
{
|
||||
int error;
|
||||
|
||||
@ -261,8 +261,7 @@ mac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
|
||||
if (!mac_enforce_system)
|
||||
return (0);
|
||||
|
||||
MAC_CHECK(check_system_sysctl, cred, name, namelen, old, oldlenp,
|
||||
inkernel, new, newlen);
|
||||
MAC_CHECK(check_system_sysctl, cred, oidp, arg1, arg2, req);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
@ -1973,8 +1973,8 @@ mac_biba_check_system_swapoff(struct ucred *cred, struct vnode *vp,
|
||||
}
|
||||
|
||||
static int
|
||||
mac_biba_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
|
||||
void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
|
||||
mac_biba_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
|
||||
void *arg1, int arg2, struct sysctl_req *req)
|
||||
{
|
||||
struct mac_biba *subj;
|
||||
int error;
|
||||
@ -1985,16 +1985,10 @@ mac_biba_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
|
||||
subj = SLOT(cred->cr_label);
|
||||
|
||||
/*
|
||||
* In general, treat sysctl variables as biba/high, but also
|
||||
* require privilege to change them, since they are a
|
||||
* communications channel between grades. Exempt MIB
|
||||
* queries from this due to undocmented sysctl magic.
|
||||
* XXXMAC: This probably requires some more review.
|
||||
* Treat sysctl variables without CTLFLAG_ANYBODY flag as
|
||||
* biba/high, but also require privilege to change them.
|
||||
*/
|
||||
if (new != NULL) {
|
||||
if (namelen > 0 && name[0] == 0)
|
||||
return (0);
|
||||
|
||||
if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) {
|
||||
if (!mac_biba_subject_dominate_high(subj))
|
||||
return (EACCES);
|
||||
|
||||
|
@ -2063,8 +2063,8 @@ mac_lomac_check_system_swapon(struct ucred *cred, struct vnode *vp,
|
||||
}
|
||||
|
||||
static int
|
||||
mac_lomac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
|
||||
void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
|
||||
mac_lomac_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
|
||||
void *arg1, int arg2, struct sysctl_req *req)
|
||||
{
|
||||
struct mac_lomac *subj;
|
||||
|
||||
@ -2074,16 +2074,10 @@ mac_lomac_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
|
||||
subj = SLOT(cred->cr_label);
|
||||
|
||||
/*
|
||||
* In general, treat sysctl variables as lomac/high, but also
|
||||
* require privilege to change them, since they are a
|
||||
* communications channel between grades. Exempt MIB
|
||||
* queries from this due to undocmented sysctl magic.
|
||||
* XXXMAC: This probably requires some more review.
|
||||
* Treat sysctl variables without CTLFLAG_ANYBODY flag as
|
||||
* lomac/high, but also require privilege to change them.
|
||||
*/
|
||||
if (new != NULL) {
|
||||
if (namelen > 0 && name[0] == 0)
|
||||
return (0);
|
||||
|
||||
if (req->newptr != NULL && (oidp->oid_kind & CTLFLAG_ANYBODY) == 0) {
|
||||
#ifdef notdef
|
||||
if (!mac_lomac_subject_dominate_high(subj))
|
||||
return (EACCES);
|
||||
|
@ -757,8 +757,8 @@ stub_check_system_swapoff(struct ucred *cred, struct vnode *vp,
|
||||
}
|
||||
|
||||
static int
|
||||
stub_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
|
||||
void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
|
||||
stub_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
|
||||
void *arg1, int arg2, struct sysctl_req *req)
|
||||
{
|
||||
|
||||
return (0);
|
||||
|
@ -1470,8 +1470,8 @@ mac_test_check_system_swapoff(struct ucred *cred, struct vnode *vp,
|
||||
}
|
||||
|
||||
static int
|
||||
mac_test_check_system_sysctl(struct ucred *cred, int *name, u_int namelen,
|
||||
void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen)
|
||||
mac_test_check_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
|
||||
void *arg1, int arg2, struct sysctl_req *req)
|
||||
{
|
||||
|
||||
ASSERT_CRED_LABEL(cred->cr_label);
|
||||
|
@ -120,6 +120,8 @@ struct mount;
|
||||
struct proc;
|
||||
struct sockaddr;
|
||||
struct socket;
|
||||
struct sysctl_oid;
|
||||
struct sysctl_req;
|
||||
struct pipepair;
|
||||
struct thread;
|
||||
struct timespec;
|
||||
@ -281,9 +283,8 @@ 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);
|
||||
int mac_check_system_swapoff(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_system_sysctl(struct ucred *cred, struct sysctl_oid *oidp,
|
||||
void *arg1, int arg2, struct sysctl_req *req);
|
||||
int mac_check_vnode_access(struct ucred *cred, struct vnode *vp,
|
||||
int acc_mode);
|
||||
int mac_check_vnode_chdir(struct ucred *cred, struct vnode *dvp);
|
||||
|
@ -63,6 +63,8 @@ struct mount;
|
||||
struct pipepair;
|
||||
struct sbuf;
|
||||
struct socket;
|
||||
struct sysctl_oid;
|
||||
struct sysctl_req;
|
||||
struct ucred;
|
||||
struct uio;
|
||||
struct vnode;
|
||||
@ -362,9 +364,9 @@ struct mac_policy_ops {
|
||||
struct vnode *vp, struct label *label);
|
||||
int (*mpo_check_system_swapoff)(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_system_sysctl)(struct ucred *cred,
|
||||
struct sysctl_oid *oidp, void *arg1, int arg2,
|
||||
struct sysctl_req *req);
|
||||
int (*mpo_check_vnode_access)(struct ucred *cred,
|
||||
struct vnode *vp, struct label *label, int acc_mode);
|
||||
int (*mpo_check_vnode_chdir)(struct ucred *cred,
|
||||
|
Loading…
x
Reference in New Issue
Block a user