Re: [PATCH v2 1/2] SELinux: reduce overhead of mls_level_isvalid()function call

From: Stephen Smalley
Date: Fri Jun 07 2013 - 14:10:30 EST


On 06/05/2013 05:15 PM, Waiman Long wrote:
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c
index 30f119b..100b3e6 100644
--- a/security/selinux/ss/ebitmap.c
+++ b/security/selinux/ss/ebitmap.c
@@ -213,7 +213,12 @@ netlbl_import_failure:
}
#endif /* CONFIG_NETLABEL */

-int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2)
+/*
+ * Check to see if all the bits set in e2 are also set in e1. Optionally,
+ * if last_e2bit is non-zero, the highest set bit in e2 cannot exceed
+ * last_e2bit.
+ */
+int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2, u32 last_e2bit)
{
struct ebitmap_node *n1, *n2;
int i;
@@ -223,6 +228,33 @@ int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2)

n1 = e1->node;
n2 = e2->node;
+ if (last_e2bit) {
+ while (n1 && n2 && (n1->startbit <= n2->startbit)) {
+ int lastsetbit = -1;
+
+ if (n1->startbit < n2->startbit) {
+ n1 = n1->next;
+ continue;
+ }
+ for (i = EBITMAP_UNIT_NUMS - 1; i >= 0; i--) {
+ if (!n2->maps[i])
+ continue;
+ if ((n1->maps[i] & n2->maps[i]) != n2->maps[i])
+ return 0;
+ if (lastsetbit < 0)
+ lastsetbit = n2->startbit +
+ i * EBITMAP_UNIT_SIZE +
+ __fls(n2->maps[i]);
+ }
+ if ((lastsetbit >= 0) && (lastsetbit > last_e2bit))
+ return 0;
+
+ n1 = n1->next;
+ n2 = n2->next;
+ }
+ goto done;
+ }
+

Can't you unify this logic with the nearly identical logic below?

while (n1 && n2 && (n1->startbit <= n2->startbit)) {
if (n1->startbit < n2->startbit) {
n1 = n1->next;
@@ -237,6 +269,7 @@ int ebitmap_contains(struct ebitmap *e1, struct ebitmap *e2)
n2 = n2->next;
}

+done:
if (n2)
return 0;


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/