virtio_console: fix missing byte order handling for cols and rows
authorHalil Pasic <pasic@linux.ibm.com>
Sat, 22 Mar 2025 00:29:54 +0000 (01:29 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 2 May 2025 05:59:05 +0000 (07:59 +0200)
commit fbd3039a64b01b769040677c4fc68badeca8e3b2 upstream.

As per virtio spec the fields cols and rows are specified as little
endian. Although there is no legacy interface requirement that would
state that cols and rows need to be handled as native endian when legacy
interface is used, unlike for the fields of the adjacent struct
virtio_console_control, I decided to err on the side of caution based
on some non-conclusive virtio spec repo archaeology and opt for using
virtio16_to_cpu() much like for virtio_console_control.event. Strictly
by the letter of the spec virtio_le_to_cpu() would have been sufficient.
But when the legacy interface is not used, it boils down to the same.

And when using the legacy interface, the device formatting these as
little endian when the guest is big endian would surprise me more than
it using guest native byte order (which would make it compatible with
the current implementation). Nevertheless somebody trying to implement
the spec following it to the letter could end up forcing little endian
byte order when the legacy interface is in use. So IMHO this ultimately
needs a judgement call by the maintainers.

Fixes: 8345adbf96fc1 ("virtio: console: Accept console size along with resize control message")
Signed-off-by: Halil Pasic <pasic@linux.ibm.com>
Cc: stable@vger.kernel.org # v2.6.35+
Message-Id: <20250322002954.3129282-1-pasic@linux.ibm.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/char/virtio_console.c

index c62b208b42f13187dfdaf2afc8ead9407c6f36c6..abcfdd3c2918357c06a3d7d641dcff2aa70c3f91 100644 (file)
@@ -1579,8 +1579,8 @@ static void handle_control_message(struct virtio_device *vdev,
                break;
        case VIRTIO_CONSOLE_RESIZE: {
                struct {
-                       __u16 rows;
-                       __u16 cols;
+                       __virtio16 rows;
+                       __virtio16 cols;
                } size;
 
                if (!is_console_port(port))
@@ -1588,7 +1588,8 @@ static void handle_control_message(struct virtio_device *vdev,
 
                memcpy(&size, buf->buf + buf->offset + sizeof(*cpkt),
                       sizeof(size));
-               set_console_size(port, size.rows, size.cols);
+               set_console_size(port, virtio16_to_cpu(vdev, size.rows),
+                                virtio16_to_cpu(vdev, size.cols));
 
                port->cons.hvc->irq_requested = 1;
                resize_console(port);