Commit 64dbf074 authored by Eric Paris's avatar Eric Paris Committed by James Morris

selinux: introduce permissive types

Introduce the concept of a permissive type.  A new ebitmap is introduced to
the policy database which indicates if a given type has the permissive bit
set or not.  This bit is tested for the scontext of any denial.  The bit is
meaningless on types which only appear as the target of a decision and never
the source.  A domain running with a permissive type will be allowed to
perform any action similarly to when the system is globally set permissive.
Signed-off-by: default avatarEric Paris <eparis@redhat.com>
Acked-by: default avatarStephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: default avatarJames Morris <jmorris@namei.org>
parent 0356357c
...@@ -145,7 +145,7 @@ config SECURITY_SELINUX_POLICYDB_VERSION_MAX ...@@ -145,7 +145,7 @@ config SECURITY_SELINUX_POLICYDB_VERSION_MAX
config SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE config SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
int "NSA SELinux maximum supported policy format version value" int "NSA SELinux maximum supported policy format version value"
depends on SECURITY_SELINUX_POLICYDB_VERSION_MAX depends on SECURITY_SELINUX_POLICYDB_VERSION_MAX
range 15 22 range 15 23
default 19 default 19
help help
This option sets the value for the maximum policy format version This option sets the value for the maximum policy format version
......
...@@ -893,12 +893,13 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid, ...@@ -893,12 +893,13 @@ int avc_has_perm_noaudit(u32 ssid, u32 tsid,
denied = requested & ~(p_ae->avd.allowed); denied = requested & ~(p_ae->avd.allowed);
if (denied) { if (denied) {
if (selinux_enforcing || (flags & AVC_STRICT)) if (flags & AVC_STRICT)
rc = -EACCES; rc = -EACCES;
else if (!selinux_enforcing || security_permissive_sid(ssid))
avc_update_node(AVC_CALLBACK_GRANT, requested, ssid,
tsid, tclass);
else else
if (node) rc = -EACCES;
avc_update_node(AVC_CALLBACK_GRANT,requested,
ssid,tsid,tclass);
} }
rcu_read_unlock(); rcu_read_unlock();
......
...@@ -26,13 +26,14 @@ ...@@ -26,13 +26,14 @@
#define POLICYDB_VERSION_AVTAB 20 #define POLICYDB_VERSION_AVTAB 20
#define POLICYDB_VERSION_RANGETRANS 21 #define POLICYDB_VERSION_RANGETRANS 21
#define POLICYDB_VERSION_POLCAP 22 #define POLICYDB_VERSION_POLCAP 22
#define POLICYDB_VERSION_PERMISSIVE 23
/* Range of policy versions we understand*/ /* Range of policy versions we understand*/
#define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
#ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
#define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE #define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
#else #else
#define POLICYDB_VERSION_MAX POLICYDB_VERSION_POLCAP #define POLICYDB_VERSION_MAX POLICYDB_VERSION_PERMISSIVE
#endif #endif
#define CONTEXT_MNT 0x01 #define CONTEXT_MNT 0x01
...@@ -69,6 +70,8 @@ struct av_decision { ...@@ -69,6 +70,8 @@ struct av_decision {
u32 seqno; u32 seqno;
}; };
int security_permissive_sid(u32 sid);
int security_compute_av(u32 ssid, u32 tsid, int security_compute_av(u32 ssid, u32 tsid,
u16 tclass, u32 requested, u16 tclass, u32 requested,
struct av_decision *avd); struct av_decision *avd);
......
...@@ -111,6 +111,11 @@ static struct policydb_compat_info policydb_compat[] = { ...@@ -111,6 +111,11 @@ static struct policydb_compat_info policydb_compat[] = {
.version = POLICYDB_VERSION_POLCAP, .version = POLICYDB_VERSION_POLCAP,
.sym_num = SYM_NUM, .sym_num = SYM_NUM,
.ocon_num = OCON_NUM, .ocon_num = OCON_NUM,
},
{
.version = POLICYDB_VERSION_PERMISSIVE,
.sym_num = SYM_NUM,
.ocon_num = OCON_NUM,
} }
}; };
...@@ -194,6 +199,7 @@ static int policydb_init(struct policydb *p) ...@@ -194,6 +199,7 @@ static int policydb_init(struct policydb *p)
goto out_free_symtab; goto out_free_symtab;
ebitmap_init(&p->policycaps); ebitmap_init(&p->policycaps);
ebitmap_init(&p->permissive_map);
out: out:
return rc; return rc;
...@@ -687,6 +693,7 @@ void policydb_destroy(struct policydb *p) ...@@ -687,6 +693,7 @@ void policydb_destroy(struct policydb *p)
kfree(p->type_attr_map); kfree(p->type_attr_map);
kfree(p->undefined_perms); kfree(p->undefined_perms);
ebitmap_destroy(&p->policycaps); ebitmap_destroy(&p->policycaps);
ebitmap_destroy(&p->permissive_map);
return; return;
} }
...@@ -1570,6 +1577,10 @@ int policydb_read(struct policydb *p, void *fp) ...@@ -1570,6 +1577,10 @@ int policydb_read(struct policydb *p, void *fp)
ebitmap_read(&p->policycaps, fp) != 0) ebitmap_read(&p->policycaps, fp) != 0)
goto bad; goto bad;
if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE &&
ebitmap_read(&p->permissive_map, fp) != 0)
goto bad;
info = policydb_lookup_compat(p->policyvers); info = policydb_lookup_compat(p->policyvers);
if (!info) { if (!info) {
printk(KERN_ERR "SELinux: unable to find policy compat info " printk(KERN_ERR "SELinux: unable to find policy compat info "
......
...@@ -243,6 +243,8 @@ struct policydb { ...@@ -243,6 +243,8 @@ struct policydb {
struct ebitmap policycaps; struct ebitmap policycaps;
struct ebitmap permissive_map;
unsigned int policyvers; unsigned int policyvers;
unsigned int reject_unknown : 1; unsigned int reject_unknown : 1;
......
...@@ -417,6 +417,31 @@ static int context_struct_compute_av(struct context *scontext, ...@@ -417,6 +417,31 @@ static int context_struct_compute_av(struct context *scontext,
return -EINVAL; return -EINVAL;
} }
/*
* Given a sid find if the type has the permissive flag set
*/
int security_permissive_sid(u32 sid)
{
struct context *context;
u32 type;
int rc;
POLICY_RDLOCK;
context = sidtab_search(&sidtab, sid);
BUG_ON(!context);
type = context->type;
/*
* we are intentionally using type here, not type-1, the 0th bit may
* someday indicate that we are globally setting permissive in policy.
*/
rc = ebitmap_get_bit(&policydb.permissive_map, type);
POLICY_RDUNLOCK;
return rc;
}
static int security_validtrans_handle_fail(struct context *ocontext, static int security_validtrans_handle_fail(struct context *ocontext,
struct context *ncontext, struct context *ncontext,
struct context *tcontext, struct context *tcontext,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment