]> xenbits.xensource.com Git - people/aperard/xtf.git/commitdiff
xenbus: fix xenbus_write() ring overflow
authorPawel Wieczorkiewicz <wipawel@amazon.de>
Wed, 3 Jun 2020 08:21:41 +0000 (08:21 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 3 Jun 2020 20:57:17 +0000 (21:57 +0100)
Currently the xenbus_write() does not handle ring wrapping around
correctly. When ring buffer is almost full and there is not enough
space for next packet (e.g. there is 12 bytes of space left, but the
packet header needs to transmit 16 bytes) the memcpy() goes out of the
ring buffer boundry.
Instead, the part variable should be limited to the space available in
the ring buffer, so the memcpy() can fill up the buffer, update len
variable (to indicate that there is still some data to be copied) and
thereby the xenbus_write() loop can iterate again to finish copying
the remainder of data to the beginning of the ring buffer.

Signed-off-by: Pawel Wieczorkiewicz <wipawel@amazon.de>
Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>
common/xenbus.c

index 59159f29b7eb0208929b7e7ab24799b33ff324b9..24fff48723728fafb1cca26860727b3a748ea455 100644 (file)
@@ -31,9 +31,7 @@ static void xenbus_write(const void *data, size_t len)
         uint32_t prod = ACCESS_ONCE(xb_ring->req_prod);
         uint32_t cons = ACCESS_ONCE(xb_ring->req_cons);
 
-        uint32_t used = mask_xenbus_idx(prod - cons);
-
-        part = (XENBUS_RING_SIZE - 1) - used;
+        part = (XENBUS_RING_SIZE - 1) - mask_xenbus_idx(prod - cons);
 
         /* No space?  Kick xenstored and wait for it to consume some data. */
         if ( !part )
@@ -47,7 +45,7 @@ static void xenbus_write(const void *data, size_t len)
         }
 
         /* Don't overrun the ring. */
-        part = min(part, XENBUS_RING_SIZE - used);
+        part = min(part, XENBUS_RING_SIZE - mask_xenbus_idx(prod));
 
         /* Don't write more than necessary. */
         part = min(part, (unsigned int)len);