PERFORCE change 111059 for review

Todd Miller millert at FreeBSD.org
Mon Dec 4 10:46:26 PST 2006


http://perforce.freebsd.org/chv.cgi?CH=111059

Change 111059 by millert at millert_g5tower on 2006/12/04 18:45:06

	numsids argument to security_get_file_sids() should be u32 *
	Reorganize security_get_file_sids() slightly to make easier to read 
	Hold policy lock in security_get_file_sids()
	Check for mls_context_isvalid() in security_get_file_sids()
	Use non-blocking allocations in security_get_file_sids()

Affected files ...

.. //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/ss/security.h#3 edit
.. //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/ss/services.c#3 edit

Differences ...

==== //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/ss/security.h#3 (text+ko) ====

@@ -69,7 +69,7 @@
 int security_get_user_sids(u32 callsid, char *username,
 			   u32 **sids, u32 *nel);
 
-int security_get_file_sids(u32 user, u16 sclass, u32 **sids, int *numsids);
+int security_get_file_sids(u32 user, u16 sclass, u32 **sids, u32 *numsids);
 
 int security_port_sid(u16 domain, u16 type, u8 protocol, u16 port,
 	u32 *out_sid);

==== //depot/projects/trustedbsd/sedarwin8/policies/sedarwin/sedarwin/ss/services.c#3 (text+ko) ====

@@ -1632,56 +1632,69 @@
 			void *args)
 {
 	struct getfilesids *p = args;
+	struct role_datum *role;
+	struct user_datum *usrdatum;
+	struct constraint_node *constraint;
 	struct context fc;
-	u16 specified = avk->specified & ~(AVTAB_ENABLED|AVTAB_ENABLED_OLD);
-	u32 ir, iu;
+	u32 sid;
 
 	if (avk->source_type != p->scon->type ||
 	    avk->target_class != p->sclass ||
-	    (specified & AVTAB_AV) == 0 ||
+	    (avk->specified & AVTAB_AV) == 0 ||
 	    (avd->data & COMMON_FILE__RELABELTO) == 0)
 		return 0;
 
 	fc.type = avk->target_type;
 
-	for (ir = 0; ir < policydb.p_roles.nprim; ir++) {
-		if (ir + 1 != OBJECT_R_VAL &&
-		    ebitmap_get_bit(&policydb.role_val_to_struct[ir]->types,
-		    fc.type - 1) == 0)
-			continue;
+	for (fc.role = 1; fc.role <= policydb.p_roles.nprim; fc.role++) {
+		/*
+		 * Role must be authorized for the type.
+		 */
+		if (fc.role != OBJECT_R_VAL) {
+			role = policydb.role_val_to_struct[fc.role - 1];
+			if (ebitmap_get_bit(&role->types, fc.type - 1) == 0)
+				continue;	/* not associated with type */
+		}
 
-		fc.role = ir + 1;
-		for (iu = 0; iu < policydb.p_users.nprim; iu++) {
-			struct constraint_node *constraint;
-			u32 sid;
+		for (fc.user = 1; fc.user <= policydb.p_users.nprim; fc.user++) {
+			/*
+			 * User must be authorized for the role.
+			 */
+			if (fc.role != OBJECT_R_VAL) {
+				usrdatum =
+				    policydb.user_val_to_struct[fc.user - 1];
+				if (usrdatum == NULL ||
+				    ebitmap_get_bit(&usrdatum->roles,
+				    fc.role - 1) == 0)
+					continue;
+			}
 
-			if (fc.role == OBJECT_R_VAL ||
-			    ebitmap_get_bit(&policydb.user_val_to_struct[iu]->roles, ir)) {
-				fc.user = iu + 1;
-				for (constraint = p->sca->constraints;
-				    constraint != NULL;
-				    constraint = constraint->next) {
-					if ((constraint->permissions & COMMON_FILE__RELABELTO) &&
-					    !constraint_expr_eval(p->scon, &fc,
-					    NULL, constraint->expr))
-						break;
-				}
+			for (constraint = p->sca->constraints;
+			    constraint != NULL;
+			    constraint = constraint->next) {
+				if ((constraint->permissions & COMMON_FILE__RELABELTO) &&
+				    !constraint_expr_eval(p->scon, &fc, NULL,
+				    constraint->expr))
+					break;
+			}
 
-				if (constraint == NULL &&
-				    sidtab_context_to_sid(&sidtab, &fc, &sid) == 0) {
-					/* passed all checks, add to list */
-					if (p->numsids == p->maxsids) {
-						u32 *sids;
+			if (constraint == NULL &&
+			    mls_context_isvalid(&policydb, &fc) &&
+			    sidtab_context_to_sid(&sidtab, &fc, &sid) == 0) {
+				/* passed all checks, add to list */
+				if (p->numsids == p->maxsids) {
+					u32 *sids;
 
-						p->maxsids += 16;
-						sids = kmalloc(sizeof(u32) * p->maxsids, GFP_KERNEL);
-						memcpy(sids, p->sids,
-						    sizeof(u32) * p->numsids);
-						kfree(p->sids);
-						p->sids = sids;
-					}
-					p->sids[p->numsids++] = sid;
+					p->maxsids *= 2;
+					sids = kmalloc(sizeof(u32) * p->maxsids, GFP_ATOMIC);
+					if (sids == NULL)
+						return ENOMEM;
+					memcpy(sids, p->sids,
+					    sizeof(u32) * p->numsids);
+					kfree(p->sids);
+					p->sids = sids;
 				}
+				p->sids[p->numsids++] = sid;
 			}
 		}
 	}
@@ -1692,32 +1705,53 @@
 int security_get_file_sids(u32 user,
 			   u16 sclass,
 			   u32 **sids,
-			   int *numsids)
+			   u32 *numsids)
 {
 	struct getfilesids p;
 	struct context *scontext;
+	int rc;
+
+	if (!ss_initialized) {
+		*sids = NULL;
+		*numsids = 0;
+		return 0;
+	}
 
-	scontext = sidtab_search(&sidtab, user);
-	if (scontext == NULL)
+	if (!sclass || sclass > policydb.p_classes.nprim)
 		goto out_err;
 
+	POLICY_RDLOCK;
+
+	scontext = sidtab_search(&sidtab, user);
+	if (scontext == NULL) {
+		rc = EINVAL;
+		goto out_unlock;
+	}
 	p.scon = scontext;
 	p.sclass = sclass;
-	if (!sclass || sclass > policydb.p_classes.nprim)
-		goto out_err;
 	p.sca = policydb.class_val_to_struct[sclass - 1];
 	p.maxsids = 32;
-	p.sids = kmalloc(sizeof(u32) * p.maxsids, GFP_KERNEL);
+	p.sids = kmalloc(sizeof(u32) * p.maxsids, GFP_ATOMIC);
+	if (p.sids == NULL) {
+		rc = ENOMEM;
+		goto out_unlock;
+	}
 	p.numsids = 0;
-	avtab_map(&policydb.te_avtab, getfilesids1, &p);
+	rc = avtab_map(&policydb.te_avtab, getfilesids1, &p);
+	if (rc != 0) {
+		kfree(p.sids);
+		goto out_unlock;
+	}
 	*sids = p.sids;
 	*numsids = p.numsids;
-	return 0;
+	return rc;
 
+out_unlock:
+	POLICY_RDUNLOCK;
 out_err:
 	*numsids = 0;
 	*sids = NULL;
-	return EINVAL;
+	return rc;
 }
 
 /**


More information about the trustedbsd-cvs mailing list