Commit 64dbf07474d011540ca479a2e87fe998f570d6e3

Authored by Eric Paris
Committed by James Morris
1 parent 0356357c51

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: Eric Paris <eparis@redhat.com>
Acked-by: Stephen Smalley <sds@tycho.nsa.gov>
Signed-off-by: James Morris <jmorris@namei.org>

Showing 6 changed files with 48 additions and 6 deletions Side-by-side Diff

security/selinux/Kconfig
... ... @@ -145,7 +145,7 @@
145 145 config SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
146 146 int "NSA SELinux maximum supported policy format version value"
147 147 depends on SECURITY_SELINUX_POLICYDB_VERSION_MAX
148   - range 15 22
  148 + range 15 23
149 149 default 19
150 150 help
151 151 This option sets the value for the maximum policy format version
security/selinux/avc.c
... ... @@ -893,12 +893,13 @@
893 893 denied = requested & ~(p_ae->avd.allowed);
894 894  
895 895 if (denied) {
896   - if (selinux_enforcing || (flags & AVC_STRICT))
  896 + if (flags & AVC_STRICT)
897 897 rc = -EACCES;
  898 + else if (!selinux_enforcing || security_permissive_sid(ssid))
  899 + avc_update_node(AVC_CALLBACK_GRANT, requested, ssid,
  900 + tsid, tclass);
898 901 else
899   - if (node)
900   - avc_update_node(AVC_CALLBACK_GRANT,requested,
901   - ssid,tsid,tclass);
  902 + rc = -EACCES;
902 903 }
903 904  
904 905 rcu_read_unlock();
security/selinux/include/security.h
... ... @@ -26,13 +26,14 @@
26 26 #define POLICYDB_VERSION_AVTAB 20
27 27 #define POLICYDB_VERSION_RANGETRANS 21
28 28 #define POLICYDB_VERSION_POLCAP 22
  29 +#define POLICYDB_VERSION_PERMISSIVE 23
29 30  
30 31 /* Range of policy versions we understand*/
31 32 #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE
32 33 #ifdef CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX
33 34 #define POLICYDB_VERSION_MAX CONFIG_SECURITY_SELINUX_POLICYDB_VERSION_MAX_VALUE
34 35 #else
35   -#define POLICYDB_VERSION_MAX POLICYDB_VERSION_POLCAP
  36 +#define POLICYDB_VERSION_MAX POLICYDB_VERSION_PERMISSIVE
36 37 #endif
37 38  
38 39 #define CONTEXT_MNT 0x01
... ... @@ -68,6 +69,8 @@
68 69 u32 auditdeny;
69 70 u32 seqno;
70 71 };
  72 +
  73 +int security_permissive_sid(u32 sid);
71 74  
72 75 int security_compute_av(u32 ssid, u32 tsid,
73 76 u16 tclass, u32 requested,
security/selinux/ss/policydb.c
... ... @@ -111,6 +111,11 @@
111 111 .version = POLICYDB_VERSION_POLCAP,
112 112 .sym_num = SYM_NUM,
113 113 .ocon_num = OCON_NUM,
  114 + },
  115 + {
  116 + .version = POLICYDB_VERSION_PERMISSIVE,
  117 + .sym_num = SYM_NUM,
  118 + .ocon_num = OCON_NUM,
114 119 }
115 120 };
116 121  
... ... @@ -194,6 +199,7 @@
194 199 goto out_free_symtab;
195 200  
196 201 ebitmap_init(&p->policycaps);
  202 + ebitmap_init(&p->permissive_map);
197 203  
198 204 out:
199 205 return rc;
... ... @@ -687,6 +693,7 @@
687 693 kfree(p->type_attr_map);
688 694 kfree(p->undefined_perms);
689 695 ebitmap_destroy(&p->policycaps);
  696 + ebitmap_destroy(&p->permissive_map);
690 697  
691 698 return;
692 699 }
... ... @@ -1568,6 +1575,10 @@
1568 1575  
1569 1576 if (p->policyvers >= POLICYDB_VERSION_POLCAP &&
1570 1577 ebitmap_read(&p->policycaps, fp) != 0)
  1578 + goto bad;
  1579 +
  1580 + if (p->policyvers >= POLICYDB_VERSION_PERMISSIVE &&
  1581 + ebitmap_read(&p->permissive_map, fp) != 0)
1571 1582 goto bad;
1572 1583  
1573 1584 info = policydb_lookup_compat(p->policyvers);
security/selinux/ss/policydb.h
... ... @@ -243,6 +243,8 @@
243 243  
244 244 struct ebitmap policycaps;
245 245  
  246 + struct ebitmap permissive_map;
  247 +
246 248 unsigned int policyvers;
247 249  
248 250 unsigned int reject_unknown : 1;
security/selinux/ss/services.c
... ... @@ -417,6 +417,31 @@
417 417 return -EINVAL;
418 418 }
419 419  
  420 +/*
  421 + * Given a sid find if the type has the permissive flag set
  422 + */
  423 +int security_permissive_sid(u32 sid)
  424 +{
  425 + struct context *context;
  426 + u32 type;
  427 + int rc;
  428 +
  429 + POLICY_RDLOCK;
  430 +
  431 + context = sidtab_search(&sidtab, sid);
  432 + BUG_ON(!context);
  433 +
  434 + type = context->type;
  435 + /*
  436 + * we are intentionally using type here, not type-1, the 0th bit may
  437 + * someday indicate that we are globally setting permissive in policy.
  438 + */
  439 + rc = ebitmap_get_bit(&policydb.permissive_map, type);
  440 +
  441 + POLICY_RDUNLOCK;
  442 + return rc;
  443 +}
  444 +
420 445 static int security_validtrans_handle_fail(struct context *ocontext,
421 446 struct context *ncontext,
422 447 struct context *tcontext,