Hello Shahriyar,

> +                     void *buf, size_t buf_size, size_t prop_count);
>
>  /**
>   * tpm2_get_pcr_info() - get the supported, active PCRs and number of banks
> diff --git a/lib/efi_loader/efi_tcg2.c b/lib/efi_loader/efi_tcg2.c
> index 5f9bbe97455..e15a2340e83 100644
> --- a/lib/efi_loader/efi_tcg2.c
> +++ b/lib/efi_loader/efi_tcg2.c
> @@ -154,7 +154,8 @@ static int tpm2_get_max_command_size(struct udevice *dev, 
> u16 *max_command_size)
>
>       memset(response, 0, sizeof(response));
>       ret = tpm2_get_capability(dev, TPM2_CAP_TPM_PROPERTIES,
> -                               TPM2_PT_MAX_COMMAND_SIZE, response, 1);
> +                               TPM2_PT_MAX_COMMAND_SIZE, response,
> +                               sizeof(response), 1);
>       if (ret)
>               return -1;
>
> @@ -180,7 +181,8 @@ static int tpm2_get_max_response_size(struct udevice *dev,
>
>       memset(response, 0, sizeof(response));
>       ret = tpm2_get_capability(dev, TPM2_CAP_TPM_PROPERTIES,
> -                               TPM2_PT_MAX_RESPONSE_SIZE, response, 1);
> +                               TPM2_PT_MAX_RESPONSE_SIZE, response,
> +                               sizeof(response), 1);
>       if (ret)
>               return -1;
>
> @@ -205,7 +207,8 @@ static int tpm2_get_manufacturer_id(struct udevice *dev, 
> u32 *manufacturer_id)
>
>       memset(response, 0, sizeof(response));
>       ret = tpm2_get_capability(dev, TPM2_CAP_TPM_PROPERTIES,
> -                               TPM2_PT_MANUFACTURER, response, 1);
> +                               TPM2_PT_MANUFACTURER, response,
> +                               sizeof(response), 1);
>       if (ret)
>               return -1;
>
> diff --git a/lib/tpm-common.c b/lib/tpm-common.c
> index b592c22bfc1..e4a620990fa 100644
> --- a/lib/tpm-common.c
> +++ b/lib/tpm-common.c
> @@ -159,7 +159,8 @@ u32 tpm_return_code(const void *response)
>  }
>
>  u32 tpm_sendrecv_command(struct udevice *dev, const void *command,
> -                      void *response, size_t *size_ptr)
> +                      void *response, size_t *size_ptr,
> +                      size_t min_response_len)
>  {
>       int err, ret;
>       u8 response_buffer[COMMAND_BUFFER_SIZE];
> @@ -190,11 +191,20 @@ u32 tpm_sendrecv_command(struct udevice *dev, const 
> void *command,
>       if (err < 0)
>               return err;
>
> +     ret = tpm_return_code(response);
> +
> +     /*
> +      * The response length is reported by the (untrusted) TPM. Reject a
> +      * successful reply too short to hold what the caller will parse, so it
> +      * cannot read past the end of a truncated response. A TPM error reply
> +      * is a bare header with no body; let its return code reach the caller.
> +      */
> +     if (!ret && size_ptr && response_length < min_response_len)
> +             return TPM_LIB_ERROR;

The documentation you added says that min_response_len of 0 is ignored. But 
here we seem to rely
only on size_ptr != NULL.

> -     ret = tpm_return_code(response);
> -
>       log_debug("TPM response [ret:%d]: ", ret);
>       for (i = 0; i < response_length; i++)
>               log_debug("%02x ", ((u8 *)response)[i]);

[...]

> @@ -519,6 +522,11 @@ u32 tpm2_get_capability(struct udevice *dev, u32 
> capability, u32 property,
>        */
>       properties_off = sizeof(u16) + sizeof(u32) + sizeof(u32) +
>                        sizeof(u8) + sizeof(u32);
> +
> +     /* the reply length is set by the TPM; do not overrun the caller's buf 
> */
> +     if (response_len - properties_off > buf_size)
> +             return TPM_LIB_ERROR;
> +

Isn't that covered by tpm_sendrecv_command() now?


>       memcpy(buf, &response[properties_off], response_len - properties_off);
>
>       return 0;

[...]

Thanks
/Ilias

Reply via email to