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