Rewrite Biba and MLS label externalization code to use sbufs instead

of C strings internally; C strings require a lot of return value
checking that (a) takes a lot of space, and (b) is difficult to get
right.  Prior to the advent of compartment support, modeling APIs
for helper functions on snprintf worked fine; with the additional
complexity, the sbuf_printf() API makes a lot more sense.

While doing this, break out the printing of sequential compartment
lists into a helper function, mac_{biba,mls}_compartment_to_string().
This permits the main body of mac_{biba,mls}_element_to_string()
to be concerned only with identifying sequential ranges rather
than rendering.

At a less disruptive moment, we'll push the move from snprintf()-like
interface to sbuf()-like interface up into the MAC Framework layer.

Obtained from:	TrustedBSD Project
Sponsored by:	DARPA, Network Associates Laboratories
This commit is contained in:
Robert Watson 2003-05-31 19:01:44 +00:00
parent 01bfa91fa2
commit 05e830f1e7
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=115497
2 changed files with 99 additions and 105 deletions

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
* Copyright (c) 2001, 2002 Networks Associates Technology, Inc.
* Copyright (c) 2001, 2002, 2003 Networks Associates Technology, Inc.
* All rights reserved.
*
* This software was developed by Robert Watson for the TrustedBSD Project.
@ -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>
@ -528,36 +529,45 @@ mac_biba_destroy_label(struct label *label)
}
/*
* 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_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 pos, bit = 1;
int i, first;
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:
pos = snprintf(string, size, "%d:", element->mbe_grade);
for (bit = 1; bit <= MAC_BIBA_MAX_COMPARTMENTS; bit++) {
if (MAC_BIBA_BIT_TEST(bit, element->mbe_compartments))
pos += snprintf(string + pos, size - pos,
"%d+", bit);
if (sbuf_printf(sb, "%d", element->mbe_grade) == -1)
return (-1);
first = 1;
for (i = 1; i <= MAC_BIBA_MAX_COMPARTMENTS; i++) {
if (MAC_BIBA_BIT_TEST(i, element->mbe_compartments)) {
if (first) {
if (sbuf_putc(sb, ':') == -1)
return (-1);
if (sbuf_printf(sb, "%d", i) == -1)
return (-1);
first = 0;
} else {
if (sbuf_printf(sb, "+%d", i) == -1)
return (-1);
}
}
}
if (string[pos - 1] == '+' || string[pos - 1] == ':')
string[--pos] = '\0';
return (pos);
return (0);
default:
panic("mac_biba_element_to_string: invalid type (%d)",
@ -565,60 +575,48 @@ mac_biba_element_to_string(char *string, size_t size,
}
}
/*
* 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);
}
@ -640,7 +638,6 @@ mac_biba_externalize_label(struct label *label, char *element_name,
if (error)
return (error);
*len = strlen(element_data);
return (0);
}

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1999, 2000, 2001, 2002 Robert N. M. Watson
* Copyright (c) 2001, 2002 Networks Associates Technology, Inc.
* Copyright (c) 2001, 2002, 2003 Networks Associates Technology, Inc.
* All rights reserved.
*
* This software was developed by Robert Watson for the TrustedBSD Project.
@ -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>
@ -493,36 +494,45 @@ mac_mls_destroy_label(struct label *label)
}
/*
* mac_mls_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_mls_element_to_string() accepts an sbuf and MLS element. It
* converts the MLS 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_mls_element_to_string(char *string, size_t size,
struct mac_mls_element *element)
static int
mac_mls_element_to_string(struct sbuf *sb, struct mac_mls_element *element)
{
int pos, bit = 1;
int i, first;
switch (element->mme_type) {
case MAC_MLS_TYPE_HIGH:
return (snprintf(string, size, "high"));
return (sbuf_printf(sb, "high"));
case MAC_MLS_TYPE_LOW:
return (snprintf(string, size, "low"));
return (sbuf_printf(sb, "low"));
case MAC_MLS_TYPE_EQUAL:
return (snprintf(string, size, "equal"));
return (sbuf_printf(sb, "equal"));
case MAC_MLS_TYPE_LEVEL:
pos = snprintf(string, size, "%d:", element->mme_level);
for (bit = 1; bit <= MAC_MLS_MAX_COMPARTMENTS; bit++) {
if (MAC_MLS_BIT_TEST(bit, element->mme_compartments))
pos += snprintf(string + pos, size - pos,
"%d+", bit);
if (sbuf_printf(sb, "%d", element->mme_level) == -1)
return (-1);
first = 1;
for (i = 1; i <= MAC_MLS_MAX_COMPARTMENTS; i++) {
if (MAC_MLS_BIT_TEST(i, element->mme_compartments)) {
if (first) {
if (sbuf_putc(sb, ':') == -1)
return (-1);
if (sbuf_printf(sb, "%d", i) == -1)
return (-1);
first = 0;
} else {
if (sbuf_printf(sb, "+%d", i) == -1)
return (-1);
}
}
}
if (string[pos - 1] == '+' || string[pos - 1] == ':')
string[--pos] = NULL;
return (pos);
return (0);
default:
panic("mac_mls_element_to_string: invalid type (%d)",
@ -530,60 +540,48 @@ mac_mls_element_to_string(char *string, size_t size,
}
}
static size_t
/*
* mac_mls_to_string() converts an MLS 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_mls_to_string(char *string, size_t size, size_t *caller_len,
struct mac_mls *mac_mls)
{
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_mls->mm_flags & MAC_MLS_FLAG_SINGLE) {
len = mac_mls_element_to_string(curptr, left,
&mac_mls->mm_single);
if (len >= left)
if (mac_mls_element_to_string(&sb, &mac_mls->mm_single)
== -1)
return (EINVAL);
left -= len;
curptr += len;
}
if (mac_mls->mm_flags & MAC_MLS_FLAG_RANGE) {
len = snprintf(curptr, left, "(");
if (len >= left)
if (sbuf_putc(&sb, '(') == -1)
return (EINVAL);
left -= len;
curptr += len;
len = mac_mls_element_to_string(curptr, left,
&mac_mls->mm_rangelow);
if (len >= left)
if (mac_mls_element_to_string(&sb, &mac_mls->mm_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_mls_element_to_string(curptr, left,
&mac_mls->mm_rangehigh);
if (len >= left)
if (mac_mls_element_to_string(&sb, &mac_mls->mm_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);
}
@ -606,7 +604,6 @@ mac_mls_externalize_label(struct label *label, char *element_name,
if (error)
return (error);
*len = strlen(element_data);
return (0);
}