* [PATCH] staging: fbtft: fix unaligned access and buffer size when startbyte is used
@ 2026-06-25 10:30 suryasaimadhu
2026-06-25 10:42 ` sashiko-bot
` (2 more replies)
0 siblings, 3 replies; 13+ messages in thread
From: suryasaimadhu @ 2026-06-25 10:30 UTC (permalink / raw)
To: andy
Cc: gregkh, dri-devel, linux-fbdev, linux-staging, linux-kernel,
suryasaimadhu
When par->startbyte is non-zero, buf is advanced by one byte creating
an unaligned pointer for 16-bit types (u16, __be16). Dereferencing this
unaligned pointer can cause a kernel panic on strict-alignment
architectures.
Fix by using put_unaligned() instead of direct pointer dereference.
Also fix incorrect buffer size calculation in fbtft_write_buf_dc() call:
len * (sizeof(data_type) + offset) /* wrong: multiplies offset by len */
len * sizeof(data_type) + offset /* correct: one startbyte +
len items */
Signed-off-by: suryasaimadhu <suryasaimadhu369@gmail.com>
---
drivers/staging/fbtft/fbtft-bus.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/drivers/staging/fbtft/fbtft-bus.c b/drivers/staging/fbtft/fbtft-bus.c
index 2169f8d1d..cfcf4d7e7 100644
--- a/drivers/staging/fbtft/fbtft-bus.c
+++ b/drivers/staging/fbtft/fbtft-bus.c
@@ -4,6 +4,7 @@
#include <linux/gpio/consumer.h>
#include <linux/spi/spi.h>
#include "fbtft.h"
+#include <linux/unaligned.h>
/*****************************************************************************
*
@@ -40,7 +41,7 @@ void func(struct fbtft_par *par, int len, ...) \
offset = 1; \
} \
\
- *buf = modifier((data_type)va_arg(args, unsigned int)); \
+ put_unaligned(modifier((data_type)va_arg(args, unsigned int)), buf); \
ret = fbtft_write_buf_dc(par, par->buf, sizeof(data_type) + offset, \
0); \
if (ret < 0) \
@@ -52,11 +53,13 @@ void func(struct fbtft_par *par, int len, ...) \
\
if (len) { \
i = len; \
- while (i--) \
- *buf++ = modifier((data_type)va_arg(args, \
- unsigned int)); \
+ while (i--) { \
+ put_unaligned(modifier((data_type)va_arg(args, \
+ unsigned int)), buf); \
+ buf++; \
+ } \
fbtft_write_buf_dc(par, par->buf, \
- len * (sizeof(data_type) + offset), 1); \
+ len * sizeof(data_type) + offset, 1); \
} \
out: \
va_end(args); \
--
2.47.3
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH] staging: fbtft: fix unaligned access and buffer size when startbyte is used 2026-06-25 10:30 [PATCH] staging: fbtft: fix unaligned access and buffer size when startbyte is used suryasaimadhu @ 2026-06-25 10:42 ` sashiko-bot 2026-06-25 11:02 ` [PATCH] staging: fbtft: fix unaligned vmem writes when txbuf is byte-offset suryasaimadhu 2026-06-25 14:08 ` [PATCH] staging: fbtft: fix unaligned access and buffer size when startbyte is used Andy Shevchenko 2026-06-26 6:48 ` David Laight 2 siblings, 1 reply; 13+ messages in thread From: sashiko-bot @ 2026-06-25 10:42 UTC (permalink / raw) To: suryasaimadhu; +Cc: dri-devel Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: Pre-existing issues: - [High] The patch fixes unaligned pointer dereferences in `fbtft_write_reg` macros but misses identical unaligned accesses in `fbtft_write_vmem16_bus8()` and `write_vmem16_bus8()` (in `fb_ra8875.c`). -- commit 41bf3a5882f6fd09bf60fb5460097488d5497b06 Author: suryasaimadhu <suryasaimadhu369@gmail.com> staging: fbtft: fix unaligned access and buffer size when startbyte is used This commit addresses an unaligned memory access in fbtft-bus.c macros by replacing direct pointer dereferences with put_unaligned() when par->startbyte is used. It also corrects a buffer size calculation. > diff --git a/drivers/staging/fbtft/fbtft-bus.c b/drivers/staging/fbtft/fbtft-bus.c > index 30e436ff19e4c..0314e450799de 100644 > --- a/drivers/staging/fbtft/fbtft-bus.c > +++ b/drivers/staging/fbtft/fbtft-bus.c [ ... ] > @@ -39,7 +40,7 @@ void func(struct fbtft_par *par, int len, ...) \ > offset = 1; \ > } \ > \ > - *buf = modifier((data_type)va_arg(args, unsigned int)); \ > + put_unaligned(modifier((data_type)va_arg(args, unsigned int)), buf); \ > ret = fbtft_write_buf_dc(par, par->buf, sizeof(data_type) + offset, \ > 0); \ [Severity: High] This is a pre-existing issue, but does this same unaligned access pattern exist in other functions that use startbyte? Looking at fbtft_write_vmem16_bus8(), when par->startbyte is non-zero, txbuf16 is offset by 1 byte and directly dereferenced: drivers/staging/fbtft/fbtft-bus.c:fbtft_write_vmem16_bus8() { ... txbuf16 = par->txbuf.buf + 1; ... for (i = 0; i < to_copy; i++) txbuf16[i] = cpu_to_be16(vmem16[i]); ... } Could this direct 16-bit store to an odd-aligned address still trigger kernel panics on strict-alignment architectures during video memory updates? A similar pattern also appears to exist in the ra8875 driver where txbuf16 is unconditionally offset by 1 byte: drivers/staging/fbtft/fb_ra8875.c:write_vmem16_bus8() { ... txbuf16 = par->txbuf.buf + 1; ... for (i = 0; i < to_copy; i++) txbuf16[i] = cpu_to_be16(vmem16[i]); ... } Should these locations also be updated to use put_unaligned() to ensure all unaligned accesses are caught by this fix? -- Sashiko AI review · https://sashiko.dev/#/patchset/20260625103041.281190-1-suryasaimadhu369@gmail.com?part=1 ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH] staging: fbtft: fix unaligned vmem writes when txbuf is byte-offset 2026-06-25 10:42 ` sashiko-bot @ 2026-06-25 11:02 ` suryasaimadhu 2026-06-25 11:16 ` sashiko-bot ` (3 more replies) 0 siblings, 4 replies; 13+ messages in thread From: suryasaimadhu @ 2026-06-25 11:02 UTC (permalink / raw) To: andy Cc: gregkh, dri-devel, linux-fbdev, linux-staging, linux-kernel, suryasaimadhu fbtft_write_vmem16_bus8() and fb_ra8875's write_vmem16_bus8() offset txbuf16 by one byte for a command/start prefix, then store 16-bit pixel data via txbuf16[i]. On strict-alignment architectures this can fault the same way as the write_reg path fixed in the previous patch. Use put_unaligned() for these stores. Signed-off-by: suryasaimadhu <suryasaimadhu369@gmail.com> --- drivers/staging/fbtft/fb_ra8875.c | 3 ++- drivers/staging/fbtft/fbtft-bus.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/fbtft/fb_ra8875.c b/drivers/staging/fbtft/fb_ra8875.c index 0ab1de664..5b95b0095 100644 --- a/drivers/staging/fbtft/fb_ra8875.c +++ b/drivers/staging/fbtft/fb_ra8875.c @@ -10,6 +10,7 @@ #include <linux/delay.h> #include <linux/gpio/consumer.h> +#include <linux/unaligned.h> #include "fbtft.h" #define DRVNAME "fb_ra8875" @@ -262,7 +263,7 @@ static int write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) to_copy, remain - to_copy); for (i = 0; i < to_copy; i++) - txbuf16[i] = cpu_to_be16(vmem16[i]); + put_unaligned(cpu_to_be16(vmem16[i]), &txbuf16[i]); vmem16 = vmem16 + to_copy; ret = par->fbtftops.write(par, par->txbuf.buf, diff --git a/drivers/staging/fbtft/fbtft-bus.c b/drivers/staging/fbtft/fbtft-bus.c index cfcf4d7e7..fc3faab7d 100644 --- a/drivers/staging/fbtft/fbtft-bus.c +++ b/drivers/staging/fbtft/fbtft-bus.c @@ -158,7 +158,7 @@ int fbtft_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) to_copy, remain - to_copy); for (i = 0; i < to_copy; i++) - txbuf16[i] = cpu_to_be16(vmem16[i]); + put_unaligned(cpu_to_be16(vmem16[i]), &txbuf16[i]); vmem16 = vmem16 + to_copy; ret = par->fbtftops.write(par, par->txbuf.buf, -- 2.47.3 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH] staging: fbtft: fix unaligned vmem writes when txbuf is byte-offset 2026-06-25 11:02 ` [PATCH] staging: fbtft: fix unaligned vmem writes when txbuf is byte-offset suryasaimadhu @ 2026-06-25 11:16 ` sashiko-bot 2026-06-25 11:42 ` [PATCH] staging: fbtft: fix unaligned access and txbuf safety issues suryasaimadhu 2026-06-25 13:20 ` [PATCH] staging: fbtft: fix unaligned vmem writes when txbuf is byte-offset kernel test robot ` (2 subsequent siblings) 3 siblings, 1 reply; 13+ messages in thread From: sashiko-bot @ 2026-06-25 11:16 UTC (permalink / raw) To: suryasaimadhu; +Cc: dri-devel Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider: New issues: - [Low] Missing `#include <linux/unaligned.h>` in `fbtft-bus.c`. Pre-existing issues: - [High] Unaligned memory stores in `define_fbtft_write_reg` macro when `startbyte` is used. - [High] An integer underflow in `tx_array_size` leads to an out-of-bounds heap write if the `txbuflen` device property is set to a small value. - [High] Missing NULL check for `par->txbuf.buf` in `fb_ra8875.c` leads to a NULL pointer dereference on Big Endian systems. -- commit 57041cf8757e7586efa49957106ff7e0611f087c Author: suryasaimadhu <suryasaimadhu369@gmail.com> staging: fbtft: fix unaligned vmem writes when txbuf is byte-offset This commit addresses unaligned memory access in the fbtft driver. It updates write_vmem16_bus8() in both fb_ra8875.c and fbtft-bus.c to use put_unaligned() when storing 16-bit pixel data. > diff --git a/drivers/staging/fbtft/fb_ra8875.c b/drivers/staging/fbtft/fb_ra8875.c > index 0ab1de6647d07..5b95b00953994 100644 > --- a/drivers/staging/fbtft/fb_ra8875.c > +++ b/drivers/staging/fbtft/fb_ra8875.c > @@ -10,6 +10,7 @@ > #include <linux/delay.h> > > #include <linux/gpio/consumer.h> > +#include <linux/unaligned.h> > #include "fbtft.h" > > #define DRVNAME "fb_ra8875" [Severity: High] This is a pre-existing issue, but does write_vmem16_bus8() have a potential null pointer dereference here? fb_ra8875.c:write_vmem16_bus8() { ... txbuf16 = par->txbuf.buf + 1; tx_array_size -= 2; *(u8 *)(par->txbuf.buf) = 0x00; ... } If the txbuflen device property is 0, par->txbuf.buf remains null on big endian systems because the fallback allocation is gated by a little endian check. Could this cause a crash when assigning 0x00 unconditionally? [Severity: High] This is a pre-existing issue, but could tx_array_size underflow and cause an out-of-bounds heap write? fb_ra8875.c:write_vmem16_bus8() { ... tx_array_size = par->txbuf.len / 2; txbuf16 = par->txbuf.buf + 1; tx_array_size -= 2; ... while (remain) { to_copy = min(tx_array_size, remain); ... } If par->txbuf.len is set to a small value like 2 via the device tree, tx_array_size evaluates to 1. Subtracting 2 causes it to underflow to a huge value. Would the min() check then just use remain, causing the loop to write past the end of the allocated heap buffer? > @@ -262,7 +263,7 @@ static int write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) > to_copy, remain - to_copy); > > for (i = 0; i < to_copy; i++) > - txbuf16[i] = cpu_to_be16(vmem16[i]); > + put_unaligned(cpu_to_be16(vmem16[i]), &txbuf16[i]); > > vmem16 = vmem16 + to_copy; > ret = par->fbtftops.write(par, par->txbuf.buf, > diff --git a/drivers/staging/fbtft/fbtft-bus.c b/drivers/staging/fbtft/fbtft-bus.c > index 30e436ff19e4c..9e25c19ec9ada 100644 > --- a/drivers/staging/fbtft/fbtft-bus.c > +++ b/drivers/staging/fbtft/fbtft-bus.c [Severity: High] This is a pre-existing issue, but does the define_fbtft_write_reg macro also suffer from unaligned stores? fbtft-bus.c:define_fbtft_write_reg() { ... if (par->startbyte) *buf++ = par->startbyte | (((size & 0xF) + 1) << 4); ... *buf = modifier((data_type)va_arg(args, unsigned int)); ... } If par->startbyte is used, buf is offset by 1 byte. If data_type is a 16-bit type, would this dereference create a misaligned store and fault on strict-alignment architectures? [Severity: High] This is a pre-existing issue, but fbtft_write_vmem16_bus8() shares the same integer underflow behavior as fb_ra8875.c: fbtft-bus.c:fbtft_write_vmem16_bus8() { ... tx_array_size = par->txbuf.len / 2; if (par->startbyte) { ... tx_array_size -= 2; ... while (remain) { to_copy = min(tx_array_size, remain); ... } Could this similarly overwrite memory beyond the heap buffer if a small txbuflen is provided? > @@ -154,7 +154,7 @@ int fbtft_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) > to_copy, remain - to_copy); > > for (i = 0; i < to_copy; i++) > - txbuf16[i] = cpu_to_be16(vmem16[i]); > + put_unaligned(cpu_to_be16(vmem16[i]), &txbuf16[i]); [Severity: Low] Does this file need to include linux/unaligned.h? Since the header was included in fb_ra8875.c but not added here, could this cause build failures on architectures where put_unaligned() isn't transitively included by other headers? > > vmem16 = vmem16 + to_copy; > ret = par->fbtftops.write(par, par->txbuf.buf, -- Sashiko AI review · https://sashiko.dev/#/patchset/20260625110237.304435-1-suryasaimadhu369@gmail.com?part=1 ^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH] staging: fbtft: fix unaligned access and txbuf safety issues 2026-06-25 11:16 ` sashiko-bot @ 2026-06-25 11:42 ` suryasaimadhu 2026-06-25 11:54 ` sashiko-bot ` (2 more replies) 0 siblings, 3 replies; 13+ messages in thread From: suryasaimadhu @ 2026-06-25 11:42 UTC (permalink / raw) To: andy Cc: gregkh, dri-devel, linux-fbdev, linux-staging, linux-kernel, suryasaimadhu This patch addresses several pre-existing issues in the fbtft driver: 1. define_fbtft_write_reg(): when par->startbyte is set, buf is advanced by one byte creating a misaligned pointer for 16-bit types. Use put_unaligned() for register writes and fix the SPI transfer size from len * (sizeof(data_type) + offset) to len * sizeof(data_type) + offset. 2. fbtft_write_vmem16_bus8() and fb_ra8875 write_vmem16_bus8(): same unaligned 16-bit stores when txbuf is byte-offset for a start prefix. Use put_unaligned() for pixel data copies. 3. tx_array_size underflow: both vmem helpers subtract 2 from tx_array_size when a startbyte prefix is used. A small txbuflen device property causes unsigned underflow and out-of-bounds heap writes. Fall back to the non-buffered write path when the buffer is too small. 4. fb_ra8875 write_vmem16_bus8(): missing NULL check for par->txbuf.buf, which remains NULL on big-endian when txbuflen is 0 because the PAGE_SIZE fallback is little-endian only. Fall back to direct write when the buffer is missing. Also replace empty modifier arguments in define_fbtft_write_reg() with a no-op macro to fix checkpatch warnings. Signed-off-by: suryasaimadhu <suryasaimadhu369@gmail.com> --- drivers/staging/fbtft/fb_ra8875.c | 10 +++++++++- drivers/staging/fbtft/fbtft-bus.c | 25 +++++++++++++++++-------- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/drivers/staging/fbtft/fb_ra8875.c b/drivers/staging/fbtft/fb_ra8875.c index 0ab1de664..06f650aac 100644 --- a/drivers/staging/fbtft/fb_ra8875.c +++ b/drivers/staging/fbtft/fb_ra8875.c @@ -10,6 +10,7 @@ #include <linux/delay.h> #include <linux/gpio/consumer.h> +#include <linux/unaligned.h> #include "fbtft.h" #define DRVNAME "fb_ra8875" @@ -250,7 +251,14 @@ static int write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) remain = len / 2; vmem16 = (u16 *)(par->info->screen_buffer + offset); + + if (!par->txbuf.buf) + return par->fbtftops.write(par, vmem16, len); + tx_array_size = par->txbuf.len / 2; + if (tx_array_size <= 2) + return par->fbtftops.write(par, vmem16, len); + txbuf16 = par->txbuf.buf + 1; tx_array_size -= 2; *(u8 *)(par->txbuf.buf) = 0x00; @@ -262,7 +270,7 @@ static int write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) to_copy, remain - to_copy); for (i = 0; i < to_copy; i++) - txbuf16[i] = cpu_to_be16(vmem16[i]); + put_unaligned(cpu_to_be16(vmem16[i]), &txbuf16[i]); vmem16 = vmem16 + to_copy; ret = par->fbtftops.write(par, par->txbuf.buf, diff --git a/drivers/staging/fbtft/fbtft-bus.c b/drivers/staging/fbtft/fbtft-bus.c index 30e436ff1..52a0c5c0c 100644 --- a/drivers/staging/fbtft/fbtft-bus.c +++ b/drivers/staging/fbtft/fbtft-bus.c @@ -4,6 +4,7 @@ #include <linux/gpio/consumer.h> #include <linux/spi/spi.h> #include "fbtft.h" +#include <linux/unaligned.h> /***************************************************************************** * @@ -11,6 +12,7 @@ * *****************************************************************************/ +#define fbtft_write_reg_no_modifier(x) (x) #define define_fbtft_write_reg(func, buffer_type, data_type, modifier) \ void func(struct fbtft_par *par, int len, ...) \ { \ @@ -39,7 +41,7 @@ void func(struct fbtft_par *par, int len, ...) \ offset = 1; \ } \ \ - *buf = modifier((data_type)va_arg(args, unsigned int)); \ + put_unaligned(modifier((data_type)va_arg(args, unsigned int)), buf); \ ret = fbtft_write_buf_dc(par, par->buf, sizeof(data_type) + offset, \ 0); \ if (ret < 0) \ @@ -51,20 +53,22 @@ void func(struct fbtft_par *par, int len, ...) \ \ if (len) { \ i = len; \ - while (i--) \ - *buf++ = modifier((data_type)va_arg(args, \ - unsigned int)); \ + while (i--) { \ + put_unaligned(modifier((data_type)va_arg(args, \ + unsigned int)), buf); \ + buf++; \ + } \ fbtft_write_buf_dc(par, par->buf, \ - len * (sizeof(data_type) + offset), 1); \ + len * sizeof(data_type) + offset, 1); \ } \ out: \ va_end(args); \ } \ EXPORT_SYMBOL(func); -define_fbtft_write_reg(fbtft_write_reg8_bus8, u8, u8, ) +define_fbtft_write_reg(fbtft_write_reg8_bus8, u8, u8, fbtft_write_reg_no_modifier) define_fbtft_write_reg(fbtft_write_reg16_bus8, __be16, u16, cpu_to_be16) -define_fbtft_write_reg(fbtft_write_reg16_bus16, u16, u16, ) +define_fbtft_write_reg(fbtft_write_reg16_bus16, u16, u16, fbtft_write_reg_no_modifier) void fbtft_write_reg8_bus9(struct fbtft_par *par, int len, ...) { @@ -142,19 +146,24 @@ int fbtft_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) tx_array_size = par->txbuf.len / 2; if (par->startbyte) { + if (tx_array_size <= 2) + return par->fbtftops.write(par, vmem16, len); txbuf16 = par->txbuf.buf + 1; tx_array_size -= 2; *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2; startbyte_size = 1; } + if (!tx_array_size) + return par->fbtftops.write(par, vmem16, len); + while (remain) { to_copy = min(tx_array_size, remain); dev_dbg(par->info->device, "to_copy=%zu, remain=%zu\n", to_copy, remain - to_copy); for (i = 0; i < to_copy; i++) - txbuf16[i] = cpu_to_be16(vmem16[i]); + put_unaligned(cpu_to_be16(vmem16[i]), &txbuf16[i]); vmem16 = vmem16 + to_copy; ret = par->fbtftops.write(par, par->txbuf.buf, -- 2.47.3 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH] staging: fbtft: fix unaligned access and txbuf safety issues 2026-06-25 11:42 ` [PATCH] staging: fbtft: fix unaligned access and txbuf safety issues suryasaimadhu @ 2026-06-25 11:54 ` sashiko-bot 2026-06-25 12:00 ` Dan Carpenter 2026-06-25 14:05 ` Andy Shevchenko 2 siblings, 0 replies; 13+ messages in thread From: sashiko-bot @ 2026-06-25 11:54 UTC (permalink / raw) To: suryasaimadhu; +Cc: dri-devel Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider: - [High] Hardware protocol violation in unbuffered SPI write fallback paths. -- commit 3d08e05dccbf9cbe108bf3c042c710ace7899fe1 Author: suryasaimadhu <suryasaimadhu369@gmail.com> staging: fbtft: fix unaligned access and txbuf safety issues This commit fixes unaligned access issues during register writes and pixel data copies in the fbtft driver. It also adds bounds checking and fallbacks for when the transmit buffer size underflows or is missing. > diff --git a/drivers/staging/fbtft/fb_ra8875.c b/drivers/staging/fbtft/fb_ra8875.c > index 0ab1de6647d07..06f650aacc204 100644 > --- a/drivers/staging/fbtft/fb_ra8875.c > +++ b/drivers/staging/fbtft/fb_ra8875.c > @@ -250,7 +251,14 @@ static int write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) > > remain = len / 2; > vmem16 = (u16 *)(par->info->screen_buffer + offset); > + > + if (!par->txbuf.buf) > + return par->fbtftops.write(par, vmem16, len); > + > tx_array_size = par->txbuf.len / 2; > + if (tx_array_size <= 2) > + return par->fbtftops.write(par, vmem16, len); > + [Severity: High] Does this fallback bypass the 0x00 command prefix required by the RA8875 hardware? Since vmem16 points directly to the framebuffer memory, this direct write will omit the prefix, which might cause the display controller to misinterpret the first pixel as a command. Additionally, could this skip the cpu_to_be16() conversion on little-endian CPUs, sending pixels in the wrong byte order? Would it be safer to return an error if the required transmission buffer is unavailable or too small to prepend the hardware protocol prefix? > txbuf16 = par->txbuf.buf + 1; > tx_array_size -= 2; > *(u8 *)(par->txbuf.buf) = 0x00; [ ... ] > diff --git a/drivers/staging/fbtft/fbtft-bus.c b/drivers/staging/fbtft/fbtft-bus.c > index 30e436ff19e4c..52a0c5c0cbaed 100644 > --- a/drivers/staging/fbtft/fbtft-bus.c > +++ b/drivers/staging/fbtft/fbtft-bus.c [ ... ] > @@ -142,19 +146,24 @@ int fbtft_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) > tx_array_size = par->txbuf.len / 2; > > if (par->startbyte) { > + if (tx_array_size <= 2) > + return par->fbtftops.write(par, vmem16, len); [Severity: High] Does this skip prepending the par->startbyte prefix when the buffer is too small, despite the prefix being explicitly required? Like the RA8875 case above, this fallback bypasses both the command prefix and endianness conversions. > txbuf16 = par->txbuf.buf + 1; > tx_array_size -= 2; > *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2; > startbyte_size = 1; > } > > + if (!tx_array_size) > + return par->fbtftops.write(par, vmem16, len); > + [Severity: High] Could this result in the same issue of bypassing necessary prefixes and endianness conversions if tx_array_size evaluates to zero? Should we return an error instead of silently sending incorrectly formatted data? > while (remain) { > to_copy = min(tx_array_size, remain); -- Sashiko AI review · https://sashiko.dev/#/patchset/20260625114215.325973-1-suryasaimadhu369@gmail.com?part=1 ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] staging: fbtft: fix unaligned access and txbuf safety issues 2026-06-25 11:42 ` [PATCH] staging: fbtft: fix unaligned access and txbuf safety issues suryasaimadhu 2026-06-25 11:54 ` sashiko-bot @ 2026-06-25 12:00 ` Dan Carpenter 2026-06-25 14:05 ` Andy Shevchenko 2 siblings, 0 replies; 13+ messages in thread From: Dan Carpenter @ 2026-06-25 12:00 UTC (permalink / raw) To: suryasaimadhu Cc: andy, gregkh, dri-devel, linux-fbdev, linux-staging, linux-kernel On Thu, Jun 25, 2026 at 07:42:15PM +0800, suryasaimadhu wrote: > This patch addresses several pre-existing issues in the fbtft driver: > > 1. define_fbtft_write_reg(): when par->startbyte is set, buf is > advanced by one byte creating a misaligned pointer for 16-bit types. > Use put_unaligned() for register writes and fix the SPI transfer > size from len * (sizeof(data_type) + offset) to > len * sizeof(data_type) + offset. > > 2. fbtft_write_vmem16_bus8() and fb_ra8875 write_vmem16_bus8(): same > unaligned 16-bit stores when txbuf is byte-offset for a start > prefix. Use put_unaligned() for pixel data copies. > > 3. tx_array_size underflow: both vmem helpers subtract 2 from > tx_array_size when a startbyte prefix is used. A small txbuflen > device property causes unsigned underflow and out-of-bounds heap > writes. Fall back to the non-buffered write path when the buffer > is too small. > > 4. fb_ra8875 write_vmem16_bus8(): missing NULL check for > par->txbuf.buf, which remains NULL on big-endian when txbuflen is > 0 because the PAGE_SIZE fallback is little-endian only. Fall back > to direct write when the buffer is missing. > > Also replace empty modifier arguments in define_fbtft_write_reg() with > a no-op macro to fix checkpatch warnings. > > Signed-off-by: suryasaimadhu <suryasaimadhu369@gmail.com> Is this how you would sign a legal document? This patch does too many things at once. Split it up. Also please a delay between sending us patches. Otherwise it's overwhelming to deal with. Bunch them together in a patchset instead of sending them one by one. regards, dan carpenter ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] staging: fbtft: fix unaligned access and txbuf safety issues 2026-06-25 11:42 ` [PATCH] staging: fbtft: fix unaligned access and txbuf safety issues suryasaimadhu 2026-06-25 11:54 ` sashiko-bot 2026-06-25 12:00 ` Dan Carpenter @ 2026-06-25 14:05 ` Andy Shevchenko 2 siblings, 0 replies; 13+ messages in thread From: Andy Shevchenko @ 2026-06-25 14:05 UTC (permalink / raw) To: suryasaimadhu Cc: andy, gregkh, dri-devel, linux-fbdev, linux-staging, linux-kernel On Thu, Jun 25, 2026 at 07:42:15PM +0800, suryasaimadhu wrote: > This patch addresses several pre-existing issues in the fbtft driver: > > 1. define_fbtft_write_reg(): when par->startbyte is set, buf is > advanced by one byte creating a misaligned pointer for 16-bit types. > Use put_unaligned() for register writes and fix the SPI transfer > size from len * (sizeof(data_type) + offset) to > len * sizeof(data_type) + offset. > > 2. fbtft_write_vmem16_bus8() and fb_ra8875 write_vmem16_bus8(): same > unaligned 16-bit stores when txbuf is byte-offset for a start > prefix. Use put_unaligned() for pixel data copies. > > 3. tx_array_size underflow: both vmem helpers subtract 2 from > tx_array_size when a startbyte prefix is used. A small txbuflen > device property causes unsigned underflow and out-of-bounds heap > writes. Fall back to the non-buffered write path when the buffer > is too small. > > 4. fb_ra8875 write_vmem16_bus8(): missing NULL check for > par->txbuf.buf, which remains NULL on big-endian when txbuflen is > 0 because the PAGE_SIZE fallback is little-endian only. Fall back > to direct write when the buffer is missing. > > Also replace empty modifier arguments in define_fbtft_write_reg() with > a no-op macro to fix checkpatch warnings. This looks like v2 of the thing without changelog and addressing the comments that have been given against v1. I'm not even going to review that. Please, consolidate feedback, take your time to study process documentation (Documentation/process/* in the Linux kernel source tree) and try again a bit later. (The fix and report are valuable in general, thanks for doing that.) -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] staging: fbtft: fix unaligned vmem writes when txbuf is byte-offset 2026-06-25 11:02 ` [PATCH] staging: fbtft: fix unaligned vmem writes when txbuf is byte-offset suryasaimadhu 2026-06-25 11:16 ` sashiko-bot @ 2026-06-25 13:20 ` kernel test robot 2026-06-25 13:53 ` kernel test robot 2026-06-25 13:59 ` Andy Shevchenko 3 siblings, 0 replies; 13+ messages in thread From: kernel test robot @ 2026-06-25 13:20 UTC (permalink / raw) To: suryasaimadhu, andy Cc: oe-kbuild-all, gregkh, dri-devel, linux-fbdev, linux-staging, linux-kernel, suryasaimadhu Hi suryasaimadhu, kernel test robot noticed the following build errors: [auto build test ERROR on staging/staging-testing] url: https://github.com/intel-lab-lkp/linux/commits/suryasaimadhu/staging-fbtft-fix-unaligned-vmem-writes-when-txbuf-is-byte-offset/20260625-190423 base: staging/staging-testing patch link: https://lore.kernel.org/r/20260625110237.304435-1-suryasaimadhu369%40gmail.com patch subject: [PATCH] staging: fbtft: fix unaligned vmem writes when txbuf is byte-offset config: sh-allmodconfig (https://download.01.org/0day-ci/archive/20260625/202606252119.rClVa8On-lkp@intel.com/config) compiler: sh4-linux-gcc (GCC) 16.1.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260625/202606252119.rClVa8On-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202606252119.rClVa8On-lkp@intel.com/ All errors (new ones prefixed by >>): drivers/staging/fbtft/fbtft-bus.c: In function 'fbtft_write_vmem16_bus8': >> drivers/staging/fbtft/fbtft-bus.c:157:25: error: implicit declaration of function 'put_unaligned' [-Wimplicit-function-declaration] 157 | put_unaligned(cpu_to_be16(vmem16[i]), &txbuf16[i]); | ^~~~~~~~~~~~~ vim +/put_unaligned +157 drivers/staging/fbtft/fbtft-bus.c 113 114 /***************************************************************************** 115 * 116 * int (*write_vmem)(struct fbtft_par *par); 117 * 118 *****************************************************************************/ 119 120 /* 16 bit pixel over 8-bit databus */ 121 int fbtft_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) 122 { 123 u16 *vmem16; 124 __be16 *txbuf16 = par->txbuf.buf; 125 size_t remain; 126 size_t to_copy; 127 size_t tx_array_size; 128 int i; 129 int ret = 0; 130 size_t startbyte_size = 0; 131 132 remain = len / 2; 133 vmem16 = (u16 *)(par->info->screen_buffer + offset); 134 135 gpiod_set_value(par->gpio.dc, 1); 136 137 /* non buffered write */ 138 if (!par->txbuf.buf) 139 return par->fbtftops.write(par, vmem16, len); 140 141 /* buffered write */ 142 tx_array_size = par->txbuf.len / 2; 143 144 if (par->startbyte) { 145 txbuf16 = par->txbuf.buf + 1; 146 tx_array_size -= 2; 147 *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2; 148 startbyte_size = 1; 149 } 150 151 while (remain) { 152 to_copy = min(tx_array_size, remain); 153 dev_dbg(par->info->device, "to_copy=%zu, remain=%zu\n", 154 to_copy, remain - to_copy); 155 156 for (i = 0; i < to_copy; i++) > 157 put_unaligned(cpu_to_be16(vmem16[i]), &txbuf16[i]); 158 159 vmem16 = vmem16 + to_copy; 160 ret = par->fbtftops.write(par, par->txbuf.buf, 161 startbyte_size + to_copy * 2); 162 if (ret < 0) 163 return ret; 164 remain -= to_copy; 165 } 166 167 return ret; 168 } 169 EXPORT_SYMBOL(fbtft_write_vmem16_bus8); 170 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] staging: fbtft: fix unaligned vmem writes when txbuf is byte-offset 2026-06-25 11:02 ` [PATCH] staging: fbtft: fix unaligned vmem writes when txbuf is byte-offset suryasaimadhu 2026-06-25 11:16 ` sashiko-bot 2026-06-25 13:20 ` [PATCH] staging: fbtft: fix unaligned vmem writes when txbuf is byte-offset kernel test robot @ 2026-06-25 13:53 ` kernel test robot 2026-06-25 13:59 ` Andy Shevchenko 3 siblings, 0 replies; 13+ messages in thread From: kernel test robot @ 2026-06-25 13:53 UTC (permalink / raw) To: suryasaimadhu, andy Cc: llvm, oe-kbuild-all, gregkh, dri-devel, linux-fbdev, linux-staging, linux-kernel, suryasaimadhu Hi suryasaimadhu, kernel test robot noticed the following build errors: [auto build test ERROR on staging/staging-testing] url: https://github.com/intel-lab-lkp/linux/commits/suryasaimadhu/staging-fbtft-fix-unaligned-vmem-writes-when-txbuf-is-byte-offset/20260625-190423 base: staging/staging-testing patch link: https://lore.kernel.org/r/20260625110237.304435-1-suryasaimadhu369%40gmail.com patch subject: [PATCH] staging: fbtft: fix unaligned vmem writes when txbuf is byte-offset config: hexagon-allmodconfig (https://download.01.org/0day-ci/archive/20260625/202606252144.F56jkpaD-lkp@intel.com/config) compiler: clang version 23.0.0git (https://github.com/llvm/llvm-project 6cc609bb250b21b47fc7d394b4019101e9983597) reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260625/202606252144.F56jkpaD-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202606252144.F56jkpaD-lkp@intel.com/ All errors (new ones prefixed by >>): >> drivers/staging/fbtft/fbtft-bus.c:157:4: error: call to undeclared function 'put_unaligned'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration] 157 | put_unaligned(cpu_to_be16(vmem16[i]), &txbuf16[i]); | ^ 1 error generated. vim +/put_unaligned +157 drivers/staging/fbtft/fbtft-bus.c 113 114 /***************************************************************************** 115 * 116 * int (*write_vmem)(struct fbtft_par *par); 117 * 118 *****************************************************************************/ 119 120 /* 16 bit pixel over 8-bit databus */ 121 int fbtft_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len) 122 { 123 u16 *vmem16; 124 __be16 *txbuf16 = par->txbuf.buf; 125 size_t remain; 126 size_t to_copy; 127 size_t tx_array_size; 128 int i; 129 int ret = 0; 130 size_t startbyte_size = 0; 131 132 remain = len / 2; 133 vmem16 = (u16 *)(par->info->screen_buffer + offset); 134 135 gpiod_set_value(par->gpio.dc, 1); 136 137 /* non buffered write */ 138 if (!par->txbuf.buf) 139 return par->fbtftops.write(par, vmem16, len); 140 141 /* buffered write */ 142 tx_array_size = par->txbuf.len / 2; 143 144 if (par->startbyte) { 145 txbuf16 = par->txbuf.buf + 1; 146 tx_array_size -= 2; 147 *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2; 148 startbyte_size = 1; 149 } 150 151 while (remain) { 152 to_copy = min(tx_array_size, remain); 153 dev_dbg(par->info->device, "to_copy=%zu, remain=%zu\n", 154 to_copy, remain - to_copy); 155 156 for (i = 0; i < to_copy; i++) > 157 put_unaligned(cpu_to_be16(vmem16[i]), &txbuf16[i]); 158 159 vmem16 = vmem16 + to_copy; 160 ret = par->fbtftops.write(par, par->txbuf.buf, 161 startbyte_size + to_copy * 2); 162 if (ret < 0) 163 return ret; 164 remain -= to_copy; 165 } 166 167 return ret; 168 } 169 EXPORT_SYMBOL(fbtft_write_vmem16_bus8); 170 -- 0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests/wiki ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] staging: fbtft: fix unaligned vmem writes when txbuf is byte-offset 2026-06-25 11:02 ` [PATCH] staging: fbtft: fix unaligned vmem writes when txbuf is byte-offset suryasaimadhu ` (2 preceding siblings ...) 2026-06-25 13:53 ` kernel test robot @ 2026-06-25 13:59 ` Andy Shevchenko 3 siblings, 0 replies; 13+ messages in thread From: Andy Shevchenko @ 2026-06-25 13:59 UTC (permalink / raw) To: suryasaimadhu Cc: andy, gregkh, dri-devel, linux-fbdev, linux-staging, linux-kernel On Thu, Jun 25, 2026 at 07:02:37PM +0800, suryasaimadhu wrote: > fbtft_write_vmem16_bus8() and fb_ra8875's write_vmem16_bus8() offset > txbuf16 by one byte for a command/start prefix, then store 16-bit pixel > data via txbuf16[i]. On strict-alignment architectures this can fault > the same way as the write_reg path fixed in the previous patch. .write_reg() Can you provide a real world example of the failure? > Use put_unaligned() for these stores. Sounds like a fix without Fixes tag. > Signed-off-by: suryasaimadhu <suryasaimadhu369@gmail.com> Use your name in accordance with your official documents. ... > +++ b/drivers/staging/fbtft/fb_ra8875.c > @@ -10,6 +10,7 @@ > #include <linux/delay.h> > You should move this blank line to be... > #include <linux/gpio/consumer.h> > +#include <linux/unaligned.h> ...here. > #include "fbtft.h" ... > #define DRVNAME "fb_ra8875" Are other drivers also being affected? ... > +++ b/drivers/staging/fbtft/fbtft-bus.c Also needs linux/unaligned.h. > + put_unaligned(cpu_to_be16(vmem16[i]), &txbuf16[i]); -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] staging: fbtft: fix unaligned access and buffer size when startbyte is used 2026-06-25 10:30 [PATCH] staging: fbtft: fix unaligned access and buffer size when startbyte is used suryasaimadhu 2026-06-25 10:42 ` sashiko-bot @ 2026-06-25 14:08 ` Andy Shevchenko 2026-06-26 6:48 ` David Laight 2 siblings, 0 replies; 13+ messages in thread From: Andy Shevchenko @ 2026-06-25 14:08 UTC (permalink / raw) To: suryasaimadhu Cc: andy, gregkh, dri-devel, linux-fbdev, linux-staging, linux-kernel On Thu, Jun 25, 2026 at 06:30:41PM +0800, suryasaimadhu wrote: > When par->startbyte is non-zero, buf is advanced by one byte creating > an unaligned pointer for 16-bit types (u16, __be16). Dereferencing this > unaligned pointer can cause a kernel panic on strict-alignment > architectures. > > Fix by using put_unaligned() instead of direct pointer dereference. > > Also fix incorrect buffer size calculation in fbtft_write_buf_dc() call: > len * (sizeof(data_type) + offset) /* wrong: multiplies offset by len */ > len * sizeof(data_type) + offset /* correct: one startbyte + > len items */ Same comments as per your other patch contributions. Make it cleaner next time. So it seem a v2 should be a mini-series with fixes for different issues/drivers/et cetera. -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH] staging: fbtft: fix unaligned access and buffer size when startbyte is used 2026-06-25 10:30 [PATCH] staging: fbtft: fix unaligned access and buffer size when startbyte is used suryasaimadhu 2026-06-25 10:42 ` sashiko-bot 2026-06-25 14:08 ` [PATCH] staging: fbtft: fix unaligned access and buffer size when startbyte is used Andy Shevchenko @ 2026-06-26 6:48 ` David Laight 2 siblings, 0 replies; 13+ messages in thread From: David Laight @ 2026-06-26 6:48 UTC (permalink / raw) To: suryasaimadhu Cc: andy, gregkh, dri-devel, linux-fbdev, linux-staging, linux-kernel On Thu, 25 Jun 2026 18:30:41 +0800 suryasaimadhu <suryasaimadhu369@gmail.com> wrote: > When par->startbyte is non-zero, buf is advanced by one byte creating > an unaligned pointer for 16-bit types (u16, __be16). Dereferencing this > unaligned pointer can cause a kernel panic on strict-alignment > architectures. > > Fix by using put_unaligned() instead of direct pointer dereference. > > Also fix incorrect buffer size calculation in fbtft_write_buf_dc() call: > len * (sizeof(data_type) + offset) /* wrong: multiplies offset by len */ > len * sizeof(data_type) + offset /* correct: one startbyte + > len items */ That should probably be a separate patch. > > Signed-off-by: suryasaimadhu <suryasaimadhu369@gmail.com> > --- > drivers/staging/fbtft/fbtft-bus.c | 13 ++++++++----- > 1 file changed, 8 insertions(+), 5 deletions(-) > > diff --git a/drivers/staging/fbtft/fbtft-bus.c b/drivers/staging/fbtft/fbtft-bus.c > index 2169f8d1d..cfcf4d7e7 100644 > --- a/drivers/staging/fbtft/fbtft-bus.c > +++ b/drivers/staging/fbtft/fbtft-bus.c > @@ -4,6 +4,7 @@ > #include <linux/gpio/consumer.h> > #include <linux/spi/spi.h> > #include "fbtft.h" > +#include <linux/unaligned.h> > > /***************************************************************************** > * > @@ -40,7 +41,7 @@ void func(struct fbtft_par *par, int len, ...) \ I'd consider changing that to: func(struct fbtft_par *par, int len, u8 cmd, ...) and probably reducing len by one. It makes it more obvious that the first parameter is mandatory and the ... is associated data. David > offset = 1; \ > } \ > \ > - *buf = modifier((data_type)va_arg(args, unsigned int)); \ > + put_unaligned(modifier((data_type)va_arg(args, unsigned int)), buf); \ > ret = fbtft_write_buf_dc(par, par->buf, sizeof(data_type) + offset, \ > 0); \ > if (ret < 0) \ > @@ -52,11 +53,13 @@ void func(struct fbtft_par *par, int len, ...) \ > \ > if (len) { \ > i = len; \ > - while (i--) \ > - *buf++ = modifier((data_type)va_arg(args, \ > - unsigned int)); \ > + while (i--) { \ > + put_unaligned(modifier((data_type)va_arg(args, \ > + unsigned int)), buf); \ > + buf++; \ > + } \ > fbtft_write_buf_dc(par, par->buf, \ > - len * (sizeof(data_type) + offset), 1); \ > + len * sizeof(data_type) + offset, 1); \ > } \ > out: \ > va_end(args); \ ^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2026-06-26 6:48 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-06-25 10:30 [PATCH] staging: fbtft: fix unaligned access and buffer size when startbyte is used suryasaimadhu 2026-06-25 10:42 ` sashiko-bot 2026-06-25 11:02 ` [PATCH] staging: fbtft: fix unaligned vmem writes when txbuf is byte-offset suryasaimadhu 2026-06-25 11:16 ` sashiko-bot 2026-06-25 11:42 ` [PATCH] staging: fbtft: fix unaligned access and txbuf safety issues suryasaimadhu 2026-06-25 11:54 ` sashiko-bot 2026-06-25 12:00 ` Dan Carpenter 2026-06-25 14:05 ` Andy Shevchenko 2026-06-25 13:20 ` [PATCH] staging: fbtft: fix unaligned vmem writes when txbuf is byte-offset kernel test robot 2026-06-25 13:53 ` kernel test robot 2026-06-25 13:59 ` Andy Shevchenko 2026-06-25 14:08 ` [PATCH] staging: fbtft: fix unaligned access and buffer size when startbyte is used Andy Shevchenko 2026-06-26 6:48 ` David Laight
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.