From 3f72e519ed08ff8b647d4e18f4cd78b38a33d91e Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Fri, 12 Dec 2025 23:03:01 -0500 Subject: [PATCH] atsamd: Fix possible buffer overflow in usbserial.c The USB buffer size register PCKSIZE.SIZE was not being assigned correctly. As a result, it was possible for an incoming USB transmission to write past the allocated buffer space, which could corrupt memory of other storage. In particular, in some cases gcc may layout ram in such a way that the trailing bytes of an incoming message might overlap the buffer for an outgoing message. This could cause sporadic transmit errors and unstable connections. Fix by correctly configuring the PCKSIZE.SIZE register. Signed-off-by: Kevin O'Connor --- src/atsamd/usbserial.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/atsamd/usbserial.c b/src/atsamd/usbserial.c index 460de4645..d083beb86 100644 --- a/src/atsamd/usbserial.c +++ b/src/atsamd/usbserial.c @@ -25,27 +25,30 @@ static uint8_t __aligned(4) acmin[USB_CDC_EP_ACM_SIZE]; static uint8_t __aligned(4) bulkout[USB_CDC_EP_BULK_OUT_SIZE]; static uint8_t __aligned(4) bulkin[USB_CDC_EP_BULK_IN_SIZE]; +// Convert 64, 32, 16, 8 sized buffer to 3, 2, 1, 0 for PCKSIZE.SIZE register +#define BSIZE(bufname) (__builtin_ctz(sizeof(bufname)) - 3) + static UsbDeviceDescriptor usb_desc[] = { [0] = { { { .ADDR.reg = (uint32_t)ep0out, - .PCKSIZE.reg = USB_DEVICE_PCKSIZE_SIZE(sizeof(ep0out) >> 4), + .PCKSIZE.reg = USB_DEVICE_PCKSIZE_SIZE(BSIZE(ep0out)), }, { .ADDR.reg = (uint32_t)ep0in, - .PCKSIZE.reg = USB_DEVICE_PCKSIZE_SIZE(sizeof(ep0in) >> 4), + .PCKSIZE.reg = USB_DEVICE_PCKSIZE_SIZE(BSIZE(ep0in)), }, } }, [USB_CDC_EP_ACM] = { { { }, { .ADDR.reg = (uint32_t)acmin, - .PCKSIZE.reg = USB_DEVICE_PCKSIZE_SIZE(sizeof(acmin) >> 4), + .PCKSIZE.reg = USB_DEVICE_PCKSIZE_SIZE(BSIZE(acmin)), }, } }, [USB_CDC_EP_BULK_OUT] = { { { .ADDR.reg = (uint32_t)bulkout, - .PCKSIZE.reg = USB_DEVICE_PCKSIZE_SIZE(sizeof(bulkout) >> 4), + .PCKSIZE.reg = USB_DEVICE_PCKSIZE_SIZE(BSIZE(bulkout)), }, { }, } }, @@ -53,7 +56,7 @@ static UsbDeviceDescriptor usb_desc[] = { { }, { .ADDR.reg = (uint32_t)bulkin, - .PCKSIZE.reg = USB_DEVICE_PCKSIZE_SIZE(sizeof(bulkin) >> 4), + .PCKSIZE.reg = USB_DEVICE_PCKSIZE_SIZE(BSIZE(bulkin)), }, } }, };