PERFORCE change 32176 for review

Robert Watson rwatson at FreeBSD.org
Sat May 31 10:08:09 PDT 2003


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

Change 32176 by rwatson at rwatson_tislabs on 2003/05/31 10:08:05

	Mirror sbuf changes from MLS to Biba: when externalizing
	the Biba label, use sbufs in preference to C strings due
	to compactness of representation and robustness of the
	interfaces.

Affected files ...

.. //depot/projects/trustedbsd/mac/sys/security/mac_biba/mac_biba.c#210 edit

Differences ...

==== //depot/projects/trustedbsd/mac/sys/security/mac_biba/mac_biba.c#210 (text+ko) ====

@@ -49,6 +49,7 @@
 #include <sys/malloc.h>
 #include <sys/mount.h>
 #include <sys/proc.h>
+#include <sys/sbuf.h>
 #include <sys/systm.h>
 #include <sys/sysproto.h>
 #include <sys/sysent.h>
@@ -529,127 +530,139 @@
 }
 
 /*
- * mac_biba_element_to_string() is basically an snprintf wrapper with
- * the same properties as snprintf().  It returns the length it would
- * have added to the string in the event the string is too short.
+ * mac_biba_compartment_to_string() takes an sbuf, range of compartments,
+ * and flag indicating whether this is the first entry in a list of
+ * compartments.  A string representing the compartment range will be
+ * appended to the sbuf, or -1 will be returned if there wasn't space.
+ */
+static int
+mac_biba_compartment_to_string(struct sbuf *sb, int start, int stop, int first)
+{
+	char *pluses, *prefix;
+
+	if (stop == start + 1)
+		pluses = "+";
+	else
+		pluses = "++";
+
+	if (first)
+		prefix = ":";
+	else
+		prefix = "+";
+
+	if (stop == start)
+		return (sbuf_printf(sb, "%s%d", prefix, start));
+	else
+		return (sbuf_printf(sb, "%s%d%s%d", prefix, start, pluses,
+		    stop));
+}
+
+/*
+ * mac_biba_element_to_string() accepts an sbuf and Biba element.  It
+ * converts the Biba element to a string and stores the result in the
+ * sbuf; if there isn't space in the sbuf, -1 is returned.
  */
-static size_t
-mac_biba_element_to_string(char *string, size_t size,
-    struct mac_biba_element *element)
+static int
+mac_biba_element_to_string(struct sbuf *sb, struct mac_biba_element *element)
 {
-	int r, bit, pbit;
-	size_t left, len;
-	char *p;
+	int i, first, start, stop, prevbit;
 
 	switch (element->mbe_type) {
 	case MAC_BIBA_TYPE_HIGH:
-		return (snprintf(string, size, "high"));
+		return (sbuf_printf(sb, "high"));
 
 	case MAC_BIBA_TYPE_LOW:
-		return (snprintf(string, size, "low"));
+		return (sbuf_printf(sb, "low"));
 
 	case MAC_BIBA_TYPE_EQUAL:
-		return (snprintf(string, size, "equal"));
+		return (sbuf_printf(sb, "equal"));
 
 	case MAC_BIBA_TYPE_GRADE:
-		bit = pbit = r = 0;
-		left = size;
+		if (sbuf_printf(sb, "%d", element->mbe_grade) == -1)
+			return (-1);
 
-		p = string + (len = snprintf(string, left, "%d:",
-		    element->mbe_grade));
-		left -= len;
-
-		do {
-			pbit = bit++;
-			len = 0;
-			if (bit <= MAC_BIBA_MAX_COMPARTMENTS &&
-			    MAC_BIBA_BIT_TEST(bit, element->mbe_compartments)) {
-				if (pbit == bit - 1) {
-					if (r == 0)
-						p += len = snprintf(p, left,
-						    "%d+", bit);
-					r++;
+		first = 1;		/* Need a ':' and no '+'. */
+		start = 0; stop = 0;	/* No starting range. */
+		prevbit = 0;		/* Was previous bit set? */
+		for (i = 1; i <= MAC_BIBA_MAX_COMPARTMENTS; i++) {
+			if (MAC_BIBA_BIT_TEST(i, element->mbe_compartments)) {
+				if (prevbit)
+					stop = i;
+				else {
+					start = i;
+					stop = i;
 				}
+				prevbit = 1;
 			} else {
-				if (r > 2)
-					p += len = snprintf(p, left, "+%d+",
-					    pbit);
-				else if (r > 1)
-					p += len = snprintf(p, left, "%d+",
-					    pbit);
-				r = 0;
+				if (prevbit) {
+					if (mac_biba_compartment_to_string(sb,
+					    start, stop, first) == -1)
+						return (-1);
+					if (first)
+						first = 0;
+				}
+				prevbit = 0;
 			}
-			left -= len;
-		} while(bit <= MAC_BIBA_MAX_COMPARTMENTS);
+		}
+		/*
+		 * If the last bit was set, we need to close that range to
+		 * terminate the string.
+		 */
+		if (prevbit) {
+			if (mac_biba_compartment_to_string(sb, start, stop,
+			    first) == -1)
+				return (-1);
+		}
+		return (0);
 
-		len = size - left - 1;
-		if (len > 0 && len < size)
-			string[len] = '\0';
-		else
-			string[0] = '\0';
-			
-		return (len);
-
 	default:
 		panic("mac_biba_element_to_string: invalid type (%d)",
 		    element->mbe_type);
 	}
 }
 
+/*
+ * mac_biba_to_string() converts an Biba label to a string, placing the
+ * results in the passed string buffer.  It returns 0 on success,
+ * or EINVAL if there isn't room in the buffer.  The size of the
+ * string appended, leaving out the nul termination, is returned to
+ * the caller via *caller_len.  Eventually, we should expose the
+ * sbuf to the caller rather than using C strings at this layer.
+ */
 static int
 mac_biba_to_string(char *string, size_t size, size_t *caller_len,
     struct mac_biba *mac_biba)
 {
-	size_t left, len;
-	char *curptr;
+	struct sbuf sb;
 
-	bzero(string, size);
-	curptr = string;
-	left = size;
+	sbuf_new(&sb, string, size, SBUF_FIXEDLEN);
 
 	if (mac_biba->mb_flags & MAC_BIBA_FLAG_SINGLE) {
-		len = mac_biba_element_to_string(curptr, left,
-		    &mac_biba->mb_single);
-		if (len >= left)
+		if (mac_biba_element_to_string(&sb, &mac_biba->mb_single)
+		    == -1)
 			return (EINVAL);
-		left -= len;
-		curptr += len;
 	}
 
 	if (mac_biba->mb_flags & MAC_BIBA_FLAG_RANGE) {
-		len = snprintf(curptr, left, "(");
-		if (len >= left)
+		if (sbuf_putc(&sb, '(') == -1)
 			return (EINVAL);
-		left -= len;
-		curptr += len;
 
-		len = mac_biba_element_to_string(curptr, left,
-		    &mac_biba->mb_rangelow);
-		if (len >= left)
+		if (mac_biba_element_to_string(&sb, &mac_biba->mb_rangelow)
+		    == -1)
 			return (EINVAL);
-		left -= len;
-		curptr += len;
 
-		len = snprintf(curptr, left, "-");
-		if (len >= left)
+		if (sbuf_putc(&sb, '-') == -1)
 			return (EINVAL);
-		left -= len;
-		curptr += len;
 
-		len = mac_biba_element_to_string(curptr, left,
-		    &mac_biba->mb_rangehigh);
-		if (len >= left)
+		if (mac_biba_element_to_string(&sb, &mac_biba->mb_rangehigh)
+		    == -1)
 			return (EINVAL);
-		left -= len;
-		curptr += len;
 
-		len = snprintf(curptr, left, ")");
-		if (len >= left)
+		if (sbuf_putc(&sb, ')') == -1)
 			return (EINVAL);
-		left -= len;
-		curptr += len;
 	}
 
+	sbuf_finish(&sb);
 	*caller_len = strlen(string);
 	return (0);
 }
@@ -667,11 +680,11 @@
 	(*claimed)++;
 
 	mac_biba = SLOT(label);
+
 	error = mac_biba_to_string(element_data, size, len, mac_biba);
 	if (error)
 		return (error);
 
-	*len = strlen(element_data);
 	return (0);
 }
 


More information about the p4-projects mailing list