Received: by 2002:a05:6358:a55:b0:ec:fcf4:3ecf with SMTP id 21csp1591704rwb; Thu, 19 Jan 2023 12:44:02 -0800 (PST) X-Google-Smtp-Source: AMrXdXuM3ins7lbEIXTY47C88vUI5+sscox/o/+CuutMQy+7WH9AjLYQ1nkkxnHEhWbhex6BDN1e X-Received: by 2002:aa7:9182:0:b0:58d:987b:2e9 with SMTP id x2-20020aa79182000000b0058d987b02e9mr11536570pfa.24.1674161041914; Thu, 19 Jan 2023 12:44:01 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1674161041; cv=none; d=google.com; s=arc-20160816; b=rLATlCuiOJr0KI7oe6BSPb8gKleS++saGljTPP2aQDCMid1E6DUpcy0N3Enk5NOk5L ieibYQ/5jA4xkH00f2QImS4Mn2Bq38viv4+D4yUUZZuKgilTtl5m3y3WBUef9xmXSw7a /jBPXHBkkL2a/5d0p5FKo7k2wvX5Xq8KWgdhORNLN63sY5gMisabO9EcFpjHst09Lesg KPTcurfHSRZIVCCCvAUe04cP5kzuFhbAF+UBIo/DzexS1+YkKslHnO9ywJLVAYvaQ1Y/ k/ahQcvhqmvdxIkzfqkQvh7cWCfLGWYEbu3YbsjWEUvEocwvgD6XOux3aFETyKziuDVe WUqw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:mime-version:message-id:date:references :in-reply-to:subject:cc:to:from:dkim-signature; bh=AYrXqXYKgmLDe47Af+Yma/AJls0lBxCfrah9mwRE65Q=; b=TtjU4+p+SH8VFUHgP9SOEk99x5MtL4vDl/gkPIZYeDK5uoCX83MVJVhZmYm1eS92Nc vod8Zuh/F5pUPQvfrghIRK0jessCDAMEgJIW2G8Pn+k81of/xKBu8ze03Ft38L88IT+M RNPuSUubDjqbQXz8FhcDZ0+qin9ESr60D1buPpFojbNv8JMmGfy1tXvZ6XKXHW9wSywT ybqURdZASu91DI+H94sCcO3c/kY+l8h6q3dsBGM6xcV+NdN7/VlhHv9/BPPiunv4PnGh MKVNGmsknsdJ6vBku/ydT1fgG+XehamMihLic8PA2C/0MHAMzLgXoykJQkjcr9M92mcz zLJg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=KrIEvrAF; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id ay29-20020a056a00301d00b0058dd544fab0si7660918pfb.101.2023.01.19.12.43.56; Thu, 19 Jan 2023 12:44:01 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@intel.com header.s=Intel header.b=KrIEvrAF; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=intel.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230163AbjASUN3 (ORCPT + 46 others); Thu, 19 Jan 2023 15:13:29 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35066 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230090AbjASUNY (ORCPT ); Thu, 19 Jan 2023 15:13:24 -0500 Received: from mga03.intel.com (mga03.intel.com [134.134.136.65]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8E5329519D for ; Thu, 19 Jan 2023 12:13:23 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1674159203; x=1705695203; h=from:to:cc:subject:in-reply-to:references:date: message-id:mime-version; bh=+3Q0D0Jugsvb2TexainnB5PwnLYuzF2qzDGI8ulotJU=; b=KrIEvrAF+/WtPvwaKsM5ZLaoYQr/VwuYTCgohuT1UwhnGQ8/jUP09RTC UrXJFcyzMb3IvtDKQJbUtL6cQ+M1PC7riyh/0jfbCFmGsazt98xZD18+L bNeHSNuehXOEcJSZtO84gebKgkbOac4GBz7O5etHiXq1Erh1/gb2RVxTD oaephQfWgHt2ctdJ6ERKnwVYqTCgYZ6d8PBaTpsoWut8uZliMKcnkdpOt 69GSwwZaIodbZXyMHZMFxy3+tZ8d96hhAnWmxuBJTnz0Pd0WT/HNI3kmi PSK0VWcLJUsNZIqD+pUhhOococj7wR1VnRQ28Z0xZnG3j8EaF6B9Dn4A9 w==; X-IronPort-AV: E=McAfee;i="6500,9779,10595"; a="327502034" X-IronPort-AV: E=Sophos;i="5.97,229,1669104000"; d="scan'208";a="327502034" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 19 Jan 2023 12:13:22 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6500,9779,10595"; a="637845790" X-IronPort-AV: E=Sophos;i="5.97,229,1669104000"; d="scan'208";a="637845790" Received: from ubik.fi.intel.com (HELO localhost) ([10.237.72.184]) by orsmga006.jf.intel.com with ESMTP; 19 Jan 2023 12:13:19 -0800 From: Alexander Shishkin To: Greg Kroah-Hartman Cc: mst@redhat.com, jasowang@redhat.com, virtualization@lists.linux-foundation.org, linux-kernel@vger.kernel.org, elena.reshetova@intel.com, kirill.shutemov@linux.intel.com, Andi Kleen , Amit Shah , Arnd Bergmann , alexander.shishkin@linux.intel.com Subject: Re: [PATCH v1 2/6] virtio console: Harden port adding In-Reply-To: References: <20230119135721.83345-1-alexander.shishkin@linux.intel.com> <20230119135721.83345-3-alexander.shishkin@linux.intel.com> <87ilh2quto.fsf@ubik.fi.intel.com> Date: Thu, 19 Jan 2023 22:13:18 +0200 Message-ID: <87a62eqo4h.fsf@ubik.fi.intel.com> MIME-Version: 1.0 Content-Type: text/plain X-Spam-Status: No, score=-4.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_EF,RCVD_IN_DNSWL_MED,SPF_HELO_NONE, SPF_NONE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Greg Kroah-Hartman writes: > Then you need to copy it out once, and then only deal with the local > copy. Otherwise you have an incomplete snapshot. Ok, would you be partial to something like this: From 1bc9bb84004154376c2a0cf643d53257da6d1cd7 Mon Sep 17 00:00:00 2001 From: Alexander Shishkin Date: Thu, 19 Jan 2023 21:59:02 +0200 Subject: [PATCH] virtio console: Keep a local copy of the control structure When handling control messages, instead of peeking at the device memory to obtain bits of the control structure, take a snapshot of it once and use it instead, to prevent it from changing under us. This avoids races between port id validation and control event decoding, which can lead to, for example, a NULL dereference in port removal of a nonexistent port. The control structure is small enough (8 bytes) that it can be cached directly on the stack. Signed-off-by: Alexander Shishkin Cc: Greg Kroah-Hartman Cc: Arnd Bergmann Cc: Amit Shah --- drivers/char/virtio_console.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index 6a821118d553..42be0991a72f 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -1559,23 +1559,24 @@ static void handle_control_message(struct virtio_device *vdev, struct ports_device *portdev, struct port_buffer *buf) { - struct virtio_console_control *cpkt; + struct virtio_console_control cpkt; struct port *port; size_t name_size; int err; - cpkt = (struct virtio_console_control *)(buf->buf + buf->offset); + /* Keep a local copy of the control structure */ + memcpy(&cpkt, buf->buf + buf->offset, sizeof(cpkt)); - port = find_port_by_id(portdev, virtio32_to_cpu(vdev, cpkt->id)); + port = find_port_by_id(portdev, virtio32_to_cpu(vdev, cpkt.id)); if (!port && - cpkt->event != cpu_to_virtio16(vdev, VIRTIO_CONSOLE_PORT_ADD)) { + cpkt.event != cpu_to_virtio16(vdev, VIRTIO_CONSOLE_PORT_ADD)) { /* No valid header at start of buffer. Drop it. */ dev_dbg(&portdev->vdev->dev, - "Invalid index %u in control packet\n", cpkt->id); + "Invalid index %u in control packet\n", cpkt.id); return; } - switch (virtio16_to_cpu(vdev, cpkt->event)) { + switch (virtio16_to_cpu(vdev, cpkt.event)) { case VIRTIO_CONSOLE_PORT_ADD: if (port) { dev_dbg(&portdev->vdev->dev, @@ -1583,21 +1584,21 @@ static void handle_control_message(struct virtio_device *vdev, send_control_msg(port, VIRTIO_CONSOLE_PORT_READY, 1); break; } - if (virtio32_to_cpu(vdev, cpkt->id) >= + if (virtio32_to_cpu(vdev, cpkt.id) >= portdev->max_nr_ports) { dev_warn(&portdev->vdev->dev, "Request for adding port with " "out-of-bound id %u, max. supported id: %u\n", - cpkt->id, portdev->max_nr_ports - 1); + cpkt.id, portdev->max_nr_ports - 1); break; } - add_port(portdev, virtio32_to_cpu(vdev, cpkt->id)); + add_port(portdev, virtio32_to_cpu(vdev, cpkt.id)); break; case VIRTIO_CONSOLE_PORT_REMOVE: unplug_port(port); break; case VIRTIO_CONSOLE_CONSOLE_PORT: - if (!cpkt->value) + if (!cpkt.value) break; if (is_console_port(port)) break; @@ -1618,7 +1619,7 @@ static void handle_control_message(struct virtio_device *vdev, if (!is_console_port(port)) break; - memcpy(&size, buf->buf + buf->offset + sizeof(*cpkt), + memcpy(&size, buf->buf + buf->offset + sizeof(cpkt), sizeof(size)); set_console_size(port, size.rows, size.cols); @@ -1627,7 +1628,7 @@ static void handle_control_message(struct virtio_device *vdev, break; } case VIRTIO_CONSOLE_PORT_OPEN: - port->host_connected = virtio16_to_cpu(vdev, cpkt->value); + port->host_connected = virtio16_to_cpu(vdev, cpkt.value); wake_up_interruptible(&port->waitqueue); /* * If the host port got closed and the host had any @@ -1658,7 +1659,7 @@ static void handle_control_message(struct virtio_device *vdev, * Skip the size of the header and the cpkt to get the size * of the name that was sent */ - name_size = buf->len - buf->offset - sizeof(*cpkt) + 1; + name_size = buf->len - buf->offset - sizeof(cpkt) + 1; port->name = kmalloc(name_size, GFP_KERNEL); if (!port->name) { @@ -1666,7 +1667,7 @@ static void handle_control_message(struct virtio_device *vdev, "Not enough space to store port name\n"); break; } - strncpy(port->name, buf->buf + buf->offset + sizeof(*cpkt), + strncpy(port->name, buf->buf + buf->offset + sizeof(cpkt), name_size - 1); port->name[name_size - 1] = 0; -- 2.39.0