Introduce MAC_CHECK_VNODE_SWAPON, which permits MAC policies to

perform authorization checks during swapon() events; policies
might choose to enforce protections based on the credential
requesting the swap configuration, the target of the swap operation,
or other factors such as internal policy state.

Approved by:	re
Obtained from:	TrustedBSD Project
Sponsored by:	DARPA, Network Associates Laboratories
This commit is contained in:
Robert Watson 2002-10-22 15:53:43 +00:00
parent 2789e47e2c
commit 1cbfd977fd
14 changed files with 213 additions and 1 deletions

View File

@ -1026,6 +1026,10 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_check_vnode_stat =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_SWAPON:
mpc->mpc_ops->mpo_check_vnode_swapon =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_WRITE:
mpc->mpc_ops->mpo_check_vnode_write =
mpe->mpe_function;
@ -2603,6 +2607,24 @@ mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
return (error);
}
int
mac_check_vnode_swapon(struct ucred *cred, struct vnode *vp)
{
int error;
ASSERT_VOP_LOCKED(vp, "mac_check_vnode_swapon");
if (!mac_enforce_fs)
return (0);
error = vn_refreshlabel(vp, cred);
if (error)
return (error);
MAC_CHECK(check_vnode_swapon, cred, vp, &vp->v_label);
return (error);
}
int
mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
struct vnode *vp)

View File

@ -1026,6 +1026,10 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_check_vnode_stat =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_SWAPON:
mpc->mpc_ops->mpo_check_vnode_swapon =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_WRITE:
mpc->mpc_ops->mpo_check_vnode_write =
mpe->mpe_function;
@ -2603,6 +2607,24 @@ mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
return (error);
}
int
mac_check_vnode_swapon(struct ucred *cred, struct vnode *vp)
{
int error;
ASSERT_VOP_LOCKED(vp, "mac_check_vnode_swapon");
if (!mac_enforce_fs)
return (0);
error = vn_refreshlabel(vp, cred);
if (error)
return (error);
MAC_CHECK(check_vnode_swapon, cred, vp, &vp->v_label);
return (error);
}
int
mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
struct vnode *vp)

View File

@ -348,6 +348,7 @@ int mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
struct timespec atime, struct timespec mtime);
int mac_check_vnode_stat(struct ucred *active_cred,
struct ucred *file_cred, struct vnode *vp);
int mac_check_vnode_swapon(struct ucred *cred, struct vnode *vp);
int mac_check_vnode_write(struct ucred *active_cred,
struct ucred *file_cred, struct vnode *vp);
int mac_getsockopt_label_get(struct ucred *cred, struct socket *so,

View File

@ -1026,6 +1026,10 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_check_vnode_stat =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_SWAPON:
mpc->mpc_ops->mpo_check_vnode_swapon =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_WRITE:
mpc->mpc_ops->mpo_check_vnode_write =
mpe->mpe_function;
@ -2603,6 +2607,24 @@ mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
return (error);
}
int
mac_check_vnode_swapon(struct ucred *cred, struct vnode *vp)
{
int error;
ASSERT_VOP_LOCKED(vp, "mac_check_vnode_swapon");
if (!mac_enforce_fs)
return (0);
error = vn_refreshlabel(vp, cred);
if (error)
return (error);
MAC_CHECK(check_vnode_swapon, cred, vp, &vp->v_label);
return (error);
}
int
mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
struct vnode *vp)

View File

@ -1026,6 +1026,10 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_check_vnode_stat =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_SWAPON:
mpc->mpc_ops->mpo_check_vnode_swapon =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_WRITE:
mpc->mpc_ops->mpo_check_vnode_write =
mpe->mpe_function;
@ -2603,6 +2607,24 @@ mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
return (error);
}
int
mac_check_vnode_swapon(struct ucred *cred, struct vnode *vp)
{
int error;
ASSERT_VOP_LOCKED(vp, "mac_check_vnode_swapon");
if (!mac_enforce_fs)
return (0);
error = vn_refreshlabel(vp, cred);
if (error)
return (error);
MAC_CHECK(check_vnode_swapon, cred, vp, &vp->v_label);
return (error);
}
int
mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
struct vnode *vp)

View File

@ -1026,6 +1026,10 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_check_vnode_stat =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_SWAPON:
mpc->mpc_ops->mpo_check_vnode_swapon =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_WRITE:
mpc->mpc_ops->mpo_check_vnode_write =
mpe->mpe_function;
@ -2603,6 +2607,24 @@ mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
return (error);
}
int
mac_check_vnode_swapon(struct ucred *cred, struct vnode *vp)
{
int error;
ASSERT_VOP_LOCKED(vp, "mac_check_vnode_swapon");
if (!mac_enforce_fs)
return (0);
error = vn_refreshlabel(vp, cred);
if (error)
return (error);
MAC_CHECK(check_vnode_swapon, cred, vp, &vp->v_label);
return (error);
}
int
mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
struct vnode *vp)

View File

@ -385,6 +385,8 @@ struct mac_policy_ops {
int (*mpo_check_vnode_stat)(struct ucred *active_cred,
struct ucred *file_cred, struct vnode *vp,
struct label *label);
int (*mpo_check_vnode_swapon)(struct ucred *cred,
struct vnode *vp, struct label *label);
int (*mpo_check_vnode_write)(struct ucred *active_cred,
struct ucred *file_cred, struct vnode *vp,
struct label *label);
@ -531,6 +533,7 @@ enum mac_op_constant {
MAC_CHECK_VNODE_SETOWNER,
MAC_CHECK_VNODE_SETUTIMES,
MAC_CHECK_VNODE_STAT,
MAC_CHECK_VNODE_SWAPON,
MAC_CHECK_VNODE_WRITE,
};

View File

@ -1026,6 +1026,10 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_check_vnode_stat =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_SWAPON:
mpc->mpc_ops->mpo_check_vnode_swapon =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_WRITE:
mpc->mpc_ops->mpo_check_vnode_write =
mpe->mpe_function;
@ -2603,6 +2607,24 @@ mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
return (error);
}
int
mac_check_vnode_swapon(struct ucred *cred, struct vnode *vp)
{
int error;
ASSERT_VOP_LOCKED(vp, "mac_check_vnode_swapon");
if (!mac_enforce_fs)
return (0);
error = vn_refreshlabel(vp, cred);
if (error)
return (error);
MAC_CHECK(check_vnode_swapon, cred, vp, &vp->v_label);
return (error);
}
int
mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
struct vnode *vp)

View File

@ -1026,6 +1026,10 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_check_vnode_stat =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_SWAPON:
mpc->mpc_ops->mpo_check_vnode_swapon =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_WRITE:
mpc->mpc_ops->mpo_check_vnode_write =
mpe->mpe_function;
@ -2603,6 +2607,24 @@ mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
return (error);
}
int
mac_check_vnode_swapon(struct ucred *cred, struct vnode *vp)
{
int error;
ASSERT_VOP_LOCKED(vp, "mac_check_vnode_swapon");
if (!mac_enforce_fs)
return (0);
error = vn_refreshlabel(vp, cred);
if (error)
return (error);
MAC_CHECK(check_vnode_swapon, cred, vp, &vp->v_label);
return (error);
}
int
mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
struct vnode *vp)

View File

@ -1026,6 +1026,10 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_check_vnode_stat =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_SWAPON:
mpc->mpc_ops->mpo_check_vnode_swapon =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_WRITE:
mpc->mpc_ops->mpo_check_vnode_write =
mpe->mpe_function;
@ -2603,6 +2607,24 @@ mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
return (error);
}
int
mac_check_vnode_swapon(struct ucred *cred, struct vnode *vp)
{
int error;
ASSERT_VOP_LOCKED(vp, "mac_check_vnode_swapon");
if (!mac_enforce_fs)
return (0);
error = vn_refreshlabel(vp, cred);
if (error)
return (error);
MAC_CHECK(check_vnode_swapon, cred, vp, &vp->v_label);
return (error);
}
int
mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
struct vnode *vp)

View File

@ -1026,6 +1026,10 @@ mac_policy_register(struct mac_policy_conf *mpc)
mpc->mpc_ops->mpo_check_vnode_stat =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_SWAPON:
mpc->mpc_ops->mpo_check_vnode_swapon =
mpe->mpe_function;
break;
case MAC_CHECK_VNODE_WRITE:
mpc->mpc_ops->mpo_check_vnode_write =
mpe->mpe_function;
@ -2603,6 +2607,24 @@ mac_check_vnode_stat(struct ucred *active_cred, struct ucred *file_cred,
return (error);
}
int
mac_check_vnode_swapon(struct ucred *cred, struct vnode *vp)
{
int error;
ASSERT_VOP_LOCKED(vp, "mac_check_vnode_swapon");
if (!mac_enforce_fs)
return (0);
error = vn_refreshlabel(vp, cred);
if (error)
return (error);
MAC_CHECK(check_vnode_swapon, cred, vp, &vp->v_label);
return (error);
}
int
mac_check_vnode_write(struct ucred *active_cred, struct ucred *file_cred,
struct vnode *vp)

View File

@ -348,6 +348,7 @@ int mac_check_vnode_setutimes(struct ucred *cred, struct vnode *vp,
struct timespec atime, struct timespec mtime);
int mac_check_vnode_stat(struct ucred *active_cred,
struct ucred *file_cred, struct vnode *vp);
int mac_check_vnode_swapon(struct ucred *cred, struct vnode *vp);
int mac_check_vnode_write(struct ucred *active_cred,
struct ucred *file_cred, struct vnode *vp);
int mac_getsockopt_label_get(struct ucred *cred, struct socket *so,

View File

@ -385,6 +385,8 @@ struct mac_policy_ops {
int (*mpo_check_vnode_stat)(struct ucred *active_cred,
struct ucred *file_cred, struct vnode *vp,
struct label *label);
int (*mpo_check_vnode_swapon)(struct ucred *cred,
struct vnode *vp, struct label *label);
int (*mpo_check_vnode_write)(struct ucred *active_cred,
struct ucred *file_cred, struct vnode *vp,
struct label *label);
@ -531,6 +533,7 @@ enum mac_op_constant {
MAC_CHECK_VNODE_SETOWNER,
MAC_CHECK_VNODE_SETUTIMES,
MAC_CHECK_VNODE_STAT,
MAC_CHECK_VNODE_SWAPON,
MAC_CHECK_VNODE_WRITE,
};

View File

@ -34,6 +34,7 @@
* $FreeBSD$
*/
#include "opt_mac.h"
#include "opt_swap.h"
#include <sys/param.h>
@ -52,6 +53,7 @@
#include <sys/conf.h>
#include <sys/stat.h>
#include <sys/sysctl.h>
#include <sys/mac.h>
#include <sys/mount.h>
#include <vm/vm.h>
#include <vm/vm_extern.h>
@ -287,7 +289,11 @@ swaponvp(td, vp, dev, nblks)
return EINVAL;
found:
(void) vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
error = VOP_OPEN(vp, FREAD | FWRITE, td->td_ucred, td);
#ifdef MAC
error = mac_check_vnode_swapon(td->td_ucred, vp);
if (error == 0)
#endif
error = VOP_OPEN(vp, FREAD | FWRITE, td->td_ucred, td);
(void) VOP_UNLOCK(vp, 0, td);
if (error)
return (error);