* [PATCH] Input: penmount: bound packet buffer indices in IRQ path
@ 2026-03-23 12:17 Pengpeng Hou
2026-03-23 13:32 ` Andy Shevchenko
` (2 more replies)
0 siblings, 3 replies; 8+ messages in thread
From: Pengpeng Hou @ 2026-03-23 12:17 UTC (permalink / raw)
To: dmitry.torokhov
Cc: andriy.shevchenko, kees, linux-input, linux-kernel, pengpeng
The IRQ handler stores each incoming byte into pm->data[] before the
packet parser gets a chance to reset pm->idx. If the incoming serial
stream never matches one of the expected packet headers, pm->idx can
advance past the fixed receive buffer and the next IRQ will write beyond
PM_MAX_LENGTH.
Reset stale indices before writing the next byte so malformed packet
streams cannot walk past the end of the local packet buffer.
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
---
drivers/input/touchscreen/penmount.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c
index 4b57b6664e37..ba09096c6573 100644
--- a/drivers/input/touchscreen/penmount.c
+++ b/drivers/input/touchscreen/penmount.c
@@ -163,6 +163,9 @@ static irqreturn_t pm_interrupt(struct serio *serio,
{
struct pm *pm = serio_get_drvdata(serio);
+ if (pm->idx >= pm->packetsize || pm->idx >= PM_MAX_LENGTH)
+ pm->idx = 0;
+
pm->data[pm->idx] = data;
pm->parse_packet(pm);
--
2.50.1 (Apple Git-155)
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH] Input: penmount: bound packet buffer indices in IRQ path
2026-03-23 12:17 [PATCH] Input: penmount: bound packet buffer indices in IRQ path Pengpeng Hou
@ 2026-03-23 13:32 ` Andy Shevchenko
2026-03-24 2:29 ` Pengpeng Hou
2026-03-24 13:14 ` [PATCH v2] " Pengpeng Hou
2 siblings, 0 replies; 8+ messages in thread
From: Andy Shevchenko @ 2026-03-23 13:32 UTC (permalink / raw)
To: Pengpeng Hou; +Cc: dmitry.torokhov, kees, linux-input, linux-kernel
On Mon, Mar 23, 2026 at 08:17:15PM +0800, Pengpeng Hou wrote:
> The IRQ handler stores each incoming byte into pm->data[] before the
> packet parser gets a chance to reset pm->idx. If the incoming serial
> stream never matches one of the expected packet headers, pm->idx can
> advance past the fixed receive buffer and the next IRQ will write beyond
> PM_MAX_LENGTH.
How did you find the issue? Any assistance?
> Reset stale indices before writing the next byte so malformed packet
> streams cannot walk past the end of the local packet buffer.
Why do you think this is the best possible approach? Maybe we should
simply ignore IRQ or handle it without any further actions?
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] Input: penmount: bound packet buffer indices in IRQ path
2026-03-23 12:17 [PATCH] Input: penmount: bound packet buffer indices in IRQ path Pengpeng Hou
2026-03-23 13:32 ` Andy Shevchenko
@ 2026-03-24 2:29 ` Pengpeng Hou
2026-03-24 12:11 ` Andy Shevchenko
2026-03-24 13:14 ` [PATCH v2] " Pengpeng Hou
2 siblings, 1 reply; 8+ messages in thread
From: Pengpeng Hou @ 2026-03-24 2:29 UTC (permalink / raw)
To: andy
Cc: Pengpeng Hou, andriy.shevchenko, hansg, mchehab, gregkh,
linux-kernel, linux-input
Hi Andy,
This was found during static code analysis of the packet receive path.
About the fix: my reasoning was that once pm->idx has already moved past
the valid packet buffer state, the current partial packet is no longer
usable, so the safest local recovery is to drop that stale state and
resynchronize from the current byte. That is why I reset the index before
storing the next byte.
I did not choose to ignore the IRQ entirely because the interrupt has
already delivered a byte, and simply returning without resetting the stale
state would leave the parser in the same invalid condition for the next
interrupt. Resetting the index seemed like the smallest change that both
prevents the out-of-bounds write and lets the parser recover cleanly.
Thanks,
Pengpeng
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH] Input: penmount: bound packet buffer indices in IRQ path
2026-03-24 2:29 ` Pengpeng Hou
@ 2026-03-24 12:11 ` Andy Shevchenko
0 siblings, 0 replies; 8+ messages in thread
From: Andy Shevchenko @ 2026-03-24 12:11 UTC (permalink / raw)
To: Pengpeng Hou; +Cc: andy, hansg, mchehab, gregkh, linux-kernel, linux-input
On Tue, Mar 24, 2026 at 10:29:50AM +0800, Pengpeng Hou wrote:
>
> This was found during static code analysis of the packet receive path.
>
> About the fix: my reasoning was that once pm->idx has already moved past
> the valid packet buffer state, the current partial packet is no longer
> usable, so the safest local recovery is to drop that stale state and
> resynchronize from the current byte. That is why I reset the index before
> storing the next byte.
>
> I did not choose to ignore the IRQ entirely because the interrupt has
> already delivered a byte, and simply returning without resetting the stale
> state would leave the parser in the same invalid condition for the next
> interrupt. Resetting the index seemed like the smallest change that both
> prevents the out-of-bounds write and lets the parser recover cleanly.
Good, (summary of) this should be in the commit message in the first place.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH v2] Input: penmount: bound packet buffer indices in IRQ path
2026-03-23 12:17 [PATCH] Input: penmount: bound packet buffer indices in IRQ path Pengpeng Hou
2026-03-23 13:32 ` Andy Shevchenko
2026-03-24 2:29 ` Pengpeng Hou
@ 2026-03-24 13:14 ` Pengpeng Hou
2026-03-24 13:47 ` Andy Shevchenko
` (2 more replies)
2 siblings, 3 replies; 8+ messages in thread
From: Pengpeng Hou @ 2026-03-24 13:14 UTC (permalink / raw)
To: dmitry.torokhov
Cc: andriy.shevchenko, kees, linux-input, linux-kernel, pengpeng
pm_interrupt() stores each incoming byte into pm->data[] before the
packet parser gets a chance to reset pm->idx. If the incoming serial
stream never matches one of the expected packet headers, pm->idx can
advance past the fixed receive buffer and the next IRQ will write beyond
PM_MAX_LENGTH.
Reset stale indices before storing the next byte. Once pm->idx has
already moved past the valid packet buffer state, the current partial
packet can no longer be trusted, so the smallest local recovery is to
drop that stale state and resynchronize from the current byte instead of
carrying the invalid index into the next interrupt.
Found by static code analysis.
Fixes: 98b013eb7a94 ("Input: penmount - rework handling of different protocols")
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
---
v2:
- note that the issue was found by static code analysis
- explain why resetting the stale index is the preferred resynchronization path
- add a Fixes tag
drivers/input/touchscreen/penmount.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/input/touchscreen/penmount.c b/drivers/input/touchscreen/penmount.c
index 4b57b6664e37..ba09096c6573 100644
--- a/drivers/input/touchscreen/penmount.c
+++ b/drivers/input/touchscreen/penmount.c
@@ -163,6 +163,9 @@ static irqreturn_t pm_interrupt(struct serio *serio,
{
struct pm *pm = serio_get_drvdata(serio);
+ if (pm->idx >= pm->packetsize || pm->idx >= PM_MAX_LENGTH)
+ pm->idx = 0;
+
pm->data[pm->idx] = data;
pm->parse_packet(pm);
--
2.50.1 (Apple Git-155)
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH v2] Input: penmount: bound packet buffer indices in IRQ path
2026-03-24 13:14 ` [PATCH v2] " Pengpeng Hou
@ 2026-03-24 13:47 ` Andy Shevchenko
2026-03-25 1:36 ` Dmitry Torokhov
2026-03-25 1:46 ` Pengpeng Hou
2 siblings, 0 replies; 8+ messages in thread
From: Andy Shevchenko @ 2026-03-24 13:47 UTC (permalink / raw)
To: Pengpeng Hou; +Cc: dmitry.torokhov, kees, linux-input, linux-kernel
On Tue, Mar 24, 2026 at 09:14:42PM +0800, Pengpeng Hou wrote:
> pm_interrupt() stores each incoming byte into pm->data[] before the
> packet parser gets a chance to reset pm->idx. If the incoming serial
> stream never matches one of the expected packet headers, pm->idx can
> advance past the fixed receive buffer and the next IRQ will write beyond
> PM_MAX_LENGTH.
>
> Reset stale indices before storing the next byte. Once pm->idx has
> already moved past the valid packet buffer state, the current partial
> packet can no longer be trusted, so the smallest local recovery is to
> drop that stale state and resynchronize from the current byte instead of
> carrying the invalid index into the next interrupt.
>
> Found by static code analysis.
Missed blank line here. No need to resend until maintainers ask explicitly for
that.
...
The explanation sounds sane, but I'm not familiar enough with how this device
works. In case others consider this good, feel free to add
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] Input: penmount: bound packet buffer indices in IRQ path
2026-03-24 13:14 ` [PATCH v2] " Pengpeng Hou
2026-03-24 13:47 ` Andy Shevchenko
@ 2026-03-25 1:36 ` Dmitry Torokhov
2026-03-25 1:46 ` Pengpeng Hou
2 siblings, 0 replies; 8+ messages in thread
From: Dmitry Torokhov @ 2026-03-25 1:36 UTC (permalink / raw)
To: Pengpeng Hou; +Cc: andriy.shevchenko, kees, linux-input, linux-kernel
Hi Pengpeng,
On Tue, Mar 24, 2026 at 09:14:42PM +0800, Pengpeng Hou wrote:
> pm_interrupt() stores each incoming byte into pm->data[] before the
> packet parser gets a chance to reset pm->idx. If the incoming serial
> stream never matches one of the expected packet headers, pm->idx can
> advance past the fixed receive buffer and the next IRQ will write beyond
> PM_MAX_LENGTH.
How will it advance? The handlers do:
if (byte_0_check() && pm->packetsize == ++pm->idx)
...
If we never match any of the protocols then pm->idx will never advance
past 0 (and we will keep overwriting the first byte of the packet
array).
Does your analyzer miss the "short-circuiting" nature of && operator?
Thanks.
--
Dmitry
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH v2] Input: penmount: bound packet buffer indices in IRQ path
2026-03-24 13:14 ` [PATCH v2] " Pengpeng Hou
2026-03-24 13:47 ` Andy Shevchenko
2026-03-25 1:36 ` Dmitry Torokhov
@ 2026-03-25 1:46 ` Pengpeng Hou
2 siblings, 0 replies; 8+ messages in thread
From: Pengpeng Hou @ 2026-03-25 1:46 UTC (permalink / raw)
To: Dmitry Torokhov
Cc: Pengpeng Hou, andriy.shevchenko, kees, linux-input, linux-kernel
Hi Dmitry,
You are right, thanks for pointing this out.
I rechecked the control flow and my analysis was wrong here. If the
first byte does not match a supported packet header, the left side of
the && fails and ++pm->idx is not evaluated, so pm->idx stays at 0. If
the first byte does match, pm->idx only advances until packetsize and
is then reset to 0 in the handler.
So this does not provide a path for pm->idx to grow past the packet
buffer. My analyzer missed the short-circuiting behavior of && here.
I will drop this patch.
Best regards,
Pengpeng
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-03-25 1:46 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-23 12:17 [PATCH] Input: penmount: bound packet buffer indices in IRQ path Pengpeng Hou
2026-03-23 13:32 ` Andy Shevchenko
2026-03-24 2:29 ` Pengpeng Hou
2026-03-24 12:11 ` Andy Shevchenko
2026-03-24 13:14 ` [PATCH v2] " Pengpeng Hou
2026-03-24 13:47 ` Andy Shevchenko
2026-03-25 1:36 ` Dmitry Torokhov
2026-03-25 1:46 ` Pengpeng Hou
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox