From: Stefan Berger <stefanb@linux.vnet.ibm.com>
To: Marc-Andre Lureau <mlureau@redhat.com>
Cc: "Marc-André Lureau" <marcandre.lureau@redhat.com>,
qemu-devel <qemu-devel@nongnu.org>
Subject: Re: [Qemu-devel] [PATCH] tpm: fix alignment issues
Date: Mon, 29 Jan 2018 13:16:23 -0500 [thread overview]
Message-ID: <ca564791-87f2-c832-adab-e5809101aff5@linux.vnet.ibm.com> (raw)
In-Reply-To: <CAMxuvax+v+VN5M_hQZb+mPWJKhV8c+WJZVLfKC3cZdXmwxH7yw@mail.gmail.com>
On 01/29/2018 01:02 PM, Marc-Andre Lureau wrote:
> Hi
>
> On Mon, Jan 29, 2018 at 6:57 PM, Stefan Berger
> <stefanb@linux.vnet.ibm.com> wrote:
>> On 01/29/2018 12:51 PM, Marc-Andre Lureau wrote:
>>> Hi
>>>
>>> On Mon, Jan 29, 2018 at 6:41 PM, Stefan Berger
>>> <stefanb@linux.vnet.ibm.com> wrote:
>>>> On 01/29/2018 07:32 AM, Marc-André Lureau wrote:
>>>>> The new tpm-crb-test fails on sparc host:
>>>>>
>>>>> TEST: tests/tpm-crb-test... (pid=230409)
>>>>> /i386/tpm-crb/test:
>>>>> Broken pipe
>>>>> FAIL
>>>>> GTester: last random seed: R02S29cea50247fe1efa59ee885a26d51a85
>>>>> (pid=230423)
>>>>> FAIL: tests/tpm-crb-test
>>>>>
>>>>> and generates a new clang sanitizer runtime warning:
>>>>>
>>>>> /home/petmay01/linaro/qemu-for-merges/hw/tpm/tpm_util.h:36:24: runtime
>>>>> error: load of misaligned address 0x7fdc24c00002 for type 'const
>>>>> uint32_t' (aka 'const unsigned int'), which requires 4 byte alignment
>>>>> 0x7fdc24c00002: note: pointer points here
>>>>> <memory cannot be printed>
>>>>>
>>>>> The sparc architecture does not allow misaligned loads and will
>>>>> segfault if you try them. For example, this function:
>>>>>
>>>>> static inline uint32_t tpm_cmd_get_size(const void *b)
>>>>> {
>>>>> return be32_to_cpu(*(const uint32_t *)(b + 2));
>>>>> }
>>>>>
>>>>> Should read,
>>>>> return ldl_be_p(b + 2);
>>>>>
>>>>> As a general rule you can't take an arbitrary pointer into a byte
>>>>> buffer and try to interpret it as a structure or a pointer to a
>>>>> larger-than-bytesize-data simply by casting the pointer.
>>>>>
>>>>> Use this clean up as an opportunity to remove unnecessary temporary
>>>>> buffers and casts.
>>>>>
>>>>> Reported-by: Peter Maydell <peter.maydell@linaro.org>
>>>>> Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
>>>>> ---
>>>>> hw/tpm/tpm_util.h | 17 ++++++++++-
>>>>> hw/tpm/tpm_emulator.c | 14 ++++-----
>>>>> hw/tpm/tpm_passthrough.c | 6 ++--
>>>>> hw/tpm/tpm_util.c | 75
>>>>> ++++++++++++++++++++++--------------------------
>>>>> 4 files changed, 58 insertions(+), 54 deletions(-)
>>>>>
>>>>> diff --git a/hw/tpm/tpm_util.h b/hw/tpm/tpm_util.h
>>>>> index 19b28474ae..c562140e52 100644
>>>>> --- a/hw/tpm/tpm_util.h
>>>>> +++ b/hw/tpm/tpm_util.h
>>>>> @@ -31,9 +31,24 @@ bool tpm_util_is_selftest(const uint8_t *in, uint32_t
>>>>> in_len);
>>>>>
>>>>> int tpm_util_test_tpmdev(int tpm_fd, TPMVersion *tpm_version);
>>>>>
>>>>> +static inline uint16_t tpm_cmd_get_tag(const void *b)
>>>>> +{
>>>>> + return lduw_be_p(b);;
>>>>> +}
>>>>> +
>>>>> static inline uint32_t tpm_cmd_get_size(const void *b)
>>>>> {
>>>>> - return be32_to_cpu(*(const uint32_t *)(b + 2));
>>>>> + return ldl_be_p(b + 2);;
>>>>
>>>> Why are there these two ';;' ?
>>>>
>>> obvious typo (repeated..)
>>>
>>>>> +}
>>>>> +
>>>>> +static inline uint32_t tpm_cmd_get_ordinal(const void *b)
>>>>> +{
>>>>> + return ldl_be_p(b + 6);;
>>>>> +}
>>>>> +
>>>>> +static inline uint32_t tpm_cmd_get_errcode(const void *b)
>>>>> +{
>>>>> + return ldl_be_p(b + 6);;
>>>>> }
>>>>>
>>>>> int tpm_util_get_buffer_size(int tpm_fd, TPMVersion tpm_version,
>>>>> diff --git a/hw/tpm/tpm_emulator.c b/hw/tpm/tpm_emulator.c
>>>>> index 35c78de5a9..a34a18ac7a 100644
>>>>> --- a/hw/tpm/tpm_emulator.c
>>>>> +++ b/hw/tpm/tpm_emulator.c
>>>>> @@ -120,7 +120,6 @@ static int tpm_emulator_unix_tx_bufs(TPMEmulator
>>>>> *tpm_emu,
>>>>> {
>>>>> ssize_t ret;
>>>>> bool is_selftest = false;
>>>>> - const struct tpm_resp_hdr *hdr = NULL;
>>>>>
>>>>> if (selftest_done) {
>>>>> *selftest_done = false;
>>>>> @@ -132,22 +131,21 @@ static int tpm_emulator_unix_tx_bufs(TPMEmulator
>>>>> *tpm_emu,
>>>>> return -1;
>>>>> }
>>>>>
>>>>> - ret = qio_channel_read_all(tpm_emu->data_ioc, (char *)out,
>>>>> sizeof(*hdr),
>>>>> - err);
>>>>> + ret = qio_channel_read_all(tpm_emu->data_ioc, (char *)out,
>>>>> + sizeof(struct tpm_resp_hdr), err);
>>>>> if (ret != 0) {
>>>>> return -1;
>>>>> }
>>>>>
>>>>> - hdr = (struct tpm_resp_hdr *)out;
>>>>> - out += sizeof(*hdr);
>>>>> - ret = qio_channel_read_all(tpm_emu->data_ioc, (char *)out,
>>>>> - be32_to_cpu(hdr->len) - sizeof(*hdr) ,
>>>>> err);
>>>>> + ret = qio_channel_read_all(tpm_emu->data_ioc,
>>>>> + (char *)out + sizeof(struct tpm_resp_hdr),
>>>>> + tpm_cmd_get_size(out) - sizeof(struct tpm_resp_hdr),
>>>>> err);
>>>>> if (ret != 0) {
>>>>> return -1;
>>>>> }
>>>>>
>>>>> if (is_selftest) {
>>>>> - *selftest_done = (be32_to_cpu(hdr->errcode) == 0);
>>>>> + *selftest_done = tpm_cmd_get_errcode(out) == 0;
>>>>> }
>>>>>
>>>>> return 0;
>>>>> diff --git a/hw/tpm/tpm_passthrough.c b/hw/tpm/tpm_passthrough.c
>>>>> index 29142f38bb..537e11a3f9 100644
>>>>> --- a/hw/tpm/tpm_passthrough.c
>>>>> +++ b/hw/tpm/tpm_passthrough.c
>>>>> @@ -87,7 +87,6 @@ static int
>>>>> tpm_passthrough_unix_tx_bufs(TPMPassthruState
>>>>> *tpm_pt,
>>>>> {
>>>>> ssize_t ret;
>>>>> bool is_selftest;
>>>>> - const struct tpm_resp_hdr *hdr;
>>>>>
>>>>> /* FIXME: protect shared variables or use other sync mechanism */
>>>>> tpm_pt->tpm_op_canceled = false;
>>>>> @@ -116,15 +115,14 @@ static int
>>>>> tpm_passthrough_unix_tx_bufs(TPMPassthruState *tpm_pt,
>>>>> strerror(errno), errno);
>>>>> }
>>>>> } else if (ret < sizeof(struct tpm_resp_hdr) ||
>>>>> - be32_to_cpu(((struct tpm_resp_hdr *)out)->len) != ret) {
>>>>> + tpm_cmd_get_size(out) != ret) {
>>>>> ret = -1;
>>>>> error_report("tpm_passthrough: received invalid response "
>>>>> "packet from TPM");
>>>>> }
>>>>>
>>>>> if (is_selftest && (ret >= sizeof(struct tpm_resp_hdr))) {
>>>>> - hdr = (struct tpm_resp_hdr *)out;
>>>>> - *selftest_done = (be32_to_cpu(hdr->errcode) == 0);
>>>>> + *selftest_done = tpm_cmd_get_errcode(out) == 0;
>>>>> }
>>>>>
>>>>> err_exit:
>>>>> diff --git a/hw/tpm/tpm_util.c b/hw/tpm/tpm_util.c
>>>>> index 747075e244..8abde59915 100644
>>>>> --- a/hw/tpm/tpm_util.c
>>>>> +++ b/hw/tpm/tpm_util.c
>>>>> @@ -106,20 +106,16 @@ const PropertyInfo qdev_prop_tpm = {
>>>>> void tpm_util_write_fatal_error_response(uint8_t *out, uint32_t
>>>>> out_len)
>>>>> {
>>>>> if (out_len >= sizeof(struct tpm_resp_hdr)) {
>>>>> - struct tpm_resp_hdr *resp = (struct tpm_resp_hdr *)out;
>>>>> -
>>>>> - resp->tag = cpu_to_be16(TPM_TAG_RSP_COMMAND);
>>>>> - resp->len = cpu_to_be32(sizeof(struct tpm_resp_hdr));
>>>>> - resp->errcode = cpu_to_be32(TPM_FAIL);
>>>>> + stw_be_p(out, TPM_TAG_RSP_COMMAND);
>>>>> + stl_be_p(out + 2, sizeof(struct tpm_resp_hdr));
>>>>> + stl_be_p(out + 6, TPM_FAIL);
>>>>
>>>> Since we wrapped the getters we should wrap the setters as well.
>>>> tpm_cmd_set_len(), tpm_cmd_set_errcode.
>>> They were not as widely used (there was only a getter so far), but
>>> that makes sense too. Could be done on top.
>>
>> Also please rebase on top of your series of patches. I had some problems
>> with tpm_passthrough.c around line 115. Error reporting there has changed.
>>
>>
> The patch is meant to be applied first on top of master, to avoid
> intermediary regressions (it passes patchew:
> http://patchew.org/QEMU/20180129123227.15778-1-marcandre.lureau@redhat.com/)
>
> There was no conflicts after a rebase of my series. If it helps, I can
> resend my pending tpm queue.
>
Please resent the series.
Stefan
prev parent reply other threads:[~2018-01-29 18:16 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-01-29 12:32 [Qemu-devel] [PATCH] tpm: fix alignment issues Marc-André Lureau
2018-01-29 17:41 ` Stefan Berger
2018-01-29 17:51 ` Marc-Andre Lureau
2018-01-29 17:57 ` Stefan Berger
2018-01-29 18:02 ` Marc-Andre Lureau
2018-01-29 18:16 ` Stefan Berger [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ca564791-87f2-c832-adab-e5809101aff5@linux.vnet.ibm.com \
--to=stefanb@linux.vnet.ibm.com \
--cc=marcandre.lureau@redhat.com \
--cc=mlureau@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).