]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
USB: serial: digi_acceleport: fix memory corruption with small endpoints
authorJohan Hovold <johan@kernel.org>
Wed, 20 May 2026 14:26:22 +0000 (16:26 +0200)
committerJohan Hovold <johan@kernel.org>
Wed, 20 May 2026 14:26:22 +0000 (16:26 +0200)
Add the missing bulk-out buffer size sanity checks to avoid
out-of-bounds memory accesses or slab corruption should a malicious
device report smaller buffers than expected.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Johan Hovold <johan@kernel.org>
drivers/usb/serial/digi_acceleport.c

index d515df045c4c82ab5a95179e0873baa739e8289d..c481208255ebe6d1bfea3524d51e84f0b285f00a 100644 (file)
@@ -1229,15 +1229,34 @@ static int digi_port_init(struct usb_serial_port *port, unsigned port_num)
 static int digi_startup(struct usb_serial *serial)
 {
        struct digi_serial *serial_priv;
+       int oob_port_num;
        int ret;
+       int i;
+
+       /*
+        * The port bulk-out buffers must be large enough for header and
+        * buffered data.
+        */
+       for (i = 0; i < serial->type->num_ports; i++) {
+               if (serial->port[i]->bulk_out_size < DIGI_OUT_BUF_SIZE + 2)
+                       return -EINVAL;
+       }
+
+       /*
+        * The OOB port bulk-out buffer must be large enough for the two
+        * commands in digi_set_modem_signals().
+        */
+       oob_port_num = serial->type->num_ports;
+       if (serial->port[oob_port_num]->bulk_out_size < 8)
+               return -EINVAL;
 
        serial_priv = kzalloc_obj(*serial_priv);
        if (!serial_priv)
                return -ENOMEM;
 
        spin_lock_init(&serial_priv->ds_serial_lock);
-       serial_priv->ds_oob_port_num = serial->type->num_ports;
-       serial_priv->ds_oob_port = serial->port[serial_priv->ds_oob_port_num];
+       serial_priv->ds_oob_port_num = oob_port_num;
+       serial_priv->ds_oob_port = serial->port[oob_port_num];
 
        ret = digi_port_init(serial_priv->ds_oob_port,
                                                serial_priv->ds_oob_port_num);