From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A811ACDB46F for ; Mon, 22 Jun 2026 16:31:57 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wbhY5-0008Js-Rq; Mon, 22 Jun 2026 12:31:01 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wbhXt-0008Ih-9R for qemu-devel@nongnu.org; Mon, 22 Jun 2026 12:30:52 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wbhXq-0008H2-U7 for qemu-devel@nongnu.org; Mon, 22 Jun 2026 12:30:48 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1782145845; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:in-reply-to:in-reply-to: references:references; bh=3kVgqQPmq4tHaNGmJrSGC++oq5/w/E5qQrdkmQIWwaY=; b=jRjn3xkW3X1+0lozkhyR3HbGd58FTTzxr08j6I0Ee0Km1X67ufzEkao0fbVjVvnICgqYFb KNO58Qh2UFtQjFmMj2HgVqeUKN7tZpCDj0fJ6vCfsXWmPsnQ88ysZr69ye5gLIF+29Nh+k YzHtid10nmnVWOldnOvOlgPgv8idDEM= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-479-qo5B9eDKNFaiwWzGtJjfLg-1; Mon, 22 Jun 2026 12:30:41 -0400 X-MC-Unique: qo5B9eDKNFaiwWzGtJjfLg-1 X-Mimecast-MFC-AGG-ID: qo5B9eDKNFaiwWzGtJjfLg_1782145840 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 8593E1955EA0; Mon, 22 Jun 2026 16:30:40 +0000 (UTC) Received: from redhat.com (unknown [10.44.32.91]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id ACB2C180029C; Mon, 22 Jun 2026 16:30:36 +0000 (UTC) Date: Mon, 22 Jun 2026 17:30:33 +0100 From: Daniel =?utf-8?B?UC4gQmVycmFuZ8Op?= To: Laurent Vivier Cc: qemu-devel@nongnu.org, "Michael S. Tsirkin" , Mauro Matteo Cascella , Paolo Bonzini , Amit Shah , =?utf-8?Q?Marc-Andr=C3=A9?= Lureau , qemu-stable@nongnu.org Subject: Re: [PATCH] hw/char/virtio-serial-bus: fix guest-triggerable OOM in control_out() Message-ID: References: <20260622161144.2883799-1-lvivier@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <20260622161144.2883799-1-lvivier@redhat.com> User-Agent: Mutt/2.3.2 (2026-04-26) X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 Received-SPF: pass client-ip=170.10.129.124; envelope-from=berrange@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: 8 X-Spam_score: 0.8 X-Spam_bar: / X-Spam_report: (0.8 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.445, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_SBL_CSS=3.335, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=no autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Daniel =?utf-8?B?UC4gQmVycmFuZ8Op?= Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org On Mon, Jun 22, 2026 at 06:11:44PM +0200, Laurent Vivier wrote: > A malicious guest can craft virtqueue descriptors with arbitrary lengths. > control_out() calls iov_size() on the guest-supplied scatter-gather list > and passes the result directly to g_malloc(), allowing a guest to force > QEMU to attempt multi-gigabyte allocations and crash the host process. > > Fix this by copying at most sizeof(struct virtio_console_control) into a > stack-local variable instead of allocating a buffer sized by the guest. > handle_control_message() only accesses the fixed-size id, event, and > value fields, so no data beyond the struct was ever needed. Does anyone have thoughts on whether we should treat guest initiated unbounded allocs as a security issue ? IIUC, this flaw would require root in the guest OS in order to craft the malicious virtqueue descriptors. A self-initiated crash triggered by root would not historically be enough justification for CVE. We would require it to be triggered by unprivileged user. Nested virt with device assignment could change that equation though as the L2 guest could be considered an unpriv user from the L1 POV. Also in theory the large alloc might be large enough to consume all host RAM but not large enough to trigger OOM kill of QEMU. This might impact operation of other co-located VMs on the same host. Anyone think this is bad enough to justify a CVE ? Or should we treat these OOM scenarios maerely as "hardening" bugs, where they require 'root' in the L1 guest ? > Cc: qemu-stable@nongnu.org > Resolves: https://gitlab.com/qemu-project/qemu/-/issues/3585 > Signed-off-by: Laurent Vivier > --- > hw/char/virtio-serial-bus.c | 34 +++++++--------------------------- > 1 file changed, 7 insertions(+), 27 deletions(-) > > diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c > index cd234dc6db1d..c1973f0248fc 100644 > --- a/hw/char/virtio-serial-bus.c > +++ b/hw/char/virtio-serial-bus.c > @@ -344,22 +344,16 @@ void virtio_serial_throttle_port(VirtIOSerialPort *port, bool throttle) > } > > /* Guest wants to notify us of some event */ > -static void handle_control_message(VirtIOSerial *vser, void *buf, size_t len) > +static void handle_control_message(VirtIOSerial *vser, > + struct virtio_console_control *gcpkt) > { > VirtIODevice *vdev = VIRTIO_DEVICE(vser); > struct VirtIOSerialPort *port; > VirtIOSerialPortClass *vsc; > - struct virtio_console_control cpkt, *gcpkt; > + struct virtio_console_control cpkt; > uint8_t *buffer; > size_t buffer_len; > > - gcpkt = buf; > - > - if (len < sizeof(cpkt)) { > - /* The guest sent an invalid control packet */ > - return; > - } > - > cpkt.event = virtio_lduw_p(vdev, &gcpkt->event); > cpkt.value = virtio_lduw_p(vdev, &gcpkt->value); > > @@ -457,41 +451,27 @@ static void control_in(VirtIODevice *vdev, VirtQueue *vq) > > static void control_out(VirtIODevice *vdev, VirtQueue *vq) > { > + struct virtio_console_control cpkt; > VirtQueueElement *elem; > VirtIOSerial *vser; > - uint8_t *buf; > size_t len; > > vser = VIRTIO_SERIAL(vdev); > > - len = 0; > - buf = NULL; > for (;;) { > - size_t cur_len; > - > elem = virtqueue_pop(vq, sizeof(VirtQueueElement)); > if (!elem) { > break; > } > > - cur_len = iov_size(elem->out_sg, elem->out_num); > - /* > - * Allocate a new buf only if we didn't have one previously or > - * if the size of the buf differs > - */ > - if (cur_len > len) { > - g_free(buf); > - > - buf = g_malloc(cur_len); > - len = cur_len; > + len = iov_to_buf(elem->out_sg, elem->out_num, 0, &cpkt, sizeof(cpkt)); > + if (len == sizeof(cpkt)) { > + handle_control_message(vser, &cpkt); > } > - iov_to_buf(elem->out_sg, elem->out_num, 0, buf, cur_len); > > - handle_control_message(vser, buf, cur_len); > virtqueue_push(vq, elem, 0); > g_free(elem); > } > - g_free(buf); > virtio_notify(vdev, vq); > } > > -- > 2.54.0 > > With regards, Daniel -- |: https://berrange.com ~~ https://hachyderm.io/@berrange :| |: https://libvirt.org ~~ https://entangle-photo.org :| |: https://pixelfed.art/berrange ~~ https://fstop138.berrange.com :|