* [PATCH] staging: axis-fifo: fix integer overflow in write()
@ 2025-10-07 11:58 Murad Sadigov
2025-10-07 12:18 ` Greg KH
2025-10-07 13:05 ` Dan Carpenter
0 siblings, 2 replies; 4+ messages in thread
From: Murad Sadigov @ 2025-10-07 11:58 UTC (permalink / raw)
To: Greg KH; +Cc: linux-staging, linux-kernel
Fix integer overflow in axis_fifo_write() that allows local users
to bypass buffer validation, potentially causing hardware FIFO
buffer overflow and system denial of service.
The axis_fifo_write() function converts user-controlled size_t 'len'
(64-bit) to unsigned int 'words_to_write' (32-bit) without overflow
checking at line 322:
words_to_write = len / sizeof(u32);
On 64-bit systems, when len equals 0x400000000 (16 GiB):
- Division: 0x400000000 / 4 = 0x100000000 (requires 33 bits)
- Truncation: Result stored in 32-bit variable = 0 (overflow)
- Validation bypass: if (0 > fifo_depth) evaluates to false
- Impact: Hardware FIFO overflow, system crash
This allows unprivileged local users with access to /dev/axis_fifo*
to trigger denial of service.
The fix adds overflow check before type conversion to ensure len
does not exceed the maximum safe value (UINT_MAX * sizeof(u32)).
Affected systems include embedded devices using Xilinx FPGA with
AXI-Stream FIFO IP cores.
Signed-off-by: Murad Sadigov <sdgvmrd@gmail.com>
---
drivers/staging/axis-fifo/axis-fifo.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/drivers/staging/axis-fifo/axis-fifo.c
b/drivers/staging/axis-fifo/axis-fifo.c
index 1234567890ab..abcdef123456 100644
--- a/drivers/staging/axis-fifo/axis-fifo.c
+++ b/drivers/staging/axis-fifo/axis-fifo.c
@@ -319,6 +319,13 @@ static ssize_t axis_fifo_write(struct file *f,
const char __user *buf,
return -EINVAL;
}
+ /* Prevent integer overflow in words calculation */
+ if (len > (size_t)UINT_MAX * sizeof(u32)) {
+ dev_err(fifo->dt_device,
+ "write length %zu exceeds maximum %zu bytes\n",
+ len, (size_t)UINT_MAX * sizeof(u32));
+ return -EINVAL;
+ }
+
words_to_write = len / sizeof(u32);
if (!words_to_write) {
--
2.34.1
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [PATCH] staging: axis-fifo: fix integer overflow in write() 2025-10-07 11:58 [PATCH] staging: axis-fifo: fix integer overflow in write() Murad Sadigov @ 2025-10-07 12:18 ` Greg KH 2025-10-07 13:01 ` Greg KH 2025-10-07 13:05 ` Dan Carpenter 1 sibling, 1 reply; 4+ messages in thread From: Greg KH @ 2025-10-07 12:18 UTC (permalink / raw) To: Murad Sadigov; +Cc: linux-staging, linux-kernel On Tue, Oct 07, 2025 at 03:58:13PM +0400, Murad Sadigov wrote: > Fix integer overflow in axis_fifo_write() that allows local users > to bypass buffer validation, potentially causing hardware FIFO > buffer overflow and system denial of service. > > The axis_fifo_write() function converts user-controlled size_t 'len' > (64-bit) to unsigned int 'words_to_write' (32-bit) without overflow > checking at line 322: > > words_to_write = len / sizeof(u32); > > On 64-bit systems, when len equals 0x400000000 (16 GiB): > - Division: 0x400000000 / 4 = 0x100000000 (requires 33 bits) > - Truncation: Result stored in 32-bit variable = 0 (overflow) > - Validation bypass: if (0 > fifo_depth) evaluates to false > - Impact: Hardware FIFO overflow, system crash > > This allows unprivileged local users with access to /dev/axis_fifo* > to trigger denial of service. > > The fix adds overflow check before type conversion to ensure len > does not exceed the maximum safe value (UINT_MAX * sizeof(u32)). > > Affected systems include embedded devices using Xilinx FPGA with > AXI-Stream FIFO IP cores. > > Signed-off-by: Murad Sadigov <sdgvmrd@gmail.com> > --- > drivers/staging/axis-fifo/axis-fifo.c | 7 +++++++ > 1 file changed, 7 insertions(+) > > diff --git a/drivers/staging/axis-fifo/axis-fifo.c > b/drivers/staging/axis-fifo/axis-fifo.c > index 1234567890ab..abcdef123456 100644 > --- a/drivers/staging/axis-fifo/axis-fifo.c > +++ b/drivers/staging/axis-fifo/axis-fifo.c > @@ -319,6 +319,13 @@ static ssize_t axis_fifo_write(struct file *f, > const char __user *buf, > return -EINVAL; > } > > + /* Prevent integer overflow in words calculation */ > + if (len > (size_t)UINT_MAX * sizeof(u32)) { > + dev_err(fifo->dt_device, > + "write length %zu exceeds maximum %zu bytes\n", > + len, (size_t)UINT_MAX * sizeof(u32)); > + return -EINVAL; > + } > + Something went wrong here, your email client dropped all of the leading spaces :( Also, you do not want to allow userspace to cause a DoS on the kernel log, so don't log this information, just return an error, no need to print anything. thanks, greg k-h ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] staging: axis-fifo: fix integer overflow in write() 2025-10-07 12:18 ` Greg KH @ 2025-10-07 13:01 ` Greg KH 0 siblings, 0 replies; 4+ messages in thread From: Greg KH @ 2025-10-07 13:01 UTC (permalink / raw) To: Murad Sadigov; +Cc: linux-staging, linux-kernel On Tue, Oct 07, 2025 at 02:18:47PM +0200, Greg KH wrote: > On Tue, Oct 07, 2025 at 03:58:13PM +0400, Murad Sadigov wrote: > > Fix integer overflow in axis_fifo_write() that allows local users > > to bypass buffer validation, potentially causing hardware FIFO > > buffer overflow and system denial of service. > > > > The axis_fifo_write() function converts user-controlled size_t 'len' > > (64-bit) to unsigned int 'words_to_write' (32-bit) without overflow > > checking at line 322: > > > > words_to_write = len / sizeof(u32); > > > > On 64-bit systems, when len equals 0x400000000 (16 GiB): > > - Division: 0x400000000 / 4 = 0x100000000 (requires 33 bits) > > - Truncation: Result stored in 32-bit variable = 0 (overflow) > > - Validation bypass: if (0 > fifo_depth) evaluates to false > > - Impact: Hardware FIFO overflow, system crash > > > > This allows unprivileged local users with access to /dev/axis_fifo* > > to trigger denial of service. > > > > The fix adds overflow check before type conversion to ensure len > > does not exceed the maximum safe value (UINT_MAX * sizeof(u32)). > > > > Affected systems include embedded devices using Xilinx FPGA with > > AXI-Stream FIFO IP cores. > > > > Signed-off-by: Murad Sadigov <sdgvmrd@gmail.com> > > --- > > drivers/staging/axis-fifo/axis-fifo.c | 7 +++++++ > > 1 file changed, 7 insertions(+) > > > > diff --git a/drivers/staging/axis-fifo/axis-fifo.c > > b/drivers/staging/axis-fifo/axis-fifo.c > > index 1234567890ab..abcdef123456 100644 > > --- a/drivers/staging/axis-fifo/axis-fifo.c > > +++ b/drivers/staging/axis-fifo/axis-fifo.c > > @@ -319,6 +319,13 @@ static ssize_t axis_fifo_write(struct file *f, > > const char __user *buf, > > return -EINVAL; > > } > > > > + /* Prevent integer overflow in words calculation */ > > + if (len > (size_t)UINT_MAX * sizeof(u32)) { > > + dev_err(fifo->dt_device, > > + "write length %zu exceeds maximum %zu bytes\n", > > + len, (size_t)UINT_MAX * sizeof(u32)); > > + return -EINVAL; > > + } > > + > > Something went wrong here, your email client dropped all of the leading > spaces :( > > Also, you do not want to allow userspace to cause a DoS on the kernel > log, so don't log this information, just return an error, no need to > print anything. Also, look at this function in the linux-next branch. It has been rewritten and I think will not fail in the same way you are thinking it will fail here. I'll get those changes to Linus by the end of this week, sorry for not noticing they were not flushed out to his tree yet. thanks, greg k-h ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] staging: axis-fifo: fix integer overflow in write() 2025-10-07 11:58 [PATCH] staging: axis-fifo: fix integer overflow in write() Murad Sadigov 2025-10-07 12:18 ` Greg KH @ 2025-10-07 13:05 ` Dan Carpenter 1 sibling, 0 replies; 4+ messages in thread From: Dan Carpenter @ 2025-10-07 13:05 UTC (permalink / raw) To: Murad Sadigov; +Cc: Greg KH, linux-staging, linux-kernel Hi Murad, This can't happen because vfs_write() caps len at <= MAX_RW_COUNT. Presumably this is your Linkedin page? https://www.linkedin.com/in/mrdsdgv/?originalSubdomain=az When you're doing the analysis on this sort of thing, it's nice to have the Smatch cross function db built. I hacked up the vfs_write() information a bit so it says that len can't be more than 1G when actually it's capped at 2G. I did that so that count + len wouldn't trigger an integer overflow warning. Those are prevented in rw_verify_area(). $ smdb axis_fifo_write file | caller | function | type | parameter | key | value | fs/read_write.c | vfs_write | (struct file_operations)->write | INTERNAL | -1 | | long(*)(struct file*, char*, ulong, llong*) fs/read_write.c | vfs_write | (struct file_operations)->write | BIT_INFO | 0 | f->f_mode | 0x40002,0xffffffff fs/read_write.c | vfs_write | (struct file_operations)->write | USER_DATA | 1 | buf | 0-u64max[c] fs/read_write.c | vfs_write | (struct file_operations)->write | USER_DATA | 2 | len | 0-1000000000 fs/read_write.c | vfs_write | (struct file_operations)->write | USER_DATA | 3 | *off | 0-1000000000 fs/read_write.c | vfs_write | (struct file_operations)->write | USER_PTR | 3 | off | fs/read_write.c | vfs_write | (struct file_operations)->write | PARAM_VALUE | 0 | f | 4096-9223372036854775807 fs/read_write.c | vfs_write | (struct file_operations)->write | PARAM_VALUE | 0 | f->f_op | 4096-ptr_max fs/read_write.c | vfs_write | (struct file_operations)->write | PARAM_VALUE | 0 | f->f_op->write | 1-u64max fs/read_write.c | vfs_write | (struct file_operations)->write | PARAM_VALUE | 2 | len | 0-1000000000,2147479552 fs/read_write.c | vfs_write | (struct file_operations)->write | FUZZY_MAX | 2 | len | 2147479552 fs/read_write.c | vfs_write | (struct file_operations)->write | PARAM_VALUE | 3 | *off | 0-1000000000 fs/read_write.c | vfs_write | (struct file_operations)->write | PARAM_VALUE | 3 | off | 0,4096-ptr_max fs/read_write.c | vfs_write | (struct file_operations)->write | CONTAINER | 0 | -32-80+0 | $(-1) fs/read_write.c | vfs_write | (struct file_operations)->write | DATA_SOURCE | 0 | f | $0 fs/read_write.c | vfs_write | (struct file_operations)->write | DATA_SOURCE | 1 | buf | $1 fs/read_write.c | vfs_write | (struct file_operations)->write | DATA_SOURCE | 2 | len | $2 [m] fs/read_write.c | vfs_write | (struct file_operations)->write | DATA_SOURCE | 3 | off | $3 fs/read_write.c | vfs_write | (struct file_operations)->write | 2059 | -1 | | y fs/read_write.c | vfs_write | (struct file_operations)->write | 2059 | -1 | | y fs/read_write.c | vfs_write | (struct file_operations)->write | BUF_SIZE | 3 | off | (-1),8 $ regards, dan carpenter ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2025-10-07 13:05 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2025-10-07 11:58 [PATCH] staging: axis-fifo: fix integer overflow in write() Murad Sadigov 2025-10-07 12:18 ` Greg KH 2025-10-07 13:01 ` Greg KH 2025-10-07 13:05 ` Dan Carpenter
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).