Merge kld access control checks from the MAC tree: these access control

checks permit policy modules to augment the system policy for permitting
kld operations.  This permits policies to limit access to kld operations
based on credential (and other) properties, as well as to perform checks
on the kld being loaded (integrity, etc).

Approved by:	re
Obtained from:	TrustedBSD Project
Sponsored by:	DARPA, Network Associates Laboratories
This commit is contained in:
Robert Watson 2002-11-19 22:12:42 +00:00
parent 33772a02e9
commit a3df768b04
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=107089
16 changed files with 488 additions and 0 deletions

View File

@ -27,6 +27,7 @@
*/
#include "opt_ddb.h"
#include "opt_mac.h"
#include <sys/param.h>
#include <sys/kernel.h>
@ -38,6 +39,7 @@
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/sx.h>
#include <sys/mac.h>
#include <sys/module.h>
#include <sys/linker.h>
#include <sys/fcntl.h>
@ -474,6 +476,11 @@ linker_file_unload(linker_file_t file)
/* Refuse to unload modules if securelevel raised. */
if (securelevel > 0)
return (EPERM);
#ifdef MAC
error = mac_check_kld_unload(curthread->td_ucred);
if (error)
return (error);
#endif
KLD_DPF(FILE, ("linker_file_unload: lf->refs=%d\n", file->refs));
if (file->refs == 1) {
@ -824,6 +831,12 @@ kldfind(struct thread *td, struct kldfind_args *uap)
linker_file_t lf;
int error = 0;
#ifdef MAC
error = mac_check_kld_stat(td->td_ucred);
if (error)
return (error);
#endif
mtx_lock(&Giant);
td->td_retval[0] = -1;
@ -854,6 +867,12 @@ kldnext(struct thread *td, struct kldnext_args *uap)
linker_file_t lf;
int error = 0;
#ifdef MAC
error = mac_check_kld_stat(td->td_ucred);
if (error)
return (error);
#endif
mtx_lock(&Giant);
if (SCARG(uap, fileid) == 0) {
@ -889,6 +908,12 @@ kldstat(struct thread *td, struct kldstat_args *uap)
int namelen, version;
struct kld_file_stat *stat;
#ifdef MAC
error = mac_check_kld_stat(td->td_ucred);
if (error)
return (error);
#endif
mtx_lock(&Giant);
lf = linker_find_file_by_id(SCARG(uap, fileid));
@ -938,6 +963,12 @@ kldfirstmod(struct thread *td, struct kldfirstmod_args *uap)
module_t mp;
int error = 0;
#ifdef MAC
error = mac_check_kld_stat(td->td_ucred);
if (error)
return (error);
#endif
mtx_lock(&Giant);
lf = linker_find_file_by_id(SCARG(uap, fileid));
if (lf) {
@ -967,6 +998,12 @@ kldsym(struct thread *td, struct kldsym_args *uap)
struct kld_sym_lookup lookup;
int error = 0;
#ifdef MAC
error = mac_check_kld_stat(td->td_ucred);
if (error)
return (error);
#endif
mtx_lock(&Giant);
if ((error = copyin(SCARG(uap, data), &lookup, sizeof(lookup))) != 0)
@ -1800,6 +1837,11 @@ sysctl_kern_function_list(SYSCTL_HANDLER_ARGS)
linker_file_t lf;
int error;
#ifdef MAC
error = mac_check_kld_stat(req->td->td_ucred);
if (error)
return (error);
#endif
sysctl_wire_old_buffer(req, 0);
mtx_lock(&kld_mtx);
TAILQ_FOREACH(lf, &linker_files, link) {

View File

@ -125,6 +125,11 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
&mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
TUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs);
static int mac_enforce_kld = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_kld, CTLFLAG_RW,
&mac_enforce_kld, 0, "Enforce MAC policy on kld operations");
TUNABLE_INT("security.mac.enforce_kld", &mac_enforce_kld);
static int mac_enforce_network = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW,
&mac_enforce_network, 0, "Enforce MAC policy on network packets");
@ -2292,6 +2297,47 @@ mac_check_kenv_unset(struct ucred *cred, char *name)
return (error);
}
int
mac_check_kld_load(struct ucred *cred, struct vnode *vp)
{
int error;
ASSERT_VOP_LOCKED(vp, "mac_check_kld_load");
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_load, cred, vp, &vp->v_label);
return (error);
}
int
mac_check_kld_stat(struct ucred *cred)
{
int error;
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_stat, cred);
return (error);
}
int
mac_check_kld_unload(struct ucred *cred)
{
int error;
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_unload, cred);
return (error);
}
int
mac_check_mount_stat(struct ucred *cred, struct mount *mount)
{

View File

@ -27,11 +27,13 @@
*/
#include "opt_ddb.h"
#include "opt_mac.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mac.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/proc.h>
@ -556,6 +558,13 @@ link_elf_load_file(linker_class_t cls, const char* filename,
if (error)
return error;
NDFREE(&nd, NDF_ONLY_PNBUF);
#ifdef MAC
error = mac_check_kld_load(curthread->td_ucred, nd.ni_vp);
if (error) {
firstpage = NULL;
goto out;
}
#endif
/*
* Read the elf header from the file.

View File

@ -27,11 +27,13 @@
*/
#include "opt_ddb.h"
#include "opt_mac.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mac.h>
#include <sys/malloc.h>
#include <sys/mutex.h>
#include <sys/proc.h>
@ -556,6 +558,13 @@ link_elf_load_file(linker_class_t cls, const char* filename,
if (error)
return error;
NDFREE(&nd, NDF_ONLY_PNBUF);
#ifdef MAC
error = mac_check_kld_load(curthread->td_ucred, nd.ni_vp);
if (error) {
firstpage = NULL;
goto out;
}
#endif
/*
* Read the elf header from the file.

View File

@ -125,6 +125,11 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
&mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
TUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs);
static int mac_enforce_kld = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_kld, CTLFLAG_RW,
&mac_enforce_kld, 0, "Enforce MAC policy on kld operations");
TUNABLE_INT("security.mac.enforce_kld", &mac_enforce_kld);
static int mac_enforce_network = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW,
&mac_enforce_network, 0, "Enforce MAC policy on network packets");
@ -2292,6 +2297,47 @@ mac_check_kenv_unset(struct ucred *cred, char *name)
return (error);
}
int
mac_check_kld_load(struct ucred *cred, struct vnode *vp)
{
int error;
ASSERT_VOP_LOCKED(vp, "mac_check_kld_load");
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_load, cred, vp, &vp->v_label);
return (error);
}
int
mac_check_kld_stat(struct ucred *cred)
{
int error;
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_stat, cred);
return (error);
}
int
mac_check_kld_unload(struct ucred *cred)
{
int error;
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_unload, cred);
return (error);
}
int
mac_check_mount_stat(struct ucred *cred, struct mount *mount)
{

View File

@ -237,6 +237,9 @@ int mac_check_kenv_dump(struct ucred *cred);
int mac_check_kenv_get(struct ucred *cred, char *name);
int mac_check_kenv_set(struct ucred *cred, char *name, char *value);
int mac_check_kenv_unset(struct ucred *cred, char *name);
int mac_check_kld_load(struct ucred *cred, struct vnode *vp);
int mac_check_kld_stat(struct ucred *cred);
int mac_check_kld_unload(struct ucred *cred);
int mac_check_mount_stat(struct ucred *cred, struct mount *mp);
int mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
unsigned long cmd, void *data);

View File

@ -125,6 +125,11 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
&mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
TUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs);
static int mac_enforce_kld = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_kld, CTLFLAG_RW,
&mac_enforce_kld, 0, "Enforce MAC policy on kld operations");
TUNABLE_INT("security.mac.enforce_kld", &mac_enforce_kld);
static int mac_enforce_network = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW,
&mac_enforce_network, 0, "Enforce MAC policy on network packets");
@ -2292,6 +2297,47 @@ mac_check_kenv_unset(struct ucred *cred, char *name)
return (error);
}
int
mac_check_kld_load(struct ucred *cred, struct vnode *vp)
{
int error;
ASSERT_VOP_LOCKED(vp, "mac_check_kld_load");
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_load, cred, vp, &vp->v_label);
return (error);
}
int
mac_check_kld_stat(struct ucred *cred)
{
int error;
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_stat, cred);
return (error);
}
int
mac_check_kld_unload(struct ucred *cred)
{
int error;
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_unload, cred);
return (error);
}
int
mac_check_mount_stat(struct ucred *cred, struct mount *mount)
{

View File

@ -125,6 +125,11 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
&mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
TUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs);
static int mac_enforce_kld = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_kld, CTLFLAG_RW,
&mac_enforce_kld, 0, "Enforce MAC policy on kld operations");
TUNABLE_INT("security.mac.enforce_kld", &mac_enforce_kld);
static int mac_enforce_network = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW,
&mac_enforce_network, 0, "Enforce MAC policy on network packets");
@ -2292,6 +2297,47 @@ mac_check_kenv_unset(struct ucred *cred, char *name)
return (error);
}
int
mac_check_kld_load(struct ucred *cred, struct vnode *vp)
{
int error;
ASSERT_VOP_LOCKED(vp, "mac_check_kld_load");
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_load, cred, vp, &vp->v_label);
return (error);
}
int
mac_check_kld_stat(struct ucred *cred)
{
int error;
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_stat, cred);
return (error);
}
int
mac_check_kld_unload(struct ucred *cred)
{
int error;
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_unload, cred);
return (error);
}
int
mac_check_mount_stat(struct ucred *cred, struct mount *mount)
{

View File

@ -125,6 +125,11 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
&mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
TUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs);
static int mac_enforce_kld = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_kld, CTLFLAG_RW,
&mac_enforce_kld, 0, "Enforce MAC policy on kld operations");
TUNABLE_INT("security.mac.enforce_kld", &mac_enforce_kld);
static int mac_enforce_network = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW,
&mac_enforce_network, 0, "Enforce MAC policy on network packets");
@ -2292,6 +2297,47 @@ mac_check_kenv_unset(struct ucred *cred, char *name)
return (error);
}
int
mac_check_kld_load(struct ucred *cred, struct vnode *vp)
{
int error;
ASSERT_VOP_LOCKED(vp, "mac_check_kld_load");
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_load, cred, vp, &vp->v_label);
return (error);
}
int
mac_check_kld_stat(struct ucred *cred)
{
int error;
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_stat, cred);
return (error);
}
int
mac_check_kld_unload(struct ucred *cred)
{
int error;
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_unload, cred);
return (error);
}
int
mac_check_mount_stat(struct ucred *cred, struct mount *mount)
{

View File

@ -272,6 +272,10 @@ struct mac_policy_ops {
int (*mpo_check_kenv_set)(struct ucred *cred, char *name,
char *value);
int (*mpo_check_kenv_unset)(struct ucred *cred, char *name);
int (*mpo_check_kld_load)(struct ucred *cred, struct vnode *vp,
struct label *vlabel);
int (*mpo_check_kld_stat)(struct ucred *cred);
int (*mpo_check_kld_unload)(struct ucred *cred);
int (*mpo_check_mount_stat)(struct ucred *cred, struct mount *mp,
struct label *mntlabel);
int (*mpo_check_pipe_ioctl)(struct ucred *cred, struct pipe *pipe,

View File

@ -125,6 +125,11 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
&mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
TUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs);
static int mac_enforce_kld = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_kld, CTLFLAG_RW,
&mac_enforce_kld, 0, "Enforce MAC policy on kld operations");
TUNABLE_INT("security.mac.enforce_kld", &mac_enforce_kld);
static int mac_enforce_network = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW,
&mac_enforce_network, 0, "Enforce MAC policy on network packets");
@ -2292,6 +2297,47 @@ mac_check_kenv_unset(struct ucred *cred, char *name)
return (error);
}
int
mac_check_kld_load(struct ucred *cred, struct vnode *vp)
{
int error;
ASSERT_VOP_LOCKED(vp, "mac_check_kld_load");
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_load, cred, vp, &vp->v_label);
return (error);
}
int
mac_check_kld_stat(struct ucred *cred)
{
int error;
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_stat, cred);
return (error);
}
int
mac_check_kld_unload(struct ucred *cred)
{
int error;
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_unload, cred);
return (error);
}
int
mac_check_mount_stat(struct ucred *cred, struct mount *mount)
{

View File

@ -125,6 +125,11 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
&mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
TUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs);
static int mac_enforce_kld = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_kld, CTLFLAG_RW,
&mac_enforce_kld, 0, "Enforce MAC policy on kld operations");
TUNABLE_INT("security.mac.enforce_kld", &mac_enforce_kld);
static int mac_enforce_network = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW,
&mac_enforce_network, 0, "Enforce MAC policy on network packets");
@ -2292,6 +2297,47 @@ mac_check_kenv_unset(struct ucred *cred, char *name)
return (error);
}
int
mac_check_kld_load(struct ucred *cred, struct vnode *vp)
{
int error;
ASSERT_VOP_LOCKED(vp, "mac_check_kld_load");
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_load, cred, vp, &vp->v_label);
return (error);
}
int
mac_check_kld_stat(struct ucred *cred)
{
int error;
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_stat, cred);
return (error);
}
int
mac_check_kld_unload(struct ucred *cred)
{
int error;
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_unload, cred);
return (error);
}
int
mac_check_mount_stat(struct ucred *cred, struct mount *mount)
{

View File

@ -125,6 +125,11 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
&mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
TUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs);
static int mac_enforce_kld = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_kld, CTLFLAG_RW,
&mac_enforce_kld, 0, "Enforce MAC policy on kld operations");
TUNABLE_INT("security.mac.enforce_kld", &mac_enforce_kld);
static int mac_enforce_network = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW,
&mac_enforce_network, 0, "Enforce MAC policy on network packets");
@ -2292,6 +2297,47 @@ mac_check_kenv_unset(struct ucred *cred, char *name)
return (error);
}
int
mac_check_kld_load(struct ucred *cred, struct vnode *vp)
{
int error;
ASSERT_VOP_LOCKED(vp, "mac_check_kld_load");
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_load, cred, vp, &vp->v_label);
return (error);
}
int
mac_check_kld_stat(struct ucred *cred)
{
int error;
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_stat, cred);
return (error);
}
int
mac_check_kld_unload(struct ucred *cred)
{
int error;
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_unload, cred);
return (error);
}
int
mac_check_mount_stat(struct ucred *cred, struct mount *mount)
{

View File

@ -125,6 +125,11 @@ SYSCTL_INT(_security_mac, OID_AUTO, enforce_fs, CTLFLAG_RW,
&mac_enforce_fs, 0, "Enforce MAC policy on file system objects");
TUNABLE_INT("security.mac.enforce_fs", &mac_enforce_fs);
static int mac_enforce_kld = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_kld, CTLFLAG_RW,
&mac_enforce_kld, 0, "Enforce MAC policy on kld operations");
TUNABLE_INT("security.mac.enforce_kld", &mac_enforce_kld);
static int mac_enforce_network = 1;
SYSCTL_INT(_security_mac, OID_AUTO, enforce_network, CTLFLAG_RW,
&mac_enforce_network, 0, "Enforce MAC policy on network packets");
@ -2292,6 +2297,47 @@ mac_check_kenv_unset(struct ucred *cred, char *name)
return (error);
}
int
mac_check_kld_load(struct ucred *cred, struct vnode *vp)
{
int error;
ASSERT_VOP_LOCKED(vp, "mac_check_kld_load");
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_load, cred, vp, &vp->v_label);
return (error);
}
int
mac_check_kld_stat(struct ucred *cred)
{
int error;
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_stat, cred);
return (error);
}
int
mac_check_kld_unload(struct ucred *cred)
{
int error;
if (!mac_enforce_kld)
return (0);
MAC_CHECK(check_kld_unload, cred);
return (error);
}
int
mac_check_mount_stat(struct ucred *cred, struct mount *mount)
{

View File

@ -237,6 +237,9 @@ int mac_check_kenv_dump(struct ucred *cred);
int mac_check_kenv_get(struct ucred *cred, char *name);
int mac_check_kenv_set(struct ucred *cred, char *name, char *value);
int mac_check_kenv_unset(struct ucred *cred, char *name);
int mac_check_kld_load(struct ucred *cred, struct vnode *vp);
int mac_check_kld_stat(struct ucred *cred);
int mac_check_kld_unload(struct ucred *cred);
int mac_check_mount_stat(struct ucred *cred, struct mount *mp);
int mac_check_pipe_ioctl(struct ucred *cred, struct pipe *pipe,
unsigned long cmd, void *data);

View File

@ -272,6 +272,10 @@ struct mac_policy_ops {
int (*mpo_check_kenv_set)(struct ucred *cred, char *name,
char *value);
int (*mpo_check_kenv_unset)(struct ucred *cred, char *name);
int (*mpo_check_kld_load)(struct ucred *cred, struct vnode *vp,
struct label *vlabel);
int (*mpo_check_kld_stat)(struct ucred *cred);
int (*mpo_check_kld_unload)(struct ucred *cred);
int (*mpo_check_mount_stat)(struct ucred *cred, struct mount *mp,
struct label *mntlabel);
int (*mpo_check_pipe_ioctl)(struct ucred *cred, struct pipe *pipe,