All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH for v2.4.1] exec: fix a glitch in checking dma r/w access
@ 2016-01-25 14:29 P J P
  2016-01-25 14:37 ` Paolo Bonzini
  0 siblings, 1 reply; 5+ messages in thread
From: P J P @ 2016-01-25 14:29 UTC (permalink / raw)
  To: QEMU Developers
  Cc: Peter Maydell, Paolo Bonzini, Prasad J Pandit, Donghai Zdh

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

While checking r/w access in 'memory_access_is_direct' routine
a glitch in the expression leads to segmentation fault while
performing dma read operation.

Reported-by: Donghai Zdh <donghai.zdh@alibaba-inc.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
---
 exec.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/exec.c b/exec.c
index 0a4a0c5..98d97d3 100644
--- a/exec.c
+++ b/exec.c
@@ -375,7 +375,7 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
 static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
 {
     if (memory_region_is_ram(mr)) {
-        return !(is_write && mr->readonly);
+        return (is_write && !mr->readonly);
     }
     if (memory_region_is_romd(mr)) {
         return !is_write;
-- 
2.5.0

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] [PATCH for v2.4.1] exec: fix a glitch in checking dma r/w access
  2016-01-25 14:29 [Qemu-devel] [PATCH for v2.4.1] exec: fix a glitch in checking dma r/w access P J P
@ 2016-01-25 14:37 ` Paolo Bonzini
  2016-01-25 18:19   ` P J P
  0 siblings, 1 reply; 5+ messages in thread
From: Paolo Bonzini @ 2016-01-25 14:37 UTC (permalink / raw)
  To: P J P, QEMU Developers; +Cc: Donghai Zdh, Prasad J Pandit, Peter Maydell



On 25/01/2016 15:29, P J P wrote:
> diff --git a/exec.c b/exec.c
> index 0a4a0c5..98d97d3 100644
> --- a/exec.c
> +++ b/exec.c
> @@ -375,7 +375,7 @@ address_space_translate_internal(AddressSpaceDispatch *d, hwaddr addr, hwaddr *x
>  static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
>  {
>      if (memory_region_is_ram(mr)) {
> -        return !(is_write && mr->readonly);
> +        return (is_write && !mr->readonly);

Putting the various cases in a table:

Read or write?		Readonly?		Old		New
   Read			    Yes			 T		 F
   Read			    No			 T		 F
   Write		    Yes			 F		 F
   Write		    No			 T		 T

This patch changes behavior for reads (is_write=false).  For
address_space_read, this makes them go through a path that is at least
100 times slower (memory_region_dispatch_read instead of just a memcpy).
 For address_space_map, it probably breaks everything that expects a
single block of RAM to be mapped in a single step, for example virtio.

So, how was this tested, and how can the bug be triggered?

Paolo

>      }
>      if (memory_region_is_romd(mr)) {
>          return !is_write;
> 

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] [PATCH for v2.4.1] exec: fix a glitch in checking dma r/w access
  2016-01-25 14:37 ` Paolo Bonzini
@ 2016-01-25 18:19   ` P J P
  2016-01-25 22:15     ` Paolo Bonzini
  0 siblings, 1 reply; 5+ messages in thread
From: P J P @ 2016-01-25 18:19 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Donghai Zdh, QEMU Developers, Peter Maydell

+-- On Mon, 25 Jan 2016, Paolo Bonzini wrote --+
| >  static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
| >  {
| >      if (memory_region_is_ram(mr)) {
| > -        return !(is_write && mr->readonly);
| > +        return (is_write && !mr->readonly);
| 
| Read or write?	Readonly?		Old		New
|    Read	          Yes			 T		 F
|    Read		  No			 T		 F
|    Write		  Yes			 F		 F
|    Write		  No			 T		 T
| 
| This patch changes behavior for reads (is_write=false).  For
| address_space_read, this makes them go through a path that is at least
| 100 times slower (memory_region_dispatch_read instead of just a memcpy).
|  For address_space_map, it probably breaks everything that expects a
| single block of RAM to be mapped in a single step, for example virtio.
| 
| So, how was this tested, and how can the bug be triggered?

  The bug was triggered if 'addr' in 'read_dword()' is set by user(ex. 
0xffffffff). The MemoryRegion section(*mr) could point to host memory area, 
which is then copied by memcpy(2) call. This leads to the said issue. The 
patch was tested using gdb(1).

 read_dword
  -> pci_dma_read
   -> pci_dma_rw
    -> dma_memory_rw
     -> dma_memory_rw_relaxed
      -> address_space_rw
       -> memcpy

Thank you.
--
Prasad J Pandit / Red Hat Product Security
47AF CE69 3A90 54AA 9045 1053 DD13 3D32 FE5B 041F

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] [PATCH for v2.4.1] exec: fix a glitch in checking dma r/w access
  2016-01-25 18:19   ` P J P
@ 2016-01-25 22:15     ` Paolo Bonzini
  2016-01-27  9:38       ` P J P
  0 siblings, 1 reply; 5+ messages in thread
From: Paolo Bonzini @ 2016-01-25 22:15 UTC (permalink / raw)
  To: P J P; +Cc: Donghai Zdh, QEMU Developers, Peter Maydell



On 25/01/2016 19:19, P J P wrote:
> +-- On Mon, 25 Jan 2016, Paolo Bonzini wrote --+
> | >  static inline bool memory_access_is_direct(MemoryRegion *mr, bool is_write)
> | >  {
> | >      if (memory_region_is_ram(mr)) {
> | > -        return !(is_write && mr->readonly);
> | > +        return (is_write && !mr->readonly);
> | 
> | Read or write?	Readonly?		Old		New
> |    Read	          Yes			 T		 F
> |    Read		  No			 T		 F
> |    Write		  Yes			 F		 F
> |    Write		  No			 T		 T
> | 
> | This patch changes behavior for reads (is_write=false).  For
> | address_space_read, this makes them go through a path that is at least
> | 100 times slower (memory_region_dispatch_read instead of just a memcpy).
> |  For address_space_map, it probably breaks everything that expects a
> | single block of RAM to be mapped in a single step, for example virtio.
> | 
> | So, how was this tested, and how can the bug be triggered?
> 
>   The bug was triggered if 'addr' in 'read_dword()' is set by user(ex. 
> 0xffffffff). The MemoryRegion section(*mr) could point to host memory area, 
> which is then copied by memcpy(2) call.

This should be handled correctly by address_space_translate_internal:

    if (memory_region_is_ram(mr)) {
        diff = int128_sub(section->size, int128_make64(addr));
        *plen = int128_get64(int128_min(diff, int128_make64(*plen)));
    }

... then, on return from address_space_translate, l will be 1:

    e.g.  section->size = 0x100000000, addr = 0xffffffff;
          diff = 1;
          *plen = min(diff, *plen) = min(1, 4) = 1

> The patch was tested using gdb(1).

You also have to test that the patch doesn't break other code.  It's not
enough to test that it solves your problem.

Paolo
This bit hasn't changed since 2.4.1.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [Qemu-devel] [PATCH for v2.4.1] exec: fix a glitch in checking dma r/w access
  2016-01-25 22:15     ` Paolo Bonzini
@ 2016-01-27  9:38       ` P J P
  0 siblings, 0 replies; 5+ messages in thread
From: P J P @ 2016-01-27  9:38 UTC (permalink / raw)
  To: Paolo Bonzini; +Cc: Donghai Zdh, QEMU Developers, Peter Maydell

  Hello Paolo,

+-- On Mon, 25 Jan 2016, Paolo Bonzini wrote --+
| This should be handled correctly by address_space_translate_internal:
| 
|     if (memory_region_is_ram(mr)) {
|         diff = int128_sub(section->size, int128_make64(addr));
|         *plen = int128_get64(int128_min(diff, int128_make64(*plen)));
|     }
| 
| ... then, on return from address_space_translate, l will be 1:
| 
|     e.g.  section->size = 0x100000000, addr = 0xffffffff;
|           diff = 1;
|           *plen = min(diff, *plen) = min(1, 4) = 1

  I see. Sorry, I think the issue affects versions <= v2.3.1 and not v2.4.x. 
v2.3.x series seems to be missing this patch

  -> http://git.qemu.org/?p=qemu.git;a=commit;h=23820dbfc79d1c9dce090b4c555994f2bb6a69b3

which avoids setting '*plen' to its earlier value. I'll send it to the -stable 
list.

| You also have to test that the patch doesn't break other code.  It's not
| enough to test that it solves your problem.

  Right, I'll run the tests/* going forward.

Thank you.
--
Prasad J Pandit / Red Hat Product Security Team
47AF CE69 3A90 54AA 9045 1053 DD13 3D32 FE5B 041F

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2016-01-27  9:38 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-01-25 14:29 [Qemu-devel] [PATCH for v2.4.1] exec: fix a glitch in checking dma r/w access P J P
2016-01-25 14:37 ` Paolo Bonzini
2016-01-25 18:19   ` P J P
2016-01-25 22:15     ` Paolo Bonzini
2016-01-27  9:38       ` P J P

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.