From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-lf1-f49.google.com (mail-lf1-f49.google.com [209.85.167.49]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 24D6D226D05 for ; Tue, 30 Jun 2026 09:24:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.49 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782811465; cv=none; b=D6m6dYHYXKDQ0xFwoumy+P9bHcFHfeCRM+i9IB1Yd7T4FqNGVoMguZViVYglbyeSUlEWQzIm9s8NARJOeYSvXq/exEYdcK0U7U+FOSR6akLUsc/CveCzDQYfX9LR5WpoHDMzL/6s84gLHwPoDb+dmEfIuz9OuXygmq5zrKag5as= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1782811465; c=relaxed/simple; bh=iSb+ZtMMn7jJl7hDX5bTTXUy7+nmv94tZQ3srN0Ceuk=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References; b=JLvx9Be6AG9+sfBY220lXy2PpqenYSQ4fXo6A/q4Ch+Y8rMtSf+NNJmRfQJoXE8VMhLu5ie+U1i901DfwOKzVMK3HGdwI/xdRsnv/RK7d3t9KFMzgUyHTgKcLKKLSyzc+2k5+gyqtuatKw08n2l+XRdq3yYqoWLdMFbMIKdgNa4= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=lY08zJWl; arc=none smtp.client-ip=209.85.167.49 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="lY08zJWl" Received: by mail-lf1-f49.google.com with SMTP id 2adb3069b0e04-5aeb11c7347so2276663e87.0 for ; Tue, 30 Jun 2026 02:24:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1782811459; x=1783416259; darn=vger.kernel.org; h=references:in-reply-to:message-id:date:subject:cc:to:from:from:to :cc:subject:date:message-id:reply-to; bh=ypqsSruaELZqDLqTvDMBF8OZyvJQU2aEZsWnRsWNrt0=; b=lY08zJWlzuWjSQ04jR1JU1eHMD5LynQaqaOW4T8Eec8FSyvYSRA6cLsLhYoTGl6Ztv jmQ42t+x1+gMpzcTchHDmkKYUPXnt2eLK/3QwFWJY6X1RAQvZc/R4U7uwICuEIkmdntD fYz54HKOLSc5nLGOJUwwhP6NTYP/8d+yIf22cGSBHZIDkxyqKLRQFkPi0eWV5La80MR7 5rfZ0d0QlTvDUYxsRf+4kapRxGmnrDrQ48wTsNiPYXfdpzaFPM+8rswhIzmi7Ia+s20k 52zqBPtUoVzjas9mKJQ9ODmIbJUDCJaZsoVScyCcdlPnzdfZI1SKj4xO1bVJTn8z4hyY 73TA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782811459; x=1783416259; h=references:in-reply-to:message-id:date:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=ypqsSruaELZqDLqTvDMBF8OZyvJQU2aEZsWnRsWNrt0=; b=UDWRAY3Zdg7gDOPFzUdrKjuumIrjrma7qBw3V9PygDYQ+9uibGd7/KZ8nLlPnhzQmu Ebmqrx2uoModabFqyRPh5XhhD/6G9AV/czdtJNJwCIseUSQZtC+wlTGbVilEsbnxX7AX DLjFpayIVOEEFFtF7SoqCnfToyjmUjHxfKQKIdv003yfZ58ReS9BWy/qL/e1TeDxg/Ut r2eqlP+f118XVjNvYO+NXIJ81f/W6O3WVX5zMZ/wcCsGuT96SxeuiDw1hSroqN2HFUfv bvwcfqgDcZM6BwYVlbMwNg3GCBdkK8N0qMJdNm++Lz8V6uA7AGMwFbeWceO+BkP6at9S xssQ== X-Forwarded-Encrypted: i=1; AHgh+RpsWa3xFotL1HLgYJ8z4wq1ZyjRFLVQ+3im3TDCDpBc9lOb3m1awhqgHlQ4b+34wwiGSHPUI7DxOsMSf+U=@vger.kernel.org X-Gm-Message-State: AOJu0YxqrqQw0G03BYjOwpCkxk4lWSaFY84EUi9nmYSR0q1cYCPWnms8 m22OnOihomMGDUd6vpRkNNDMvJAMO3DQY33+aqgGdiygoOKYBIZZENzS X-Gm-Gg: AfdE7clAleEgXmgk0AOw64zQOfX1Su0L0IBEE7ZpZHWb7U9dKQkbFRm6UoS4TMNXQ/W SolXD2BIWdDJXV0Q3UG6Mm/tVo9ty8jronWNuwl5yMDhEHYmIx+pA0XynbBvrdNMezM6pwes9XO mWmER4NLCCfubDPdnIBlpz9lGH3ehkg1tzlI/YZsTTryF6kFUJkYbzTyeMuXNfsXZEAQJV1kfmp r3YLolKRBktBaOyBnLmmZCozWSbwRabmd0CJDzNG0XX7hIB7vAsm6WHO/VZ/0ta0cglsb7E3/Wf YwjORuP3+8sqhjmxdMpgKa0IZZKIzl1xJ9JHQQA+WOq0OA2BQzAw6aEJUVsLAAfJI/F1UxjjOEn oJMVAOWHFLf2P/rHOwcEG/h2x5u2uyRSQbvv2nrEaRkmRkLFmmQMq2Y6pftMm4o8RR/lBixM3B/ 7hudpMdumSNWmkHeb8Pq/LCf9nXwujGBxBJDY7eiF3 X-Received: by 2002:a05:6512:3514:b0:5ae:aeeb:e902 with SMTP id 2adb3069b0e04-5aebdb8a172mr576061e87.13.1782811458881; Tue, 30 Jun 2026 02:24:18 -0700 (PDT) Received: from localhost (c-85-228-45-68.bbcust.telenor.se. [85.228.45.68]) by smtp.gmail.com with ESMTPSA id 2adb3069b0e04-5aebe333821sm437209e87.16.2026.06.30.02.24.18 (version=TLS1_2 cipher=ECDHE-ECDSA-CHACHA20-POLY1305 bits=256/256); Tue, 30 Jun 2026 02:24:18 -0700 (PDT) From: Eli Billauer To: gregkh@linuxfoundation.org Cc: arnd@arndb.de, linux-kernel@vger.kernel.org, Eli Billauer Subject: [PATCH 6/7] char: xillybus: Add defensive sanity checks Date: Tue, 30 Jun 2026 11:23:29 +0200 Message-Id: <20260630092330.43534-7-eli.billauer@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20260630092330.43534-1-eli.billauer@gmail.com> References: <20260630092330.43534-1-eli.billauer@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: Add validation checks for values derived from hardware or user input to prevent incorrect behavior with malformed data. Signed-off-by: Eli Billauer --- drivers/char/xillybus/xillybus_class.c | 11 ++++++++ drivers/char/xillybus/xillybus_class.h | 4 +++ drivers/char/xillybus/xillybus_core.c | 37 ++++++++++++++++++++++++-- drivers/char/xillybus/xillybus_of.c | 6 +++++ drivers/char/xillybus/xillyusb.c | 29 +++++++++++++++++++- 5 files changed, 84 insertions(+), 3 deletions(-) diff --git a/drivers/char/xillybus/xillybus_class.c b/drivers/char/xillybus/xillybus_class.c index 5e8f03b77064..1eecb8ba244a 100644 --- a/drivers/char/xillybus/xillybus_class.c +++ b/drivers/char/xillybus/xillybus_class.c @@ -57,6 +57,9 @@ int xillybus_init_chrdev(struct device *dev, size_t namelen; struct xilly_unit *unit, *u; + if (num_nodes <= 0 || num_nodes > XILLYBUS_MAX_NODES || !idt || !prefix || !dev) + return -ENODEV; + unit = kzalloc_obj(*unit); if (!unit) @@ -68,6 +71,11 @@ int xillybus_init_chrdev(struct device *dev, snprintf(unit->name, UNITNAMELEN, "%s", prefix); for (i = 0; enumerate; i++) { + if (i > 99) { + dev_err(dev, "Failed to obtain unique unit name\n"); + goto fail_obtain; + } + snprintf(unit->name, UNITNAMELEN, "%s_%02d", prefix, i); @@ -219,6 +227,9 @@ int xillybus_find_inode(struct inode *inode, int major = imajor(inode); struct xilly_unit *unit = NULL, *iter; + if (!inode || !private_data || !index) + return -ENODEV; + mutex_lock(&unit_mutex); list_for_each_entry(iter, &unit_list, list_entry) diff --git a/drivers/char/xillybus/xillybus_class.h b/drivers/char/xillybus/xillybus_class.h index 5dbfdfc95c65..264b9f6d6793 100644 --- a/drivers/char/xillybus/xillybus_class.h +++ b/drivers/char/xillybus/xillybus_class.h @@ -8,6 +8,10 @@ #ifndef __XILLYBUS_CLASS_H #define __XILLYBUS_CLASS_H +#define XILLYBUS_MAX_COUNT (((unsigned int) ~0x1ffff) >> 1) +#define XILLYBUS_MAX_NODES 1024 +#define XILLYBUS_MAX_IDT 1048576 + #include #include #include diff --git a/drivers/char/xillybus/xillybus_core.c b/drivers/char/xillybus/xillybus_core.c index b264578b2572..3436f16092e0 100644 --- a/drivers/char/xillybus/xillybus_core.c +++ b/drivers/char/xillybus/xillybus_core.c @@ -351,6 +351,12 @@ static int xilly_get_dma_buffers(struct xilly_endpoint *ep, struct device *dev = ep->dev; struct xilly_buffer *this_buffer = NULL; /* Init to silence warning */ + if (bytebufsize == 0 || bytebufsize > 0x40000000) { + dev_err(ep->dev, + "Illegal buffer size requested in IDT. Aborting.\n"); + return -ENODEV; + } + if (buffers) { /* Not the message buffer */ this_buffer = devm_kcalloc(dev, bufnum, sizeof(struct xilly_buffer), @@ -623,6 +629,12 @@ static int xilly_scan_idt(struct xilly_endpoint *endpoint, return -ENODEV; } + if (count == 0 || count > XILLYBUS_MAX_NODES) { + dev_err(endpoint->dev, + "Unreasonable number of channels. Aborting.\n"); + return -ENODEV; + } + idt_handle->entries = len >> 2; endpoint->num_channels = count; @@ -707,6 +719,9 @@ static ssize_t xillybus_read(struct file *filp, char __user *userbuf, if (channel->endpoint->fatal_error) return -EIO; + if (count > XILLYBUS_MAX_COUNT) + count = XILLYBUS_MAX_COUNT; + deadline = jiffies + 1 + XILLY_RX_TIMEOUT; rc = mutex_lock_interruptible(&channel->wr_mutex); @@ -725,8 +740,18 @@ static ssize_t xillybus_read(struct file *filp, char __user *userbuf, bufidx = channel->wr_host_buf_idx; bufpos = channel->wr_host_buf_pos; howmany = ((channel->wr_buffers[bufidx]->end_offset - + 1) << channel->log2_element_size) - - bufpos; + + 1) << channel->log2_element_size); + + if (howmany > channel->wr_buf_size || + howmany < bufpos) { + dev_err(channel->endpoint->dev, + "Illegal buffer fill level from hardware\n"); + channel->endpoint->fatal_error = 1; + spin_unlock_irqrestore(&channel->wr_spinlock, flags); + break; + } + + howmany -= bufpos; /* Update wr_host_* to its post-operation state */ if (howmany > bytes_to_do) { @@ -1216,6 +1241,9 @@ static ssize_t xillybus_write(struct file *filp, const char __user *userbuf, if (channel->endpoint->fatal_error) return -EIO; + if (count > XILLYBUS_MAX_COUNT) + count = XILLYBUS_MAX_COUNT; + rc = mutex_lock_interruptible(&channel->rd_mutex); if (rc) return rc; @@ -1902,6 +1930,11 @@ int xillybus_endpoint_discovery(struct xilly_endpoint *endpoint) return -ENODEV; } + if (endpoint->idtlen < 4 || endpoint->idtlen > XILLYBUS_MAX_IDT) { + dev_err(endpoint->dev, "Invalid IDT length. Aborting.\n"); + return -ENODEV; + } + /* Enable DMA */ iowrite32((u32) (0x0002 | (endpoint->dma_using_dac & 0x0001)), endpoint->registers + fpga_dma_control_reg); diff --git a/drivers/char/xillybus/xillybus_of.c b/drivers/char/xillybus/xillybus_of.c index 1a1e64133315..22dcc387a5e4 100644 --- a/drivers/char/xillybus/xillybus_of.c +++ b/drivers/char/xillybus/xillybus_of.c @@ -53,6 +53,12 @@ static int xilly_drv_probe(struct platform_device *op) irq = platform_get_irq(op, 0); + if (irq < 0) { + dev_err(endpoint->dev, + "Failed to obtain IRQ number. Aborting.\n"); + return irq; + } + rc = devm_request_irq(dev, irq, xillybus_isr, 0, xillyname, endpoint); if (rc) { diff --git a/drivers/char/xillybus/xillyusb.c b/drivers/char/xillybus/xillyusb.c index aa08206a18ef..7459ec9295af 100644 --- a/drivers/char/xillybus/xillyusb.c +++ b/drivers/char/xillybus/xillyusb.c @@ -396,6 +396,10 @@ static int fifo_init(struct xillyfifo *fifo, fifo->size = fifo->bufnum * fifo->bufsize; fifo->buf_order = buf_order; + if (!fifo->size || /* Unsigned integer overflow */ + fifo->size > 0x40000000) /* Stay clear from signed int issues */ + return -ENOMEM; /* Reported as greed for memory */ + fifo->mem = kmalloc_array(fifo->bufnum, sizeof(void *), GFP_KERNEL); if (!fifo->mem) @@ -888,6 +892,7 @@ static int process_in_opcode(struct xillyusb_dev *xdev, struct xillyusb_channel *chan; struct device *dev = xdev->dev; int chan_idx = chan_num >> 1; + struct xillyfifo *in_fifo; if (chan_idx >= xdev->num_channels) { dev_err(dev, "Received illegal channel ID %d from FPGA\n", @@ -912,7 +917,10 @@ static int process_in_opcode(struct xillyusb_dev *xdev, */ smp_wmb(); WRITE_ONCE(chan->read_data_ok, 0); - wake_up_interruptible(&chan->in_fifo->waitq); + + in_fifo = READ_ONCE(chan->in_fifo); + if (in_fifo) + wake_up_interruptible(&in_fifo->waitq); break; case OPCODE_REACHED_CHECKPOINT: @@ -1443,6 +1451,9 @@ static ssize_t xillyusb_read(struct file *filp, char __user *userbuf, bool sent_set_push = false; int rc; + if (count > XILLYBUS_MAX_COUNT) + count = XILLYBUS_MAX_COUNT; + deadline = jiffies + 1 + XILLY_RX_TIMEOUT; rc = mutex_lock_interruptible(&chan->in_mutex); @@ -1649,6 +1660,9 @@ static ssize_t xillyusb_write(struct file *filp, const char __user *userbuf, struct xillyfifo *fifo = &chan->out_ep->fifo; int rc; + if (count > XILLYBUS_MAX_COUNT) + count = XILLYBUS_MAX_COUNT; + rc = mutex_lock_interruptible(&chan->out_mutex); if (rc) @@ -2072,6 +2086,13 @@ static int xillyusb_discovery(struct usb_interface *interface) } idt_len = READ_ONCE(idt_fifo.fill); + + if (idt_len < 4 || idt_len > XILLYBUS_MAX_IDT) { + rc = -ENODEV; + dev_err(&interface->dev, "Invalid IDT length. Aborting.\n"); + goto unfifo; + } + idt = kmalloc(idt_len, GFP_KERNEL); if (!idt) { @@ -2106,6 +2127,12 @@ static int xillyusb_discovery(struct usb_interface *interface) goto unidt; } + if (num_channels == 0 || num_channels > XILLYBUS_MAX_NODES) { + dev_err(&interface->dev, "Unreasonable number of channels. Aborting.\n"); + rc = -ENODEV; + goto unidt; + } + rc = setup_channels(xdev, (void *)idt + 3, num_channels); if (rc) -- 2.34.1