qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v2 2/2] net: Update MemReentrancyGuard for NIC


From: Alexander Bulekov
Subject: Re: [PATCH v2 2/2] net: Update MemReentrancyGuard for NIC
Date: Mon, 5 Jun 2023 04:04:40 -0400

On 230601 1218, Akihiko Odaki wrote:
> Recently MemReentrancyGuard was added to DeviceState to record that the
> device is engaging in I/O. The network device backend needs to update it
> when delivering a packet to a device.
> 
> This implementation follows what bottom half does, but it does not add
> a tracepoint for the case that the network device backend started
> delivering a packet to a device which is already engaging in I/O. This
> is because such reentrancy frequently happens for
> qemu_flush_queued_packets() and is insignificant.
> 
> Fixes: CVE-2023-3019
> Reported-by: Alexander Bulekov <alxndr@bu.edu>
> Signed-off-by: Akihiko Odaki <akihiko.odaki@daynix.com>

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

> ---
>  include/net/net.h |  1 +
>  net/net.c         | 14 ++++++++++++++
>  2 files changed, 15 insertions(+)
> 
> diff --git a/include/net/net.h b/include/net/net.h
> index a7d8deaccb..685ec58318 100644
> --- a/include/net/net.h
> +++ b/include/net/net.h
> @@ -124,6 +124,7 @@ typedef QTAILQ_HEAD(NetClientStateList, NetClientState) 
> NetClientStateList;
>  typedef struct NICState {
>      NetClientState *ncs;
>      NICConf *conf;
> +    MemReentrancyGuard *reentrancy_guard;
>      void *opaque;
>      bool peer_deleted;
>  } NICState;
> diff --git a/net/net.c b/net/net.c
> index 982df2479f..3523cceafc 100644
> --- a/net/net.c
> +++ b/net/net.c
> @@ -332,6 +332,7 @@ NICState *qemu_new_nic(NetClientInfo *info,
>      nic = g_malloc0(info->size + sizeof(NetClientState) * queues);
>      nic->ncs = (void *)nic + info->size;
>      nic->conf = conf;
> +    nic->reentrancy_guard = reentrancy_guard,
>      nic->opaque = opaque;
>  
>      for (i = 0; i < queues; i++) {
> @@ -805,6 +806,7 @@ static ssize_t qemu_deliver_packet_iov(NetClientState 
> *sender,
>                                         int iovcnt,
>                                         void *opaque)
>  {
> +    MemReentrancyGuard *owned_reentrancy_guard;
>      NetClientState *nc = opaque;
>      int ret;
>  
> @@ -817,12 +819,24 @@ static ssize_t qemu_deliver_packet_iov(NetClientState 
> *sender,
>          return 0;
>      }
>  
> +    if (nc->info->type != NET_CLIENT_DRIVER_NIC ||
> +        qemu_get_nic(nc)->reentrancy_guard->engaged_in_io) {
> +        owned_reentrancy_guard = NULL;
> +    } else {
> +        owned_reentrancy_guard = qemu_get_nic(nc)->reentrancy_guard;
> +        owned_reentrancy_guard->engaged_in_io = true;
> +    }
> +
>      if (nc->info->receive_iov && !(flags & QEMU_NET_PACKET_FLAG_RAW)) {
>          ret = nc->info->receive_iov(nc, iov, iovcnt);
>      } else {
>          ret = nc_sendv_compat(nc, iov, iovcnt, flags);
>      }
>  
> +    if (owned_reentrancy_guard) {
> +        owned_reentrancy_guard->engaged_in_io = false;
> +    }
> +
>      if (ret == 0) {
>          nc->receive_disabled = 1;
>      }
> -- 
> 2.40.1
> 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]