All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: P J P <ppandit@redhat.com>, John Snow <jsnow@redhat.com>
Cc: Wenxiang Qian <leonwxqian@gmail.com>,
	QEMU Developers <qemu-devel@nongnu.org>
Subject: Re: [PATCH] ide:atapi: check io_buffer_index in ide_atapi_cmd_reply_end
Date: Tue, 1 Dec 2020 12:51:09 +0100	[thread overview]
Message-ID: <492170b8-8056-bd65-5150-62c6e89cb3f0@redhat.com> (raw)
In-Reply-To: <204751s9-11np-413q-q3pr-3o6os86078@erqung.pbz>

On 27/11/20 14:57, P J P wrote:
> +-- On Wed, 18 Nov 2020, P J P wrote --+
> | During data transfer via packet command in 'ide_atapi_cmd_reply_end'
> | 's->io_buffer_index' could exceed the 's->io_buffer' length, leading
> | to OOB access issue. Add check to avoid it.
> |  ...
> |  #9  ahci_pio_transfer ../hw/ide/ahci.c:1383
> |  #10 ide_transfer_start_norecurse ../hw/ide/core.c:553
> |  #11 ide_atapi_cmd_reply_end ../hw/ide/atapi.c:284
> |  #12 ide_atapi_cmd_read_pio ../hw/ide/atapi.c:329
> |  #13 ide_atapi_cmd_read ../hw/ide/atapi.c:442
> |  #14 cmd_read ../hw/ide/atapi.c:988
> |  #15 ide_atapi_cmd ../hw/ide/atapi.c:1352
> |  #16 ide_transfer_start ../hw/ide/core.c:561
> |  #17 cmd_packet ../hw/ide/core.c:1729
> |  #18 ide_exec_cmd ../hw/ide/core.c:2107
> |  #19 handle_reg_h2d_fis ../hw/ide/ahci.c:1267
> |  #20 handle_cmd ../hw/ide/ahci.c:1318
> |  #21 check_cmd ../hw/ide/ahci.c:592
> |  #22 ahci_port_write ../hw/ide/ahci.c:373
> |  #23 ahci_mem_write ../hw/ide/ahci.c:513
> |
> | Reported-by: Wenxiang Qian <leonwxqian@gmail.com>
> | Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>

Prasad, please try to put yourself in the reviewer's shoes.

1) Obviously this condition was not in the mind of whoever wrote the 
code.  For this reason the first thing to understand if how the bug came 
to happen, which precondition was not respected.  Your backtraces shows 
that you came from ide_atapi_cmd_read_pio, so:

- ide_atapi_cmd_reply_end is first entered with s->io_buffer_index == 
s->cd_sector_size

- s->lba is assumed to be != -1.  from there you go to cd_read_sector -> 
cd_read_sector_cb and then reenter ide_atapi_cmd_reply_end with 
s->io_buffer_index == 0.  Or to cd_read_sector_sync and then continue 
down ide_atapi_cmd_reply_end, again with s->io_buffer_index == 0

- if s->elementary_transfer_size > 0, the number of bytes that are read 
is bounded to s->cd_sector_size - s->io_buffer_index

- if s->elementary_transfer_size == 0, the size is again bounded to 
s->cd_sector_size - s->io_buffer_index in this code:

             /* we cannot transmit more than one sector at a time */
             if (s->lba != -1) {
                 if (size > (s->cd_sector_size - s->io_buffer_index))
                     size = (s->cd_sector_size - s->io_buffer_index);
             }

So my understanding is that, for the bug to happen, you need to enter 
ide_atapi_cmd_reply_end with s->lba == -1 despite being in the read CD 
path.  This might be possible by passing 0xFFFFFFFF as the LBA in 
cmd_read.  The correct fix would be to check lba against the media size 
in cmd_read.

This is reasoning that you should understand even before starting to 
write a patch.  Did you do this step?  If so, no problem---I still 
believe the patch is incorrect, but please explain how my reasoning is 
wrong and we'll take it from there.  If not, how do you know your patch 
is not papering over a bigger issue somewhere?


2) The maintainer is not the one that knows the code best: it's only 
someone who is trusted to make judgment calls that are good enough.  My 
job is to poke holes in your reasoning, not to reverse engineer it.  So 
if you did do step 1, you need to explain it to me, because at this 
point you know this part of the code better than I do.  This is a step 
that you did not do, because your commit message has no such explanation.

There's also another reason to do this: recording the details of the bug 
in the commit message helps anyone who wants to understand the story of 
the code.


3) We also need to ensure that the bug will not happen again.  Did you 
get a reproducer from the reporter?  If not, how did you trust the 
report to be correct?  If so, did you try to include it in the QEMU 
qtest testsuite?


If my understanding of the bug is correct, the patch is not the correct 
fix.  The correct fix is to add an assertion here *and* to fix the 
incorrect assumption up in the call chain.  For example:

- add an assertion in ide_atapi_cmd_read_{dma,pio} that s->lba <= 
s->nb_sectors && s->lba != -1

- add a range check in cmd_read and cmd_read_cd similar to what is 
already done in cmd_seek (but checking the full range from lba to 
lba+nb_sectors-1.


Even if the patch were correct, however, bullets (2) and (3) are two 
reasons why this patch is not acceptable for QEMU's standards---not even 
for a security fix.

This is nothing new.  Even though I have sometimes applied (or redone_ 
your fixes, I have told you a variation of the above every time I saw a 
a patch of yours.  The output of "git log --author pjp tests" tells me 
you didn't heed the advice though; I'm calling you out this time because 
it's especially clear that you didn't do these steps and because the 
result is especially wrong.

Thanks,

Paolo



  reply	other threads:[~2020-12-01 11:53 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-11-18 14:27 [PATCH] ide:atapi: check io_buffer_index in ide_atapi_cmd_reply_end P J P
2020-11-27 13:57 ` P J P
2020-12-01 11:51   ` Paolo Bonzini [this message]
2020-12-01 15:00     ` P J P
2020-12-01 15:23       ` Philippe Mathieu-Daudé
2020-12-01 15:30         ` Peter Maydell
2020-12-01 15:42           ` Paolo Bonzini
2020-12-01 15:30         ` Paolo Bonzini
2020-12-01 15:30       ` Paolo Bonzini
2020-12-02  7:07         ` Markus Armbruster
2020-12-02 13:17           ` P J P
2020-12-02 13:33             ` Paolo Bonzini
2020-12-02 13:36             ` Philippe Mathieu-Daudé
2020-12-03  9:48               ` P J P
2020-12-11  8:23             ` Wenxiang Qian
2020-12-11  8:32               ` Wenxiang Qian
2020-12-11 11:46                 ` Paolo Bonzini
2020-12-11 11:45               ` Paolo Bonzini
2020-12-11 14:16                 ` P J P

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=492170b8-8056-bd65-5150-62c6e89cb3f0@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=jsnow@redhat.com \
    --cc=leonwxqian@gmail.com \
    --cc=ppandit@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.