From 4eea1da06217cf5b8ea83387b79dcc6f332354fb Mon Sep 17 00:00:00 2001 From: Daniel De Graaf Date: Thu, 21 Mar 2013 16:11:27 -0400 Subject: stubdom/vtpm: constrain locality by XSM label This adds the ability for a vTPM to constrain what localities a given client domain can use based on its XSM label. For example: locality=user_1:vm_r:domU_t=0,1,2 locality=user_1:vm_r:watcher_t=5 An arbitrary prefix can be matched by using a '*'. Signed-off-by: Daniel De Graaf --- stubdom/vtpm/vtpm.c | 76 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 2 deletions(-) (limited to 'stubdom') diff --git a/stubdom/vtpm/vtpm.c b/stubdom/vtpm/vtpm.c index 8f8095f5cc..f67de18667 100644 --- a/stubdom/vtpm/vtpm.c +++ b/stubdom/vtpm/vtpm.c @@ -139,6 +139,35 @@ int check_ordinal(tpmcmd_t* tpmcmd) { return true; } +struct locality_item { + char* lbl; + uint8_t mask[32]; +}; +#define MAX_CLIENT_LOCALITIES 16 +static struct locality_item client_locality[MAX_CLIENT_LOCALITIES]; +static int nr_client_localities = 0; + +static void *generate_locality_mask(domid_t domid, unsigned int handle) +{ + char label[512]; + int i; + if (tpmback_get_peercontext(domid, handle, label, sizeof(label))) + BUG(); + for(i=0; i < nr_client_localities; i++) { + if (!strcmp(client_locality[i].lbl, label)) + goto found; + if (client_locality[i].lbl[0] == '*') { + char * f = strstr(label, 1 + client_locality[i].lbl); + if (!strcmp(f, 1 + client_locality[i].lbl)) + goto found; + } + } + return NULL; + found: + tpmback_set_opaque(domid, handle, client_locality[i].mask); + return client_locality[i].mask; +} + static void main_loop(void) { tpmcmd_t* tpmcmd = NULL; int res = -1; @@ -164,11 +193,24 @@ static void main_loop(void) { while(tpmcmd) { /* Handle the request */ if(tpmcmd->req_len) { + uint8_t* locality_mask = tpmcmd->opaque; + uint8_t locality_bit = (1 << (tpmcmd->locality & 7)); + int locality_byte = tpmcmd->locality >> 3; tpmcmd->resp = NULL; tpmcmd->resp_len = 0; - /* First check for disabled ordinals */ - if(!check_ordinal(tpmcmd)) { + if (nr_client_localities && !locality_mask) + locality_mask = generate_locality_mask(tpmcmd->domid, tpmcmd->handle); + if (nr_client_localities && !locality_mask) { + error("Unknown client label in tpm_handle_command"); + create_error_response(tpmcmd, TPM_FAIL); + } + else if (nr_client_localities && !(locality_mask[locality_byte] & locality_bit)) { + error("Invalid locality (%d) for client in tpm_handle_command", tpmcmd->locality); + create_error_response(tpmcmd, TPM_FAIL); + } + /* Check for disabled ordinals */ + else if(!check_ordinal(tpmcmd)) { create_error_response(tpmcmd, TPM_BAD_ORDINAL); } /* If not disabled, do the command */ @@ -273,6 +315,36 @@ int parse_cmd_line(int argc, char** argv) pch = strtok(NULL, ","); } } + else if(!strncmp(argv[i], "locality=", 9)) { + char *lbl = argv[i] + 9; + char *pch = strchr(lbl, '='); + uint8_t* locality_mask = client_locality[nr_client_localities].mask; + if (pch == NULL) { + error("Invalid locality specification: %s", lbl); + return -1; + } + if (nr_client_localities == MAX_CLIENT_LOCALITIES) { + error("Too many locality specifications"); + return -1; + } + client_locality[nr_client_localities].lbl = lbl; + memset(locality_mask, 0, 32); + nr_client_localities++; + *pch = 0; + pch = strtok(pch + 1, ","); + while (pch != NULL) { + unsigned int loc; + if (sscanf(pch, "%u", &loc) == 1 && loc < 256) { + uint8_t locality_bit = (1 << (loc & 7)); + int locality_byte = loc >> 3; + locality_mask[locality_byte] |= locality_bit; + } else { + error("Invalid locality item: %s", pch); + return -1; + } + pch = strtok(NULL, ","); + } + } else { error("Invalid command line option `%s'", argv[i]); } -- cgit v1.2.3