From owner-p4-projects@FreeBSD.ORG Sat May 31 10:08:09 2003 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id C4AAE37B404; Sat, 31 May 2003 10:08:08 -0700 (PDT) Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7070837B401 for ; Sat, 31 May 2003 10:08:08 -0700 (PDT) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 825E943F75 for ; Sat, 31 May 2003 10:08:07 -0700 (PDT) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.12.6/8.12.6) with ESMTP id h4VH870U009016 for ; Sat, 31 May 2003 10:08:07 -0700 (PDT) (envelope-from bb+lists.freebsd.perforce@cyrus.watson.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.12.6/8.12.6/Submit) id h4VH87oJ009009 for perforce@freebsd.org; Sat, 31 May 2003 10:08:07 -0700 (PDT) Date: Sat, 31 May 2003 10:08:07 -0700 (PDT) Message-Id: <200305311708.h4VH87oJ009009@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to bb+lists.freebsd.perforce@cyrus.watson.org using -f From: Robert Watson To: Perforce Change Reviews Subject: PERFORCE change 32176 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 31 May 2003 17:08:09 -0000 http://perforce.freebsd.org/chv.cgi?CH=32176 Change 32176 by rwatson@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 #include #include +#include #include #include #include @@ -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); }