Re: [PATCH] staging: fbtft: fix unaligned access and buffer size when startbyte is used

David Laight <[email protected]>
Newsgroups org.kernel.vger.linux-fbdev,dev.linux.lists.linux-staging,org.freedesktop.lists.dri-devel,org.kernel.vger.linux-kernel
Message-ID <20260626074810.433c4006@pumpkin>
On Thu, 25 Jun 2026 18:30:41 +0800
suryasaimadhu <[email protected]> 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 <[email protected]>
> ---
>  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);                                                         \
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.