aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss/services.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/ss/services.c')
-rw-r--r--security/selinux/ss/services.c75
1 files changed, 66 insertions, 9 deletions
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c
index 6100fc023055..03140edf97a3 100644
--- a/security/selinux/ss/services.c
+++ b/security/selinux/ss/services.c
@@ -292,6 +292,7 @@ static int context_struct_compute_av(struct context *scontext,
292 struct class_datum *tclass_datum; 292 struct class_datum *tclass_datum;
293 struct ebitmap *sattr, *tattr; 293 struct ebitmap *sattr, *tattr;
294 struct ebitmap_node *snode, *tnode; 294 struct ebitmap_node *snode, *tnode;
295 const struct selinux_class_perm *kdefs = &selinux_class_perm;
295 unsigned int i, j; 296 unsigned int i, j;
296 297
297 /* 298 /*
@@ -305,13 +306,6 @@ static int context_struct_compute_av(struct context *scontext,
305 tclass <= SECCLASS_NETLINK_DNRT_SOCKET) 306 tclass <= SECCLASS_NETLINK_DNRT_SOCKET)
306 tclass = SECCLASS_NETLINK_SOCKET; 307 tclass = SECCLASS_NETLINK_SOCKET;
307 308
308 if (!tclass || tclass > policydb.p_classes.nprim) {
309 printk(KERN_ERR "security_compute_av: unrecognized class %d\n",
310 tclass);
311 return -EINVAL;
312 }
313 tclass_datum = policydb.class_val_to_struct[tclass - 1];
314
315 /* 309 /*
316 * Initialize the access vectors to the default values. 310 * Initialize the access vectors to the default values.
317 */ 311 */
@@ -322,6 +316,36 @@ static int context_struct_compute_av(struct context *scontext,
322 avd->seqno = latest_granting; 316 avd->seqno = latest_granting;
323 317
324 /* 318 /*
319 * Check for all the invalid cases.
320 * - tclass 0
321 * - tclass > policy and > kernel
322 * - tclass > policy but is a userspace class
323 * - tclass > policy but we do not allow unknowns
324 */
325 if (unlikely(!tclass))
326 goto inval_class;
327 if (unlikely(tclass > policydb.p_classes.nprim))
328 if (tclass > kdefs->cts_len ||
329 !kdefs->class_to_string[tclass - 1] ||
330 !policydb.allow_unknown)
331 goto inval_class;
332
333 /*
334 * Kernel class and we allow unknown so pad the allow decision
335 * the pad will be all 1 for unknown classes.
336 */
337 if (tclass <= kdefs->cts_len && policydb.allow_unknown)
338 avd->allowed = policydb.undefined_perms[tclass - 1];
339
340 /*
341 * Not in policy. Since decision is completed (all 1 or all 0) return.
342 */
343 if (unlikely(tclass > policydb.p_classes.nprim))
344 return 0;
345
346 tclass_datum = policydb.class_val_to_struct[tclass - 1];
347
348 /*
325 * If a specific type enforcement rule was defined for 349 * If a specific type enforcement rule was defined for
326 * this permission check, then use it. 350 * this permission check, then use it.
327 */ 351 */
@@ -387,6 +411,10 @@ static int context_struct_compute_av(struct context *scontext,
387 } 411 }
388 412
389 return 0; 413 return 0;
414
415inval_class:
416 printk(KERN_ERR "%s: unrecognized class %d\n", __FUNCTION__, tclass);
417 return -EINVAL;
390} 418}
391 419
392static int security_validtrans_handle_fail(struct context *ocontext, 420static int security_validtrans_handle_fail(struct context *ocontext,
@@ -1054,6 +1082,13 @@ static int validate_classes(struct policydb *p)
1054 const char *def_class, *def_perm, *pol_class; 1082 const char *def_class, *def_perm, *pol_class;
1055 struct symtab *perms; 1083 struct symtab *perms;
1056 1084
1085 if (p->allow_unknown) {
1086 u32 num_classes = kdefs->cts_len;
1087 p->undefined_perms = kcalloc(num_classes, sizeof(u32), GFP_KERNEL);
1088 if (!p->undefined_perms)
1089 return -ENOMEM;
1090 }
1091
1057 for (i = 1; i < kdefs->cts_len; i++) { 1092 for (i = 1; i < kdefs->cts_len; i++) {
1058 def_class = kdefs->class_to_string[i]; 1093 def_class = kdefs->class_to_string[i];
1059 if (!def_class) 1094 if (!def_class)
@@ -1062,6 +1097,10 @@ static int validate_classes(struct policydb *p)
1062 printk(KERN_INFO 1097 printk(KERN_INFO
1063 "security: class %s not defined in policy\n", 1098 "security: class %s not defined in policy\n",
1064 def_class); 1099 def_class);
1100 if (p->reject_unknown)
1101 return -EINVAL;
1102 if (p->allow_unknown)
1103 p->undefined_perms[i-1] = ~0U;
1065 continue; 1104 continue;
1066 } 1105 }
1067 pol_class = p->p_class_val_to_name[i-1]; 1106 pol_class = p->p_class_val_to_name[i-1];
@@ -1087,12 +1126,16 @@ static int validate_classes(struct policydb *p)
1087 printk(KERN_INFO 1126 printk(KERN_INFO
1088 "security: permission %s in class %s not defined in policy\n", 1127 "security: permission %s in class %s not defined in policy\n",
1089 def_perm, pol_class); 1128 def_perm, pol_class);
1129 if (p->reject_unknown)
1130 return -EINVAL;
1131 if (p->allow_unknown)
1132 p->undefined_perms[class_val-1] |= perm_val;
1090 continue; 1133 continue;
1091 } 1134 }
1092 perdatum = hashtab_search(perms->table, def_perm); 1135 perdatum = hashtab_search(perms->table, def_perm);
1093 if (perdatum == NULL) { 1136 if (perdatum == NULL) {
1094 printk(KERN_ERR 1137 printk(KERN_ERR
1095 "security: permission %s in class %s not found in policy\n", 1138 "security: permission %s in class %s not found in policy, bad policy\n",
1096 def_perm, pol_class); 1139 def_perm, pol_class);
1097 return -EINVAL; 1140 return -EINVAL;
1098 } 1141 }
@@ -1130,12 +1173,16 @@ static int validate_classes(struct policydb *p)
1130 printk(KERN_INFO 1173 printk(KERN_INFO
1131 "security: permission %s in class %s not defined in policy\n", 1174 "security: permission %s in class %s not defined in policy\n",
1132 def_perm, pol_class); 1175 def_perm, pol_class);
1176 if (p->reject_unknown)
1177 return -EINVAL;
1178 if (p->allow_unknown)
1179 p->undefined_perms[class_val-1] |= (1 << j);
1133 continue; 1180 continue;
1134 } 1181 }
1135 perdatum = hashtab_search(perms->table, def_perm); 1182 perdatum = hashtab_search(perms->table, def_perm);
1136 if (perdatum == NULL) { 1183 if (perdatum == NULL) {
1137 printk(KERN_ERR 1184 printk(KERN_ERR
1138 "security: permission %s in class %s not found in policy\n", 1185 "security: permission %s in class %s not found in policy, bad policy\n",
1139 def_perm, pol_class); 1186 def_perm, pol_class);
1140 return -EINVAL; 1187 return -EINVAL;
1141 } 1188 }
@@ -2102,6 +2149,16 @@ err:
2102 return rc; 2149 return rc;
2103} 2150}
2104 2151
2152int security_get_reject_unknown(void)
2153{
2154 return policydb.reject_unknown;
2155}
2156
2157int security_get_allow_unknown(void)
2158{
2159 return policydb.allow_unknown;
2160}
2161
2105struct selinux_audit_rule { 2162struct selinux_audit_rule {
2106 u32 au_seqno; 2163 u32 au_seqno;
2107 struct context au_ctxt; 2164 struct context au_ctxt;