diff mbox series

fdc: check null block pointer before blk_pwrite

Message ID 20200827113806.1850687-1-ppandit@redhat.com
State New
Headers show
Series fdc: check null block pointer before blk_pwrite | expand

Commit Message

Prasad Pandit Aug. 27, 2020, 11:38 a.m. UTC
From: Prasad J Pandit <pjp@fedoraproject.org>

While transferring data via fdctrl_write_data(), check that
current drive does not have a null block pointer. Avoid
null pointer dereference.

 -> https://ruhr-uni-bochum.sciebo.de/s/NNWP2GfwzYKeKwE?path=%2Ffdc_nullptr1
    ==1658854==Hint: address points to the zero page.
    #0 blk_inc_in_flight block/block-backend.c:1327
    #1 blk_prw block/block-backend.c:1299
    #2 blk_pwrite block/block-backend.c:1464
    #3 fdctrl_write_data hw/block/fdc.c:2418
    #4 fdctrl_write hw/block/fdc.c:962
    #5 portio_write ioport.c:205
    #6 memory_region_write_accessor memory.c:483
    #7 access_with_adjusted_size memory.c:544
    #8 memory_region_dispatch_write memory.c:1476

Reported-by: Ruhr-University <bugs-syssec@rub.de>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
---
 hw/block/fdc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

Comments

Prasad Pandit Sept. 15, 2020, 12:47 p.m. UTC | #1
+-- On Thu, 27 Aug 2020, P J P wrote --+
| While transferring data via fdctrl_write_data(), check that
| current drive does not have a null block pointer. Avoid
| null pointer dereference.
| 
|  -> https://ruhr-uni-bochum.sciebo.de/s/NNWP2GfwzYKeKwE?path=%2Ffdc_nullptr1
|     ==1658854==Hint: address points to the zero page.
|     #0 blk_inc_in_flight block/block-backend.c:1327
|     #1 blk_prw block/block-backend.c:1299
|     #2 blk_pwrite block/block-backend.c:1464
|     #3 fdctrl_write_data hw/block/fdc.c:2418
|     #4 fdctrl_write hw/block/fdc.c:962
|     #5 portio_write ioport.c:205
|     #6 memory_region_write_accessor memory.c:483
|     #7 access_with_adjusted_size memory.c:544
|     #8 memory_region_dispatch_write memory.c:1476
| 
| Reported-by: Ruhr-University <bugs-syssec@rub.de>
| Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
| ---
|  hw/block/fdc.c | 3 ++-
|  1 file changed, 2 insertions(+), 1 deletion(-)
| 
| diff --git a/hw/block/fdc.c b/hw/block/fdc.c
| index e9ed3eef45..dedadac68a 100644
| --- a/hw/block/fdc.c
| +++ b/hw/block/fdc.c
| @@ -2419,7 +2419,8 @@ static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value)
|          if (pos == FD_SECTOR_LEN - 1 ||
|              fdctrl->data_pos == fdctrl->data_len) {
|              cur_drv = get_cur_drv(fdctrl);
| -            if (blk_pwrite(cur_drv->blk, fd_offset(cur_drv), fdctrl->fifo,
| +            if (cur_drv->blk
| +                && blk_pwrite(cur_drv->blk, fd_offset(cur_drv), fdctrl->fifo,
|                             BDRV_SECTOR_SIZE, 0) < 0) {
|                  FLOPPY_DPRINTF("error writing sector %d\n",
|                                 fd_sector(cur_drv));
| 

Ping...!
--
Prasad J Pandit / Red Hat Product Security Team
8685 545E B54C 486B C6EB 271E E285 8B5A F050 DE8D
Li Qiang Sept. 18, 2020, 10:52 a.m. UTC | #2
P J P <ppandit@redhat.com> 于2020年8月27日周四 下午7:41写道:
>

> From: Prasad J Pandit <pjp@fedoraproject.org>

>

> While transferring data via fdctrl_write_data(), check that

> current drive does not have a null block pointer. Avoid

> null pointer dereference.

>

>  -> https://ruhr-uni-bochum.sciebo.de/s/NNWP2GfwzYKeKwE?path=%2Ffdc_nullptr1

>     ==1658854==Hint: address points to the zero page.

>     #0 blk_inc_in_flight block/block-backend.c:1327

>     #1 blk_prw block/block-backend.c:1299

>     #2 blk_pwrite block/block-backend.c:1464

>     #3 fdctrl_write_data hw/block/fdc.c:2418

>     #4 fdctrl_write hw/block/fdc.c:962

>     #5 portio_write ioport.c:205

>     #6 memory_region_write_accessor memory.c:483

>     #7 access_with_adjusted_size memory.c:544

>     #8 memory_region_dispatch_write memory.c:1476

>

> Reported-by: Ruhr-University <bugs-syssec@rub.de>

> Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>

> ---

>  hw/block/fdc.c | 3 ++-

>  1 file changed, 2 insertions(+), 1 deletion(-)

>

> diff --git a/hw/block/fdc.c b/hw/block/fdc.c

> index e9ed3eef45..dedadac68a 100644

> --- a/hw/block/fdc.c

> +++ b/hw/block/fdc.c

> @@ -2419,7 +2419,8 @@ static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value)

>          if (pos == FD_SECTOR_LEN - 1 ||

>              fdctrl->data_pos == fdctrl->data_len) {

>              cur_drv = get_cur_drv(fdctrl);

> -            if (blk_pwrite(cur_drv->blk, fd_offset(cur_drv), fdctrl->fifo,

> +            if (cur_drv->blk

> +                && blk_pwrite(cur_drv->blk, fd_offset(cur_drv), fdctrl->fifo,

>                             BDRV_SECTOR_SIZE, 0) < 0) {

>                  FLOPPY_DPRINTF("error writing sector %d\n",

>                                 fd_sector(cur_drv));

> --


Hello Prasad,

There are several pattern to address this NULL check in fdc.c.
I think it is better to consider this as an error. Just like the check
in 'fdctrl_format_sector':

if (cur_drv->blk == NULL ||
    blk_pwrite(cur_drv->blk, fd_offset(cur_drv), fdctrl->fifo,
    BDRV_SECTOR_SIZE, 0) < 0) {
    FLOPPY_DPRINTF("error formatting sector %d\n", fd_sector(cur_drv));
    fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM | FD_SR0_SEEK, 0x00, 0x00);
} else {

Also there seems exists the same issue in  'fdctrl_read_data'

Thanks,
Li Qiang

> 2.26.2

>

>
Markus Armbruster March 19, 2021, 5:53 a.m. UTC | #3
Alexander Bulekov <alxndr@bu.edu> writes:

> dd if=/dev/zero of=/tmp/fda.img bs=1024 count=1440

> cat << EOF | ./qemu-system-i386 -nographic -m 512M -nodefaults \

> -accel qtest -fda /tmp/fda.img -qtest stdio

> outw 0x3f4 0x0500

> outb 0x3f5 0x00

> outb 0x3f5 0x00

> outw 0x3f4 0x00

> outb 0x3f5 0x00

> outw 0x3f1 0x0400

> outw 0x3f4 0x0

> outw 0x3f4 0x00

> outb 0x3f5 0x0

> outb 0x3f5 0x01

> outw 0x3f1 0x0500

> outb 0x3f5 0x00

> EOF

>

> Signed-off-by: Alexander Bulekov <alxndr@bu.edu>


I guess this is a reproducer.  Please also describe actual and expected
result.  Same for PATCH 2.
Paolo Bonzini March 19, 2021, 9:26 a.m. UTC | #4
On 19/03/21 06:53, Markus Armbruster wrote:
> I guess this is a reproducer.  Please also describe actual and expected

> result.  Same for PATCH 2.


Isn't it in the patch itself?

Alexander, I think these reproducers are self-contained enough (no 
writes to PCI configuration space to set up the device) that we can 
place them in fdc-test.c.

Paolo
Markus Armbruster March 19, 2021, 9:54 a.m. UTC | #5
Paolo Bonzini <pbonzini@redhat.com> writes:

> On 19/03/21 06:53, Markus Armbruster wrote:

>> I guess this is a reproducer.  Please also describe actual and expected

>> result.  Same for PATCH 2.

>

> Isn't it in the patch itself?


A commit message should tell me what the patch is trying to accomplish.

This commit message's title tells me it's a test for a CVE.  Okay.  The
body additionally gives me the reproducer.  To be useful, a reproducer
needs to come with actual and expected result.  Yes, I can find those in
the patch.  But I could find the reproducer there, too.  If you're nice
enough to save me the trouble of digging through the patch for the
reproducer (thanks), please consider saving me the trouble digging for
the information I need to make use of it (thanks again).  That's all :)

[...]
Paolo Bonzini March 19, 2021, 10:17 a.m. UTC | #6
On 19/03/21 10:54, Markus Armbruster wrote:
> A commit message should tell me what the patch is trying to accomplish.

> 

> This commit message's title tells me it's a test for a CVE.  Okay.  The

> body additionally gives me the reproducer.  To be useful, a reproducer

> needs to come with actual and expected result.  Yes, I can find those in

> the patch.  But I could find the reproducer there, too.  If you're nice

> enough to save me the trouble of digging through the patch for the

> reproducer (thanks), please consider saving me the trouble digging for

> the information I need to make use of it (thanks again).  That's all:)


FWIW I don't think in this case there is an expected result other than 
not crashing, but yeah it may be worth adding in the commit message "for 
CVE-2020-25741, a {crash,undefined behavior,ASAN violation} in func_name".

Paolo
Alexander Bulekov March 19, 2021, 2:51 p.m. UTC | #7
On 210319 1054, Markus Armbruster wrote:
> Paolo Bonzini <pbonzini@redhat.com> writes:

> 

> > On 19/03/21 06:53, Markus Armbruster wrote:

> >> I guess this is a reproducer.  Please also describe actual and expected

> >> result.  Same for PATCH 2.

> >

> > Isn't it in the patch itself?

> 

> A commit message should tell me what the patch is trying to accomplish.

> 

> This commit message's title tells me it's a test for a CVE.  Okay.  The

> body additionally gives me the reproducer.  To be useful, a reproducer

> needs to come with actual and expected result.  Yes, I can find those in

> the patch.  But I could find the reproducer there, too.  If you're nice

> enough to save me the trouble of digging through the patch for the

> reproducer (thanks), please consider saving me the trouble digging for

> the information I need to make use of it (thanks again).  That's all :)

> 

> [...]

> 


Ok sounds good. I posted this in-reply-to patch [1] from August 2020,
which had a stacktrace, and I hoped that would provide enough context.
However, that depends on the email-viewer and I see how that context
would be lost if/once these reproducer patches are applied.

[1] https://lore.kernel.org/qemu-devel/20200827113806.1850687-1-ppandit@redhat.com/

(https://lists.nongnu.org/archive doesn't display this discussion
as a child of that message)
Alexander Bulekov March 19, 2021, 2:52 p.m. UTC | #8
On 210319 1026, Paolo Bonzini wrote:
> On 19/03/21 06:53, Markus Armbruster wrote:

> > I guess this is a reproducer.  Please also describe actual and expected

> > result.  Same for PATCH 2.

> 

> Isn't it in the patch itself?

> 

> Alexander, I think these reproducers are self-contained enough (no writes to

> PCI configuration space to set up the device) that we can place them in

> fdc-test.c.

> 


Will do
-Alex

> Paolo

>
John Snow May 18, 2021, 5:30 p.m. UTC | #9
On 8/27/20 7:38 AM, P J P wrote:
> From: Prasad J Pandit <pjp@fedoraproject.org>

> 

> While transferring data via fdctrl_write_data(), check that

> current drive does not have a null block pointer. Avoid

> null pointer dereference.

> 


Hi PJP. I assume this patch actually covers the exact same thing that 
the other if cur_drv->blk patch we have been discussing recently does.

You may want to combine the Reported-By lines for both.

I am dropping this patch from my queue in favor of pursuing our other, 
more recent and active thread, which I am also now tracking via this 
gitlab issue:

https://gitlab.com/qemu-project/qemu/-/issues/338

>   -> https://ruhr-uni-bochum.sciebo.de/s/NNWP2GfwzYKeKwE?path=%2Ffdc_nullptr1

>      ==1658854==Hint: address points to the zero page.

>      #0 blk_inc_in_flight block/block-backend.c:1327

>      #1 blk_prw block/block-backend.c:1299

>      #2 blk_pwrite block/block-backend.c:1464

>      #3 fdctrl_write_data hw/block/fdc.c:2418

>      #4 fdctrl_write hw/block/fdc.c:962

>      #5 portio_write ioport.c:205

>      #6 memory_region_write_accessor memory.c:483

>      #7 access_with_adjusted_size memory.c:544

>      #8 memory_region_dispatch_write memory.c:1476

> 

> Reported-by: Ruhr-University <bugs-syssec@rub.de>

> Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>

> ---

>   hw/block/fdc.c | 3 ++-

>   1 file changed, 2 insertions(+), 1 deletion(-)

> 

> diff --git a/hw/block/fdc.c b/hw/block/fdc.c

> index e9ed3eef45..dedadac68a 100644

> --- a/hw/block/fdc.c

> +++ b/hw/block/fdc.c

> @@ -2419,7 +2419,8 @@ static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value)

>           if (pos == FD_SECTOR_LEN - 1 ||

>               fdctrl->data_pos == fdctrl->data_len) {

>               cur_drv = get_cur_drv(fdctrl);

> -            if (blk_pwrite(cur_drv->blk, fd_offset(cur_drv), fdctrl->fifo,

> +            if (cur_drv->blk

> +                && blk_pwrite(cur_drv->blk, fd_offset(cur_drv), fdctrl->fifo,

>                              BDRV_SECTOR_SIZE, 0) < 0) {

>                   FLOPPY_DPRINTF("error writing sector %d\n",

>                                  fd_sector(cur_drv));

>
diff mbox series

Patch

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index e9ed3eef45..dedadac68a 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -2419,7 +2419,8 @@  static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value)
         if (pos == FD_SECTOR_LEN - 1 ||
             fdctrl->data_pos == fdctrl->data_len) {
             cur_drv = get_cur_drv(fdctrl);
-            if (blk_pwrite(cur_drv->blk, fd_offset(cur_drv), fdctrl->fifo,
+            if (cur_drv->blk
+                && blk_pwrite(cur_drv->blk, fd_offset(cur_drv), fdctrl->fifo,
                            BDRV_SECTOR_SIZE, 0) < 0) {
                 FLOPPY_DPRINTF("error writing sector %d\n",
                                fd_sector(cur_drv));