Michael S. Tsirkin
2023-Jan-20 12:59 UTC
[PATCH v1 2/6] virtio console: Harden port adding
On Thu, Jan 19, 2023 at 03:57:17PM +0200, Alexander Shishkin wrote:> From: Andi Kleen <ak at linux.intel.com> > > The ADD_PORT operation reads and sanity checks the port id multiple > times from the untrusted host. This is not safe because a malicious > host could change it between reads. > > Read the port id only once and cache it for subsequent uses. > > Signed-off-by: Andi Kleen <ak at linux.intel.com> > Signed-off-by: Alexander Shishkin <alexander.shishkin at linux.intel.com> > Cc: Amit Shah <amit at kernel.org> > Cc: Arnd Bergmann <arnd at arndb.de> > Cc: Greg Kroah-Hartman <gregkh at linuxfoundation.org>I suspect anyone worried about this kind of thing already uses a bounce buffer. No? The patch itself makes the code more readable, except maybe for the READ_ONCE thing.> --- > drivers/char/virtio_console.c | 10 ++++++---- > 1 file changed, 6 insertions(+), 4 deletions(-) > > diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c > index f4fd5fe7cd3a..6599c2956ba4 100644 > --- a/drivers/char/virtio_console.c > +++ b/drivers/char/virtio_console.c > @@ -1563,10 +1563,13 @@ static void handle_control_message(struct virtio_device *vdev, > struct port *port; > size_t name_size; > int err; > + unsigned id; > > cpkt = (struct virtio_console_control *)(buf->buf + buf->offset); > > - port = find_port_by_id(portdev, virtio32_to_cpu(vdev, cpkt->id)); > + /* Make sure the host cannot change id under us */ > + id = virtio32_to_cpu(vdev, READ_ONCE(cpkt->id)); > + port = find_port_by_id(portdev, id); > if (!port && > cpkt->event != cpu_to_virtio16(vdev, VIRTIO_CONSOLE_PORT_ADD)) { > /* No valid header at start of buffer. Drop it. */ > @@ -1583,15 +1586,14 @@ 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) >> - portdev->max_nr_ports) { > + if (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); > break; > } > - add_port(portdev, virtio32_to_cpu(vdev, cpkt->id)); > + add_port(portdev, id); > break; > case VIRTIO_CONSOLE_PORT_REMOVE: > unplug_port(port); > -- > 2.39.0