[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 4/4] stubdom/vtpm: Support multiple backends and locality
On 11/27/2012 03:34 PM, Matthew Fioravante wrote: > On 11/27/2012 03:30 PM, Daniel De Graaf wrote: >> On 11/27/2012 03:21 PM, Matthew Fioravante wrote: >>> On 11/27/2012 03:11 PM, Daniel De Graaf wrote: >>>> On 11/27/2012 02:48 PM, Matthew Fioravante wrote: >>>>> On 11/27/2012 02:02 PM, Daniel De Graaf wrote: >>>>>> On 11/27/2012 01:19 PM, Matthew Fioravante wrote: >>>>>>> On 11/27/2012 10:14 AM, Daniel De Graaf wrote: >>>>>>>> The vTPM protocol now contains a field allowing the locality of a >>>>>>>> command to be specified; pass this to the TPM when processing a packet. >>>>>>>> This also enables a single vTPM to provide multiple tpmback interfaces >>>>>>>> so that several closely related domains can share a vTPM (for example, >>>>>>>> a >>>>>>>> qemu device stubdom and its target domain). >>>>>>>> >>>>>>>> Signed-off-by: Daniel De Graaf <dgdegra@xxxxxxxxxxxxx> >>>>>>>> --- >>>>>>>> stubdom/tpmemu-0.7.4.patch | 61 >>>>>>>> ++++++++++++++++++++++++++++++++++++++++++---- >>>>>>>> stubdom/vtpm/vtpm.c | 16 +++--------- >>>>>>>> 2 files changed, 59 insertions(+), 18 deletions(-) >>>>>>>> >>>>>>>> diff --git a/stubdom/tpmemu-0.7.4.patch b/stubdom/tpmemu-0.7.4.patch >>>>>>>> index b84eff1..31ace1a 100644 >>>>>>>> --- a/stubdom/tpmemu-0.7.4.patch >>>>>>>> +++ b/stubdom/tpmemu-0.7.4.patch >>>>>>>> @@ -1,9 +1,60 @@ >>>>>>>> -diff -Naur tpm_emulator-x86_64-back/tpm/tpm_emulator_extern.c >>>>>>>> tpm_emulator-x86_64/tpm/tpm_emulator_extern.c >>>>>>>> ---- tpm_emulator-x86_64-back/tpm/tpm_emulator_extern.c 2012-04-27 >>>>>>>> 10:55:46.581963398 -0400 >>>>>>>> -+++ tpm_emulator-x86_64/tpm/tpm_emulator_extern.c 2012-04-27 >>>>>>>> 10:56:02.193034152 -0400 >>>>>>>> -@@ -249,7 +249,7 @@ >>>>>>>> +diff --git a/tpm/tpm_capability.c b/tpm/tpm_capability.c >>>>>>>> +index 60bbb90..f8f7f0f 100644 >>>>>>>> +--- a/tpm/tpm_capability.c >>>>>>>> ++++ b/tpm/tpm_capability.c >>>>>>>> +@@ -949,6 +949,8 @@ static TPM_RESULT set_vendor(UINT32 subCap, BYTE >>>>>>>> *setValue, >>>>>>>> + UINT32 setValueSize, BOOL ownerAuth, >>>>>>>> + BOOL deactivated, BOOL disabled) >>>>>>>> + { >>>>>>>> ++ if (tpmData.stany.flags.localityModifier != 8) >>>>>>>> ++ return TPM_BAD_PARAMETER; >>>>>>>> + /* set the capability area with the specified data, on failure >>>>>>>> + deactivate the TPM */ >>>>>>>> + switch (subCap) { >>>>>>>> +diff --git a/tpm/tpm_cmd_handler.c b/tpm/tpm_cmd_handler.c >>>>>>>> +index 288d1ce..9e1cfb4 100644 >>>>>>>> +--- a/tpm/tpm_cmd_handler.c >>>>>>>> ++++ b/tpm/tpm_cmd_handler.c >>>>>>>> +@@ -4132,7 +4132,7 @@ void tpm_emulator_shutdown() >>>>>>>> + tpm_extern_release(); >>>>>>>> + } >>>>>>>> + >>>>>>>> +-int tpm_handle_command(const uint8_t *in, uint32_t in_size, uint8_t >>>>>>>> **out, uint32_t *out_size) >>>>>>>> ++int tpm_handle_command(const uint8_t *in, uint32_t in_size, uint8_t >>>>>>>> **out, uint32_t *out_size, int locality) >>>>>>>> + { >>>>>>>> + TPM_REQUEST req; >>>>>>>> + TPM_RESPONSE rsp; >>>>>>>> +@@ -4140,7 +4140,9 @@ int tpm_handle_command(const uint8_t *in, >>>>>>>> uint32_t in_size, uint8_t **out, uint3 >>>>>>>> + UINT32 len; >>>>>>>> + BOOL free_out; >>>>>>>> + >>>>>>>> +- debug("tpm_handle_command()"); >>>>>>>> ++ debug("tpm_handle_command(%d)", locality); >>>>>>>> ++ if (locality != -1) >>>>>>>> ++ tpmData.stany.flags.localityModifier = locality; >>>>>>>> + >>>>>>>> + /* we need the whole packet at once, otherwise unmarshalling will >>>>>>>> fail */ >>>>>>>> + if (tpm_unmarshal_TPM_REQUEST((uint8_t**)&in, &in_size, &req) != >>>>>>>> 0) { >>>>>>>> +diff --git a/tpm/tpm_emulator.h b/tpm/tpm_emulator.h >>>>>>>> +index eed749e..4c228bd 100644 >>>>>>>> +--- a/tpm/tpm_emulator.h >>>>>>>> ++++ b/tpm/tpm_emulator.h >>>>>>>> +@@ -59,7 +59,7 @@ void tpm_emulator_shutdown(void); >>>>>>>> + * its usage. In case of an error, all internally allocated memory >>>>>>>> + * is released and the the state of out and out_size is unspecified. >>>>>>>> + */ >>>>>>>> +-int tpm_handle_command(const uint8_t *in, uint32_t in_size, uint8_t >>>>>>>> **out, uint32_t *out_size); >>>>>>>> ++int tpm_handle_command(const uint8_t *in, uint32_t in_size, uint8_t >>>>>>>> **out, uint32_t *out_size, int locality); >>>>>>>> + >>>>>>>> + #endif /* _TPM_EMULATOR_H_ */ >>>>>>>> + >>>>>>>> +diff --git a/tpm/tpm_emulator_extern.c b/tpm/tpm_emulator_extern.c >>>>>>>> +index aabe6c3..440a01b 100644 >>>>>>>> +--- a/tpm/tpm_emulator_extern.c >>>>>>>> ++++ b/tpm/tpm_emulator_extern.c >>>>>>>> +@@ -249,7 +249,7 @@ int (*tpm_read_from_storage)(uint8_t **data, >>>>>>>> size_t *data_length) = _tpm_read_fr >>>>>>>> #else /* TPM_NO_EXTERN */ >>>>>>>> - >>>>>>>> + >>>>>>>> int (*tpm_extern_init)(void) >>>>>>>> = NULL; >>>>>>>> -int (*tpm_extern_release)(void) >>>>>>>> = NULL; >>>>>>>> +void (*tpm_extern_release)(void) >>>>>>>> = NULL; >>>>>>>> diff --git a/stubdom/vtpm/vtpm.c b/stubdom/vtpm/vtpm.c >>>>>>>> index c33e078..dcfc3b9 100644 >>>>>>>> --- a/stubdom/vtpm/vtpm.c >>>>>>>> +++ b/stubdom/vtpm/vtpm.c >>>>>>>> @@ -141,8 +141,6 @@ int check_ordinal(tpmcmd_t* tpmcmd) { >>>>>>>> static void main_loop(void) { >>>>>>>> tpmcmd_t* tpmcmd = NULL; >>>>>>>> - domid_t domid; /* Domid of frontend */ >>>>>>>> - unsigned int handle; /* handle of frontend */ >>>>>>>> int res = -1; >>>>>>>> info("VTPM Initializing\n"); >>>>>>>> @@ -162,15 +160,7 @@ static void main_loop(void) { >>>>>>>> goto abort_postpcrs; >>>>>>>> } >>>>>>>> - /* Wait for the frontend domain to connect */ >>>>>>>> - info("Waiting for frontend domain to connect.."); >>>>>>>> - if(tpmback_wait_for_frontend_connect(&domid, &handle) == 0) { >>>>>>>> - info("VTPM attached to Frontend %u/%u", (unsigned int) domid, >>>>>>>> handle); >>>>>>>> - } else { >>>>>>>> - error("Unable to attach to a frontend"); >>>>>>>> - } >>>>>>>> - >>>>>>>> - tpmcmd = tpmback_req(domid, handle); >>>>>>>> + tpmcmd = tpmback_req_any(); >>>>>>>> while(tpmcmd) { >>>>>>>> /* Handle the request */ >>>>>>>> if(tpmcmd->req_len) { >>>>>>>> @@ -183,7 +173,7 @@ static void main_loop(void) { >>>>>>>> } >>>>>>>> /* If not disabled, do the command */ >>>>>>>> else { >>>>>>>> - if((res = tpm_handle_command(tpmcmd->req, >>>>>>>> tpmcmd->req_len, &tpmcmd->resp, &tpmcmd->resp_len)) != 0) { >>>>>>>> + if((res = tpm_handle_command(tpmcmd->req, >>>>>>>> tpmcmd->req_len, &tpmcmd->resp, &tpmcmd->resp_len, tpmcmd->locality)) >>>>>>>> != 0) { >>>>>>>> error("tpm_handle_command() failed"); >>>>>>>> create_error_response(tpmcmd, TPM_FAIL); >>>>>>>> } >>>>>>>> @@ -194,7 +184,7 @@ static void main_loop(void) { >>>>>>>> tpmback_resp(tpmcmd); >>>>>>>> /* Wait for the next request */ >>>>>>>> - tpmcmd = tpmback_req(domid, handle); >>>>>>>> + tpmcmd = tpmback_req_any(); >>>>>>>> } >>>>>>> Before the vtpm would shut down on its own when the host domain >>>>>>> disconnects. This occurs because tpmback_req() returns NULL if the >>>>>>> frontend disconnected. Using tpmback_req_any(), this is no longer the >>>>>>> case which now means the user has to shut down the vtpm manually. How >>>>>>> are you handling vtpm shutdown on your end? >>>>>> When a domain shuts down, "xl destroy" is called on its paired vTPM (by >>>>>> some >>>>>> scripting that may need to be incorporated into libxl). A graceful >>>>>> shutdown >>>>>> is not really needed at this point, although it might be needed in the >>>>>> short >>>>>> term if the save-state operation is not atomic - but a method of >>>>>> recovering >>>>>> from this type of failure is needed for vTPMs anyway. >>>>> This is kind of a difficult problem. The save state operation is not by >>>>> any means atomic and it is very possible that the guest shuts down and xl >>>>> destroy is called before the save operation completes. This is especially >>>>> true if the guest is an embedded or even a mini-os domain using tpmfront >>>>> that shuts down very quickly. Its the reason why now the vtpm shuts >>>>> itself down after the guest disconnects. >>>>> >>>>> What is really needed is a way to do an xl shutdown on mini-os domains to >>>>> let vtpm-stubdom shutdown correctly. From what I understand there is not >>>>> yet any support for this in mini-os. How tricky would it be to add that? >>>>> Samuel any ideas? >>>>> >>>>> If thats not possible, another potential hack could be writing a key in >>>>> xenstore to trigger the shutdown or setting up some other kind of event >>>>> channel mechanism between the vtpm domain and libxl. >>>>> >>>> I have approached this problem from the opposite direction, while looking >>>> at >>>> adding protection from vTPM state rollback. The method that I am currently >>>> considering is to have two "slots" in the vTPM disk image - one active and >>>> and one inactive. The save process would then consist of writing a new save >>>> state to the inactive slot, ensuring it has been committed to disk, and >>>> then >>>> requesting the TPM Manager atomically update the state encryption key to >>>> the >>>> new value. When loading, the key obtained from the TPM manager will only be >>>> able to decrypt one of the two state images; the successful one is the >>>> active >>>> image. Since the vTPM's saved state is not expected to be very large, this >>>> doesn't waste a significant amount of disk space. >>>> >>> I like that idea in general, but it still doesn't solve the shutdown race >>> condition. You might not get a corrupted disk but you can still get >>> inadvertently rolled back. Adding a xenstore watch as samuel suggested and >>> doing a clean shutdown would be ideal. >> If you run the save before you send back the TPM response, you won't have >> any >> races - if a domain dies without getting a TPM response, the it's valid for >> the command to not have completed. The TPM emulator does execute the save >> prior to returning the result packet, so this race is already avoided. >> >> That's not to say that handling shutdowns properly is useless, of course; >> other >> minios domains may need it, and a graceful shutdown is easier to clean up >> after >> if not all peers of the vTPM are shutting down at the same time. > Ok I follow you now. Do you already have patches to do the disk mirroring and > destroy the vtpm from libxl? I think we will want to include this so these > new features don't break the automatic vtpm shutdown model already in place. > No, I haven't implemented either of those yet. The destroy that I'm using is not based on libxl (it assumes both the vtpm and client domain are being created by a dedicated domain-builder domain, and so don't have a libxl watcher process). -- Daniel De Graaf National Security Agency _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |