aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/ss/avtab.c
diff options
context:
space:
mode:
authorStephen Smalley <sds@tycho.nsa.gov>2007-11-07 10:08:00 -0500
committerJames Morris <jmorris@namei.org>2007-11-07 16:56:23 -0500
commit45e5421eb5bbcd9efa037d682dd357284e3ef982 (patch)
treeceb24143024fe335d08ac30fb4da9ca25fbeb6e6 /security/selinux/ss/avtab.c
parent6d2b685564ba417f4c6d80c3661f0dfee13fff85 (diff)
SELinux: add more validity checks on policy load
Add more validity checks at policy load time to reject malformed policies and prevent subsequent out-of-range indexing when in permissive mode. Resolves the NULL pointer dereference reported in https://bugzilla.redhat.com/show_bug.cgi?id=357541. Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> Signed-off-by: James Morris <jmorris@namei.org>
Diffstat (limited to 'security/selinux/ss/avtab.c')
-rw-r--r--security/selinux/ss/avtab.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/security/selinux/ss/avtab.c b/security/selinux/ss/avtab.c
index 7551af1f7899..9e70a160d7da 100644
--- a/security/selinux/ss/avtab.c
+++ b/security/selinux/ss/avtab.c
@@ -325,7 +325,7 @@ static uint16_t spec_order[] = {
325 AVTAB_MEMBER 325 AVTAB_MEMBER
326}; 326};
327 327
328int avtab_read_item(void *fp, u32 vers, struct avtab *a, 328int avtab_read_item(struct avtab *a, void *fp, struct policydb *pol,
329 int (*insertf)(struct avtab *a, struct avtab_key *k, 329 int (*insertf)(struct avtab *a, struct avtab_key *k,
330 struct avtab_datum *d, void *p), 330 struct avtab_datum *d, void *p),
331 void *p) 331 void *p)
@@ -333,10 +333,11 @@ int avtab_read_item(void *fp, u32 vers, struct avtab *a,
333 __le16 buf16[4]; 333 __le16 buf16[4];
334 u16 enabled; 334 u16 enabled;
335 __le32 buf32[7]; 335 __le32 buf32[7];
336 u32 items, items2, val; 336 u32 items, items2, val, vers = pol->policyvers;
337 struct avtab_key key; 337 struct avtab_key key;
338 struct avtab_datum datum; 338 struct avtab_datum datum;
339 int i, rc; 339 int i, rc;
340 unsigned set;
340 341
341 memset(&key, 0, sizeof(struct avtab_key)); 342 memset(&key, 0, sizeof(struct avtab_key));
342 memset(&datum, 0, sizeof(struct avtab_datum)); 343 memset(&datum, 0, sizeof(struct avtab_datum));
@@ -420,12 +421,35 @@ int avtab_read_item(void *fp, u32 vers, struct avtab *a,
420 key.target_class = le16_to_cpu(buf16[items++]); 421 key.target_class = le16_to_cpu(buf16[items++]);
421 key.specified = le16_to_cpu(buf16[items++]); 422 key.specified = le16_to_cpu(buf16[items++]);
422 423
424 if (!policydb_type_isvalid(pol, key.source_type) ||
425 !policydb_type_isvalid(pol, key.target_type) ||
426 !policydb_class_isvalid(pol, key.target_class)) {
427 printk(KERN_WARNING "security: avtab: invalid type or class\n");
428 return -1;
429 }
430
431 set = 0;
432 for (i = 0; i < ARRAY_SIZE(spec_order); i++) {
433 if (key.specified & spec_order[i])
434 set++;
435 }
436 if (!set || set > 1) {
437 printk(KERN_WARNING
438 "security: avtab: more than one specifier\n");
439 return -1;
440 }
441
423 rc = next_entry(buf32, fp, sizeof(u32)); 442 rc = next_entry(buf32, fp, sizeof(u32));
424 if (rc < 0) { 443 if (rc < 0) {
425 printk("security: avtab: truncated entry\n"); 444 printk("security: avtab: truncated entry\n");
426 return -1; 445 return -1;
427 } 446 }
428 datum.data = le32_to_cpu(*buf32); 447 datum.data = le32_to_cpu(*buf32);
448 if ((key.specified & AVTAB_TYPE) &&
449 !policydb_type_isvalid(pol, datum.data)) {
450 printk(KERN_WARNING "security: avtab: invalid type\n");
451 return -1;
452 }
429 return insertf(a, &key, &datum, p); 453 return insertf(a, &key, &datum, p);
430} 454}
431 455
@@ -435,7 +459,7 @@ static int avtab_insertf(struct avtab *a, struct avtab_key *k,
435 return avtab_insert(a, k, d); 459 return avtab_insert(a, k, d);
436} 460}
437 461
438int avtab_read(struct avtab *a, void *fp, u32 vers) 462int avtab_read(struct avtab *a, void *fp, struct policydb *pol)
439{ 463{
440 int rc; 464 int rc;
441 __le32 buf[1]; 465 __le32 buf[1];
@@ -459,7 +483,7 @@ int avtab_read(struct avtab *a, void *fp, u32 vers)
459 goto bad; 483 goto bad;
460 484
461 for (i = 0; i < nel; i++) { 485 for (i = 0; i < nel; i++) {
462 rc = avtab_read_item(fp,vers, a, avtab_insertf, NULL); 486 rc = avtab_read_item(a, fp, pol, avtab_insertf, NULL);
463 if (rc) { 487 if (rc) {
464 if (rc == -ENOMEM) 488 if (rc == -ENOMEM)
465 printk(KERN_ERR "security: avtab: out of memory\n"); 489 printk(KERN_ERR "security: avtab: out of memory\n");