mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] Input: raydium_i2c_ts - validate report parameters
@ 2026-09-27 11:44 Pooyan Azad
  2026-09-27 17:30 ` Muhammad Bilal
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Pooyan Azad @ 2026-09-27 11:44 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Uwe Kleine-König, Muhammad Bilal, Herlangga Maulani,
	linux-input, linux-kernel

The controller supplies packet and per-contact sizes used to allocate and
parse touch reports. The driver trusts these values without validation.

A packet size smaller than the two-byte checksum makes report_size wrap,
allowing the IRQ handler to read beyond the report buffer. A zero or
undersized contact size can cause a divide by zero or make the contact
parser read beyond a record.

Validate both sizes before publishing them, and reject reports that
describe more contacts than the input device has slots.

Allocate the report buffer once valid main firmware information is
available, and resize it if a firmware update changes the packet size.
This also handles devices that probe in bootloader mode, where the packet
size is not known yet.

Finally, return main firmware query failures from initialization so probe
and firmware update do not continue with invalid report parameters. Keep
bootloader HWID query failures non-fatal so the recovery interface remains
available.

Fixes: 48a2b783483b ("Input: add Raydium I2C touchscreen driver")
Link: https://lore.kernel.org/all/20260728135127.48971-1-meatuni001@gmail.com/
Cc: stable@vger.kernel.org
Signed-off-by: Pooyan Azad <pooyan.azadparvar@gmail.com>
---
This partially overlaps Muhammad Bilal's earlier patch linked above. That
patch propagates both main and bootloader query errors. This version keeps
bootloader HWID errors non-fatal so recovery remains available, and moves
report-buffer allocation into the main query path so size changes can be
handled safely.

Compile-tested with:

  make O=/tmp/raydium-build W=1 -j$(nproc) \
    drivers/input/touchscreen/raydium_i2c_ts.o

 drivers/input/touchscreen/raydium_i2c_ts.c | 64 +++++++++++++---------
 1 file changed, 39 insertions(+), 25 deletions(-)

diff --git a/drivers/input/touchscreen/raydium_i2c_ts.c b/drivers/input/touchscreen/raydium_i2c_ts.c
index 0256055abcef..1d7f53d0b9fe 100644
--- a/drivers/input/touchscreen/raydium_i2c_ts.c
+++ b/drivers/input/touchscreen/raydium_i2c_ts.c
@@ -64,6 +64,7 @@
 #define RM_CONTACT_PRESSURE_POS	5
 #define RM_CONTACT_WIDTH_X_POS	6
 #define RM_CONTACT_WIDTH_Y_POS	7
+#define RM_MIN_CONTACT_SIZE	(RM_CONTACT_WIDTH_Y_POS + 1)
 
 /* Bootloader relative info */
 #define RM_BL_WRT_CMD_SIZE	3	/* bl flash wrt cmd size */
@@ -331,7 +332,10 @@ static int raydium_i2c_query_ts_info(struct raydium_data *ts)
 {
 	struct i2c_client *client = ts->client;
 	struct raydium_data_info data_info;
+	struct raydium_info info;
 	__le32 query_bank_addr;
+	u8 *report_data;
+	u8 report_size;
 
 	int error, retry_cnt;
 
@@ -341,26 +345,22 @@ static int raydium_i2c_query_ts_info(struct raydium_data *ts)
 		if (error)
 			continue;
 
-		/*
-		 * Warn user if we already allocated memory for reports and
-		 * then the size changed (due to firmware update?) and keep
-		 * old size instead.
-		 */
-		if (ts->report_data && ts->pkg_size != data_info.pkg_size) {
-			dev_warn(&client->dev,
-				 "report size changes, was: %d, new: %d\n",
-				 ts->pkg_size, data_info.pkg_size);
-		} else {
-			ts->pkg_size = data_info.pkg_size;
-			ts->report_size = ts->pkg_size - RM_PACKET_CRC_SIZE;
+		if (data_info.pkg_size < RM_PACKET_CRC_SIZE) {
+			dev_err(&client->dev,
+				"invalid report sizes: packet=%u contact=%u\n",
+				data_info.pkg_size, data_info.tp_info_size);
+			return -EINVAL;
 		}
 
-		ts->contact_size = data_info.tp_info_size;
-		ts->data_bank_addr = le32_to_cpu(data_info.data_bank_addr);
-
-		dev_dbg(&client->dev,
-			"data_bank_addr: %#08x, report_size: %d, contact_size: %d\n",
-			ts->data_bank_addr, ts->report_size, ts->contact_size);
+		report_size = data_info.pkg_size - RM_PACKET_CRC_SIZE;
+		if (data_info.tp_info_size < RM_MIN_CONTACT_SIZE ||
+		    data_info.tp_info_size > report_size ||
+		    report_size / data_info.tp_info_size > RM_MAX_TOUCH_NUM) {
+			dev_err(&client->dev,
+				"invalid report sizes: packet=%u contact=%u\n",
+				data_info.pkg_size, data_info.tp_info_size);
+			return -EINVAL;
+		}
 
 		error = raydium_i2c_read(client, RM_CMD_QUERY_BANK,
 					 &query_bank_addr,
@@ -369,10 +369,29 @@ static int raydium_i2c_query_ts_info(struct raydium_data *ts)
 			continue;
 
 		error = raydium_i2c_read(client, le32_to_cpu(query_bank_addr),
-					 &ts->info, sizeof(ts->info));
+					 &info, sizeof(info));
 		if (error)
 			continue;
 
+		if (!ts->report_data || ts->pkg_size != data_info.pkg_size) {
+			report_data = devm_krealloc(&client->dev, ts->report_data,
+						    data_info.pkg_size, GFP_KERNEL);
+			if (!report_data)
+				return -ENOMEM;
+
+			ts->report_data = report_data;
+		}
+
+		ts->pkg_size = data_info.pkg_size;
+		ts->report_size = report_size;
+		ts->contact_size = data_info.tp_info_size;
+		ts->data_bank_addr = le32_to_cpu(data_info.data_bank_addr);
+		ts->info = info;
+
+		dev_dbg(&client->dev,
+			"data_bank_addr: %#08x, report_size: %d, contact_size: %d\n",
+			ts->data_bank_addr, ts->report_size, ts->contact_size);
+
 		return 0;
 	}
 
@@ -428,7 +447,7 @@ static int raydium_i2c_initialize(struct raydium_data *ts)
 	if (ts->boot_mode == RAYDIUM_TS_BLDR)
 		raydium_i2c_query_ts_bootloader_info(ts);
 	else
-		raydium_i2c_query_ts_info(ts);
+		error = raydium_i2c_query_ts_info(ts);
 
 	return error;
 }
@@ -1116,11 +1135,6 @@ static int raydium_i2c_probe(struct i2c_client *client)
 		return error;
 	}
 
-	ts->report_data = devm_kmalloc(&client->dev,
-				       ts->pkg_size, GFP_KERNEL);
-	if (!ts->report_data)
-		return -ENOMEM;
-
 	ts->input = devm_input_allocate_device(&client->dev);
 	if (!ts->input) {
 		dev_err(&client->dev, "Failed to allocate input device\n");
-- 
2.43.0

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Input: raydium_i2c_ts - validate report parameters
  2026-09-27 11:44 [PATCH] Input: raydium_i2c_ts - validate report parameters Pooyan Azad
@ 2026-09-27 17:30 ` Muhammad Bilal
  2026-09-27 17:58   ` Pooyan Azadparvar
  2026-09-28  2:38 ` Dmitry Torokhov
  2026-09-28 16:26 ` [PATCH v2 0/3] Input: raydium_i2c_ts report handling fixes Pooyan Azad
  2 siblings, 1 reply; 9+ messages in thread
From: Muhammad Bilal @ 2026-09-27 17:30 UTC (permalink / raw)
  To: Pooyan Azad
  Cc: Dmitry Torokhov, Uwe Kleine-König, Herlangga Maulani,
	linux-input, linux-kernel

Hi Pooyan,

Nice fix, the size validation and resize-on-update handling both look
correct. Two quick questions:

1.  Does the IRQ handler independently clamp the per-packet touch
count against RM_MAX_TOUCH_NUM, or does it trust the count once these
static sizes pass?

2.  raydium_i2c_query_ts_info() can rerun after a firmware update. Is
the devm_krealloc() of ts->report_data protected from a racing IRQ
handler?

Reviewed-by: Muhammad Bilal <meatuni001@gmail.com>

Thanks,
Muhammad


On Sun, Sep 27, 2026 at 4:44 PM Pooyan Azad <pooyan.azadparvar@gmail.com> wrote:
>
> The controller supplies packet and per-contact sizes used to allocate and
> parse touch reports. The driver trusts these values without validation.
>
> A packet size smaller than the two-byte checksum makes report_size wrap,
> allowing the IRQ handler to read beyond the report buffer. A zero or
> undersized contact size can cause a divide by zero or make the contact
> parser read beyond a record.
>
> Validate both sizes before publishing them, and reject reports that
> describe more contacts than the input device has slots.
>
> Allocate the report buffer once valid main firmware information is
> available, and resize it if a firmware update changes the packet size.
> This also handles devices that probe in bootloader mode, where the packet
> size is not known yet.
>
> Finally, return main firmware query failures from initialization so probe
> and firmware update do not continue with invalid report parameters. Keep
> bootloader HWID query failures non-fatal so the recovery interface remains
> available.
>
> Fixes: 48a2b783483b ("Input: add Raydium I2C touchscreen driver")
> Link: https://lore.kernel.org/all/20260728135127.48971-1-meatuni001@gmail.com/
> Cc: stable@vger.kernel.org
> Signed-off-by: Pooyan Azad <pooyan.azadparvar@gmail.com>
> ---
> This partially overlaps Muhammad Bilal's earlier patch linked above. That
> patch propagates both main and bootloader query errors. This version keeps
> bootloader HWID errors non-fatal so recovery remains available, and moves
> report-buffer allocation into the main query path so size changes can be
> handled safely.
>
> Compile-tested with:
>
>   make O=/tmp/raydium-build W=1 -j$(nproc) \
>     drivers/input/touchscreen/raydium_i2c_ts.o
>
>  drivers/input/touchscreen/raydium_i2c_ts.c | 64 +++++++++++++---------
>  1 file changed, 39 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/input/touchscreen/raydium_i2c_ts.c b/drivers/input/touchscreen/raydium_i2c_ts.c
> index 0256055abcef..1d7f53d0b9fe 100644
> --- a/drivers/input/touchscreen/raydium_i2c_ts.c
> +++ b/drivers/input/touchscreen/raydium_i2c_ts.c
> @@ -64,6 +64,7 @@
>  #define RM_CONTACT_PRESSURE_POS        5
>  #define RM_CONTACT_WIDTH_X_POS 6
>  #define RM_CONTACT_WIDTH_Y_POS 7
> +#define RM_MIN_CONTACT_SIZE    (RM_CONTACT_WIDTH_Y_POS + 1)
>
>  /* Bootloader relative info */
>  #define RM_BL_WRT_CMD_SIZE     3       /* bl flash wrt cmd size */
> @@ -331,7 +332,10 @@ static int raydium_i2c_query_ts_info(struct raydium_data *ts)
>  {
>         struct i2c_client *client = ts->client;
>         struct raydium_data_info data_info;
> +       struct raydium_info info;
>         __le32 query_bank_addr;
> +       u8 *report_data;
> +       u8 report_size;
>
>         int error, retry_cnt;
>
> @@ -341,26 +345,22 @@ static int raydium_i2c_query_ts_info(struct raydium_data *ts)
>                 if (error)
>                         continue;
>
> -               /*
> -                * Warn user if we already allocated memory for reports and
> -                * then the size changed (due to firmware update?) and keep
> -                * old size instead.
> -                */
> -               if (ts->report_data && ts->pkg_size != data_info.pkg_size) {
> -                       dev_warn(&client->dev,
> -                                "report size changes, was: %d, new: %d\n",
> -                                ts->pkg_size, data_info.pkg_size);
> -               } else {
> -                       ts->pkg_size = data_info.pkg_size;
> -                       ts->report_size = ts->pkg_size - RM_PACKET_CRC_SIZE;
> +               if (data_info.pkg_size < RM_PACKET_CRC_SIZE) {
> +                       dev_err(&client->dev,
> +                               "invalid report sizes: packet=%u contact=%u\n",
> +                               data_info.pkg_size, data_info.tp_info_size);
> +                       return -EINVAL;
>                 }
>
> -               ts->contact_size = data_info.tp_info_size;
> -               ts->data_bank_addr = le32_to_cpu(data_info.data_bank_addr);
> -
> -               dev_dbg(&client->dev,
> -                       "data_bank_addr: %#08x, report_size: %d, contact_size: %d\n",
> -                       ts->data_bank_addr, ts->report_size, ts->contact_size);
> +               report_size = data_info.pkg_size - RM_PACKET_CRC_SIZE;
> +               if (data_info.tp_info_size < RM_MIN_CONTACT_SIZE ||
> +                   data_info.tp_info_size > report_size ||
> +                   report_size / data_info.tp_info_size > RM_MAX_TOUCH_NUM) {
> +                       dev_err(&client->dev,
> +                               "invalid report sizes: packet=%u contact=%u\n",
> +                               data_info.pkg_size, data_info.tp_info_size);
> +                       return -EINVAL;
> +               }
>
>                 error = raydium_i2c_read(client, RM_CMD_QUERY_BANK,
>                                          &query_bank_addr,
> @@ -369,10 +369,29 @@ static int raydium_i2c_query_ts_info(struct raydium_data *ts)
>                         continue;
>
>                 error = raydium_i2c_read(client, le32_to_cpu(query_bank_addr),
> -                                        &ts->info, sizeof(ts->info));
> +                                        &info, sizeof(info));
>                 if (error)
>                         continue;
>
> +               if (!ts->report_data || ts->pkg_size != data_info.pkg_size) {
> +                       report_data = devm_krealloc(&client->dev, ts->report_data,
> +                                                   data_info.pkg_size, GFP_KERNEL);
> +                       if (!report_data)
> +                               return -ENOMEM;
> +
> +                       ts->report_data = report_data;
> +               }
> +
> +               ts->pkg_size = data_info.pkg_size;
> +               ts->report_size = report_size;
> +               ts->contact_size = data_info.tp_info_size;
> +               ts->data_bank_addr = le32_to_cpu(data_info.data_bank_addr);
> +               ts->info = info;
> +
> +               dev_dbg(&client->dev,
> +                       "data_bank_addr: %#08x, report_size: %d, contact_size: %d\n",
> +                       ts->data_bank_addr, ts->report_size, ts->contact_size);
> +
>                 return 0;
>         }
>
> @@ -428,7 +447,7 @@ static int raydium_i2c_initialize(struct raydium_data *ts)
>         if (ts->boot_mode == RAYDIUM_TS_BLDR)
>                 raydium_i2c_query_ts_bootloader_info(ts);
>         else
> -               raydium_i2c_query_ts_info(ts);
> +               error = raydium_i2c_query_ts_info(ts);
>
>         return error;
>  }
> @@ -1116,11 +1135,6 @@ static int raydium_i2c_probe(struct i2c_client *client)
>                 return error;
>         }
>
> -       ts->report_data = devm_kmalloc(&client->dev,
> -                                      ts->pkg_size, GFP_KERNEL);
> -       if (!ts->report_data)
> -               return -ENOMEM;
> -
>         ts->input = devm_input_allocate_device(&client->dev);
>         if (!ts->input) {
>                 dev_err(&client->dev, "Failed to allocate input device\n");
> --
> 2.43.0

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Input: raydium_i2c_ts - validate report parameters
  2026-09-27 17:30 ` Muhammad Bilal
@ 2026-09-27 17:58   ` Pooyan Azadparvar
  0 siblings, 0 replies; 9+ messages in thread
From: Pooyan Azadparvar @ 2026-09-27 17:58 UTC (permalink / raw)
  To: Muhammad Bilal
  Cc: Dmitry Torokhov, Uwe Kleine-König, Herlangga Maulani,
	linux-input, linux-kernel

Hi Muhammad,

Thanks for the review.

There is no per-packet touch count in the IRQ path; it uses
report_size / contact_size. Those values are validated by the query,
including the RM_MAX_TOUCH_NUM limit.

The resize is safe too: query happens before requesting the IRQ at
probe, or with the IRQ disabled during firmware update/resume.
disable_irq() waits for a running threaded handler to finish.

Thanks,
Pooyan

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Input: raydium_i2c_ts - validate report parameters
  2026-09-27 11:44 [PATCH] Input: raydium_i2c_ts - validate report parameters Pooyan Azad
  2026-09-27 17:30 ` Muhammad Bilal
@ 2026-09-28  2:38 ` Dmitry Torokhov
  2026-09-28  6:04   ` Pooyan Azadparvar
  2026-09-28 16:26 ` [PATCH v2 0/3] Input: raydium_i2c_ts report handling fixes Pooyan Azad
  2 siblings, 1 reply; 9+ messages in thread
From: Dmitry Torokhov @ 2026-09-28  2:38 UTC (permalink / raw)
  To: Pooyan Azad
  Cc: Uwe Kleine-König, Muhammad Bilal, Herlangga Maulani,
	linux-input, linux-kernel

Hi Pooyan,

On Sun, Sep 27, 2026 at 01:44:25PM +0200, Pooyan Azad wrote:
> The controller supplies packet and per-contact sizes used to allocate and
> parse touch reports. The driver trusts these values without validation.
> 
> A packet size smaller than the two-byte checksum makes report_size wrap,
> allowing the IRQ handler to read beyond the report buffer. A zero or
> undersized contact size can cause a divide by zero or make the contact
> parser read beyond a record.
> 
> Validate both sizes before publishing them, and reject reports that
> describe more contacts than the input device has slots.
> 
> Allocate the report buffer once valid main firmware information is
> available, and resize it if a firmware update changes the packet size.
> This also handles devices that probe in bootloader mode, where the packet
> size is not known yet.
> 
> Finally, return main firmware query failures from initialization so probe
> and firmware update do not continue with invalid report parameters. Keep
> bootloader HWID query failures non-fatal so the recovery interface remains
> available.

It looks like there ate 3 somewhat independent changes. Please split the
incoming data validation from the buffer management and handling
bootloader query failures. I think only the data validation needs to go
into stable, the rest are regular behavior improvements.

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] Input: raydium_i2c_ts - validate report parameters
  2026-09-28  2:38 ` Dmitry Torokhov
@ 2026-09-28  6:04   ` Pooyan Azadparvar
  0 siblings, 0 replies; 9+ messages in thread
From: Pooyan Azadparvar @ 2026-09-28  6:04 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Uwe Kleine-König, Muhammad Bilal, Herlangga Maulani,
	linux-input, linux-kernel

Thanks Dmitry,

Sure, I'll split these up in v2 and keep the validation fix separate for stable.

Thanks,
Pooyan


On Mon, Sep 28, 2026 at 4:38 AM Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
>
> Hi Pooyan,
>
> On Sun, Sep 27, 2026 at 01:44:25PM +0200, Pooyan Azad wrote:
> > The controller supplies packet and per-contact sizes used to allocate and
> > parse touch reports. The driver trusts these values without validation.
> >
> > A packet size smaller than the two-byte checksum makes report_size wrap,
> > allowing the IRQ handler to read beyond the report buffer. A zero or
> > undersized contact size can cause a divide by zero or make the contact
> > parser read beyond a record.
> >
> > Validate both sizes before publishing them, and reject reports that
> > describe more contacts than the input device has slots.
> >
> > Allocate the report buffer once valid main firmware information is
> > available, and resize it if a firmware update changes the packet size.
> > This also handles devices that probe in bootloader mode, where the packet
> > size is not known yet.
> >
> > Finally, return main firmware query failures from initialization so probe
> > and firmware update do not continue with invalid report parameters. Keep
> > bootloader HWID query failures non-fatal so the recovery interface remains
> > available.
>
> It looks like there ate 3 somewhat independent changes. Please split the
> incoming data validation from the buffer management and handling
> bootloader query failures. I think only the data validation needs to go
> into stable, the rest are regular behavior improvements.
>
> Thanks.
>
> --
> Dmitry

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 0/3] Input: raydium_i2c_ts report handling fixes
  2026-09-27 11:44 [PATCH] Input: raydium_i2c_ts - validate report parameters Pooyan Azad
  2026-09-27 17:30 ` Muhammad Bilal
  2026-09-28  2:38 ` Dmitry Torokhov
@ 2026-09-28 16:26 ` Pooyan Azad
  2026-09-28 16:26   ` [PATCH v2 1/3] Input: raydium_i2c_ts - validate report parameters Pooyan Azad
                     ` (2 more replies)
  2 siblings, 3 replies; 9+ messages in thread
From: Pooyan Azad @ 2026-09-28 16:26 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Uwe Kleine-König, Muhammad Bilal, Herlangga Maulani,
	Rob Herring, Jeffrey Lin, linux-input, linux-kernel

Hi Dmitry,

This is v2 of the Raydium report parameter patch, split as requested.

Patch 1 validates the packet and contact sizes supplied by the controller.
It also propagates main firmware query errors because otherwise a validation
failure would be ignored by initialization. This is the only patch marked
for stable.

Patch 2 resizes an existing report buffer when a firmware update changes the
packet size. Patch 3 moves the initial allocation to the main firmware query
so devices can remain usable for recovery when they probe in bootloader mode.

Changes in v2:
- Split validation, buffer resizing, and bootloader-mode allocation handling
  into separate patches.
- Mark only the validation fix for stable.
- Rebase onto v7.3-rc5.

The series was compile-tested with:

  make O=/tmp/raydium-build W=1 -j$(nproc) \
       drivers/input/touchscreen/raydium_i2c_ts.o

No runtime testing with a Raydium controller was performed.

Thanks,
Pooyan

Pooyan Azad (3):
  Input: raydium_i2c_ts - validate report parameters
  Input: raydium_i2c_ts - resize report buffer after firmware update
  Input: raydium_i2c_ts - defer report buffer allocation

 drivers/input/touchscreen/raydium_i2c_ts.c | 64 +++++++++++++---------
 1 file changed, 39 insertions(+), 25 deletions(-)

-- 
2.43.0

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 1/3] Input: raydium_i2c_ts - validate report parameters
  2026-09-28 16:26 ` [PATCH v2 0/3] Input: raydium_i2c_ts report handling fixes Pooyan Azad
@ 2026-09-28 16:26   ` Pooyan Azad
  2026-09-28 16:26   ` [PATCH v2 2/3] Input: raydium_i2c_ts - resize report buffer after firmware update Pooyan Azad
  2026-09-28 16:26   ` [PATCH v2 3/3] Input: raydium_i2c_ts - defer report buffer allocation Pooyan Azad
  2 siblings, 0 replies; 9+ messages in thread
From: Pooyan Azad @ 2026-09-28 16:26 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Uwe Kleine-König, Muhammad Bilal, Herlangga Maulani,
	Rob Herring, Jeffrey Lin, linux-input, linux-kernel

The controller supplies packet and per-contact sizes used to allocate and
parse touch reports. The driver trusts these values without validation.

A packet size smaller than the two-byte checksum makes report_size wrap,
allowing the IRQ handler to read beyond the report buffer. A zero or
undersized contact size can cause a divide by zero or make the contact
parser read beyond a record.

Validate both sizes before publishing them, and reject reports that
describe more contacts than the input device has slots. Return main
firmware query errors from initialization as well; otherwise rejecting
invalid parameters would not stop probe or firmware update.

Fixes: 48a2b783483b ("Input: add Raydium I2C touchscreen driver")
Link: https://lore.kernel.org/r/20260728135127.48971-1-meatuni001@gmail.com/
Link: https://lore.kernel.org/r/20260927114425.442803-1-pooyan.azadparvar@gmail.com/
Cc: stable@vger.kernel.org
Reviewed-by: Muhammad Bilal <meatuni001@gmail.com>
Signed-off-by: Pooyan Azad <pooyan.azadparvar@gmail.com>
---
 drivers/input/touchscreen/raydium_i2c_ts.c | 23 ++++++++++++++++++++--
 1 file changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/input/touchscreen/raydium_i2c_ts.c b/drivers/input/touchscreen/raydium_i2c_ts.c
index 0256055abcef..03ea0ae62999 100644
--- a/drivers/input/touchscreen/raydium_i2c_ts.c
+++ b/drivers/input/touchscreen/raydium_i2c_ts.c
@@ -64,6 +64,7 @@
 #define RM_CONTACT_PRESSURE_POS	5
 #define RM_CONTACT_WIDTH_X_POS	6
 #define RM_CONTACT_WIDTH_Y_POS	7
+#define RM_MIN_CONTACT_SIZE	(RM_CONTACT_WIDTH_Y_POS + 1)
 
 /* Bootloader relative info */
 #define RM_BL_WRT_CMD_SIZE	3	/* bl flash wrt cmd size */
@@ -332,6 +333,7 @@ static int raydium_i2c_query_ts_info(struct raydium_data *ts)
 	struct i2c_client *client = ts->client;
 	struct raydium_data_info data_info;
 	__le32 query_bank_addr;
+	u8 report_size;
 
 	int error, retry_cnt;
 
@@ -341,6 +343,23 @@ static int raydium_i2c_query_ts_info(struct raydium_data *ts)
 		if (error)
 			continue;
 
+		if (data_info.pkg_size < RM_PACKET_CRC_SIZE) {
+			dev_err(&client->dev,
+				"invalid report sizes: packet=%u contact=%u\n",
+				data_info.pkg_size, data_info.tp_info_size);
+			return -EINVAL;
+		}
+
+		report_size = data_info.pkg_size - RM_PACKET_CRC_SIZE;
+		if (data_info.tp_info_size < RM_MIN_CONTACT_SIZE ||
+		    data_info.tp_info_size > report_size ||
+		    report_size / data_info.tp_info_size > RM_MAX_TOUCH_NUM) {
+			dev_err(&client->dev,
+				"invalid report sizes: packet=%u contact=%u\n",
+				data_info.pkg_size, data_info.tp_info_size);
+			return -EINVAL;
+		}
+
 		/*
 		 * Warn user if we already allocated memory for reports and
 		 * then the size changed (due to firmware update?) and keep
@@ -352,7 +371,7 @@ static int raydium_i2c_query_ts_info(struct raydium_data *ts)
 				 ts->pkg_size, data_info.pkg_size);
 		} else {
 			ts->pkg_size = data_info.pkg_size;
-			ts->report_size = ts->pkg_size - RM_PACKET_CRC_SIZE;
+			ts->report_size = report_size;
 		}
 
 		ts->contact_size = data_info.tp_info_size;
@@ -428,7 +447,7 @@ static int raydium_i2c_initialize(struct raydium_data *ts)
 	if (ts->boot_mode == RAYDIUM_TS_BLDR)
 		raydium_i2c_query_ts_bootloader_info(ts);
 	else
-		raydium_i2c_query_ts_info(ts);
+		error = raydium_i2c_query_ts_info(ts);
 
 	return error;
 }
-- 
2.43.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 2/3] Input: raydium_i2c_ts - resize report buffer after firmware update
  2026-09-28 16:26 ` [PATCH v2 0/3] Input: raydium_i2c_ts report handling fixes Pooyan Azad
  2026-09-28 16:26   ` [PATCH v2 1/3] Input: raydium_i2c_ts - validate report parameters Pooyan Azad
@ 2026-09-28 16:26   ` Pooyan Azad
  2026-09-28 16:26   ` [PATCH v2 3/3] Input: raydium_i2c_ts - defer report buffer allocation Pooyan Azad
  2 siblings, 0 replies; 9+ messages in thread
From: Pooyan Azad @ 2026-09-28 16:26 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Uwe Kleine-König, Muhammad Bilal, Herlangga Maulani,
	Rob Herring, Jeffrey Lin, linux-input, linux-kernel

A firmware update can change the packet size. The driver currently warns
and keeps the old report buffer in that case, while still updating other
report parameters. This leaves the buffer and parser state inconsistent.

Resize an existing report buffer after all device information has been
read successfully. Keep the new parameters local until the resize
succeeds so an error leaves the previous configuration intact.

Link: https://lore.kernel.org/r/20260927114425.442803-1-pooyan.azadparvar@gmail.com/
Reviewed-by: Muhammad Bilal <meatuni001@gmail.com>
Signed-off-by: Pooyan Azad <pooyan.azadparvar@gmail.com>
---
 drivers/input/touchscreen/raydium_i2c_ts.c | 44 +++++++++++-----------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/drivers/input/touchscreen/raydium_i2c_ts.c b/drivers/input/touchscreen/raydium_i2c_ts.c
index 03ea0ae62999..00990c61010f 100644
--- a/drivers/input/touchscreen/raydium_i2c_ts.c
+++ b/drivers/input/touchscreen/raydium_i2c_ts.c
@@ -332,7 +332,9 @@ static int raydium_i2c_query_ts_info(struct raydium_data *ts)
 {
 	struct i2c_client *client = ts->client;
 	struct raydium_data_info data_info;
+	struct raydium_info info;
 	__le32 query_bank_addr;
+	u8 *report_data;
 	u8 report_size;
 
 	int error, retry_cnt;
@@ -360,27 +362,6 @@ static int raydium_i2c_query_ts_info(struct raydium_data *ts)
 			return -EINVAL;
 		}
 
-		/*
-		 * Warn user if we already allocated memory for reports and
-		 * then the size changed (due to firmware update?) and keep
-		 * old size instead.
-		 */
-		if (ts->report_data && ts->pkg_size != data_info.pkg_size) {
-			dev_warn(&client->dev,
-				 "report size changes, was: %d, new: %d\n",
-				 ts->pkg_size, data_info.pkg_size);
-		} else {
-			ts->pkg_size = data_info.pkg_size;
-			ts->report_size = report_size;
-		}
-
-		ts->contact_size = data_info.tp_info_size;
-		ts->data_bank_addr = le32_to_cpu(data_info.data_bank_addr);
-
-		dev_dbg(&client->dev,
-			"data_bank_addr: %#08x, report_size: %d, contact_size: %d\n",
-			ts->data_bank_addr, ts->report_size, ts->contact_size);
-
 		error = raydium_i2c_read(client, RM_CMD_QUERY_BANK,
 					 &query_bank_addr,
 					 sizeof(query_bank_addr));
@@ -388,10 +369,29 @@ static int raydium_i2c_query_ts_info(struct raydium_data *ts)
 			continue;
 
 		error = raydium_i2c_read(client, le32_to_cpu(query_bank_addr),
-					 &ts->info, sizeof(ts->info));
+					 &info, sizeof(info));
 		if (error)
 			continue;
 
+		if (ts->report_data && ts->pkg_size != data_info.pkg_size) {
+			report_data = devm_krealloc(&client->dev, ts->report_data,
+						    data_info.pkg_size, GFP_KERNEL);
+			if (!report_data)
+				return -ENOMEM;
+
+			ts->report_data = report_data;
+		}
+
+		ts->pkg_size = data_info.pkg_size;
+		ts->report_size = report_size;
+		ts->contact_size = data_info.tp_info_size;
+		ts->data_bank_addr = le32_to_cpu(data_info.data_bank_addr);
+		ts->info = info;
+
+		dev_dbg(&client->dev,
+			"data_bank_addr: %#08x, report_size: %d, contact_size: %d\n",
+			ts->data_bank_addr, ts->report_size, ts->contact_size);
+
 		return 0;
 	}
 
-- 
2.43.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH v2 3/3] Input: raydium_i2c_ts - defer report buffer allocation
  2026-09-28 16:26 ` [PATCH v2 0/3] Input: raydium_i2c_ts report handling fixes Pooyan Azad
  2026-09-28 16:26   ` [PATCH v2 1/3] Input: raydium_i2c_ts - validate report parameters Pooyan Azad
  2026-09-28 16:26   ` [PATCH v2 2/3] Input: raydium_i2c_ts - resize report buffer after firmware update Pooyan Azad
@ 2026-09-28 16:26   ` Pooyan Azad
  2 siblings, 0 replies; 9+ messages in thread
From: Pooyan Azad @ 2026-09-28 16:26 UTC (permalink / raw)
  To: Dmitry Torokhov
  Cc: Uwe Kleine-König, Muhammad Bilal, Herlangga Maulani,
	Rob Herring, Jeffrey Lin, linux-input, linux-kernel

Devices may probe in bootloader mode, where the main firmware packet size
is not available yet. Allocating the report buffer from probe in this state
requests zero bytes and leaves a ZERO_SIZE_PTR until firmware is updated.

Allocate the buffer from the main firmware information query instead. The
query runs before the IRQ is requested during normal probe and with the IRQ
disabled after a firmware update, so changing the allocation point does not
introduce a race with the IRQ handler.

Link: https://lore.kernel.org/r/20260927114425.442803-1-pooyan.azadparvar@gmail.com/
Reviewed-by: Muhammad Bilal <meatuni001@gmail.com>
Signed-off-by: Pooyan Azad <pooyan.azadparvar@gmail.com>
---
 drivers/input/touchscreen/raydium_i2c_ts.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/drivers/input/touchscreen/raydium_i2c_ts.c b/drivers/input/touchscreen/raydium_i2c_ts.c
index 00990c61010f..1d7f53d0b9fe 100644
--- a/drivers/input/touchscreen/raydium_i2c_ts.c
+++ b/drivers/input/touchscreen/raydium_i2c_ts.c
@@ -373,7 +373,7 @@ static int raydium_i2c_query_ts_info(struct raydium_data *ts)
 		if (error)
 			continue;
 
-		if (ts->report_data && ts->pkg_size != data_info.pkg_size) {
+		if (!ts->report_data || ts->pkg_size != data_info.pkg_size) {
 			report_data = devm_krealloc(&client->dev, ts->report_data,
 						    data_info.pkg_size, GFP_KERNEL);
 			if (!report_data)
@@ -1135,11 +1135,6 @@ static int raydium_i2c_probe(struct i2c_client *client)
 		return error;
 	}
 
-	ts->report_data = devm_kmalloc(&client->dev,
-				       ts->pkg_size, GFP_KERNEL);
-	if (!ts->report_data)
-		return -ENOMEM;
-
 	ts->input = devm_input_allocate_device(&client->dev);
 	if (!ts->input) {
 		dev_err(&client->dev, "Failed to allocate input device\n");
-- 
2.43.0


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2026-09-28 16:26 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-27 11:44 [PATCH] Input: raydium_i2c_ts - validate report parameters Pooyan Azad
2026-09-27 17:30 ` Muhammad Bilal
2026-09-27 17:58   ` Pooyan Azadparvar
2026-09-28  2:38 ` Dmitry Torokhov
2026-09-28  6:04   ` Pooyan Azadparvar
2026-09-28 16:26 ` [PATCH v2 0/3] Input: raydium_i2c_ts report handling fixes Pooyan Azad
2026-09-28 16:26   ` [PATCH v2 1/3] Input: raydium_i2c_ts - validate report parameters Pooyan Azad
2026-09-28 16:26   ` [PATCH v2 2/3] Input: raydium_i2c_ts - resize report buffer after firmware update Pooyan Azad
2026-09-28 16:26   ` [PATCH v2 3/3] Input: raydium_i2c_ts - defer report buffer allocation Pooyan Azad

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®