From: Kees Cook <kees@kernel.org>
To: Dan Carpenter <dan.carpenter@linaro.org>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>,
Javier Carrasco <javier.carrasco.cruz@gmail.com>,
David Lechner <dlechner@baylibre.com>,
"Gustavo A. R. Silva" <gustavoars@kernel.org>,
Al Viro <viro@zeniv.linux.org.uk>,
Erick Archer <erick.archer@outlook.com>,
linux-input@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH 3/3] Input: ims-pcu - Check record size in ims_pcu_flash_firmware()
Date: Wed, 28 May 2025 16:26:18 -0700 [thread overview]
Message-ID: <202505281611.A024D45E@keescook> (raw)
In-Reply-To: <131fd1ae92c828ee9f4fa2de03d8c210ae1f3524.1748463049.git.dan.carpenter@linaro.org>
On Wed, May 28, 2025 at 11:22:24PM +0300, Dan Carpenter wrote:
> The "len" variable comes from the firmware and we generally do
> trust firmware, but it's always better to double check. If the "len"
> is too large it could result in memory corruption when we do
> "memcpy(fragment->data, rec->data, len);"
>
> Fixes: 628329d52474 ("Input: add IMS Passenger Control Unit driver")
> Signed-off-by: Dan Carpenter <dan.carpenter@linaro.org>
> ---
> Kees, this is a __counted_by() thing. Would the checkers catch this?
> We know the maximum valid length for "fragment" is and so it's maybe
> possible to know that "fragment->len = len;" is too long?
I see:
pcu->cmd_buf as:
u8 cmd_buf[IMS_PCU_BUF_SIZE];
and fragment is:
struct ims_pcu_flash_fmt {
__le32 addr;
u8 len;
u8 data[] __counted_by(len);
};
I assume you're asking about this line:
fragment->len = len;
I'm not aware of any compiler instrumentation that would bounds check
this -- it was designed to trust these sort of explicit assignments.
This is hardly the only place in the kernel doing this kind of
deserialization into a flexible array structure, so maybe there should
be some kind of helper to do the bounds checking and set the
"counted_by" counter?
#define gimme(from, into, counter, len) \
({ \
int __gimme_rc = -EINVAL \
size_t __gimme_size = __member_size(from); \
if (__gimme_size >= sizeof(*into) && \
__gimme_size - sizeof(*into) >= len) { \
into = (void *)from; \
into->counter = len; \
__gimme_rc = 0; \
} \
__gimme_rc; \
})
rc = gimme(&pcu->cmd_buf[1], fragment, len, len);
if (rc) {
dev_err(pcu->dev,
"Invalid record length in firmware: %d\n", len);
return rc;
}
-Kees
>
> drivers/input/misc/ims-pcu.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/drivers/input/misc/ims-pcu.c b/drivers/input/misc/ims-pcu.c
> index d9ee14b1f451..4581f1c53644 100644
> --- a/drivers/input/misc/ims-pcu.c
> +++ b/drivers/input/misc/ims-pcu.c
> @@ -844,6 +844,12 @@ static int ims_pcu_flash_firmware(struct ims_pcu *pcu,
> addr = be32_to_cpu(rec->addr) / 2;
> len = be16_to_cpu(rec->len);
>
> + if (len > sizeof(pcu->cmd_buf) - 1 - sizeof(*fragment)) {
> + dev_err(pcu->dev,
> + "Invalid record length in firmware: %d\n", len);
> + return -EINVAL;
> + }
> +
> fragment = (void *)&pcu->cmd_buf[1];
> put_unaligned_le32(addr, &fragment->addr);
> fragment->len = len;
> --
> 2.47.2
>
--
Kees Cook
next prev parent reply other threads:[~2025-05-28 23:26 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-05-28 20:22 [PATCH 0/3] ihex: add some bounds checking to firmware parsing Dan Carpenter
2025-05-28 20:22 ` [PATCH 1/3] media: gspca: Add bounds checking to firmware parser Dan Carpenter
2025-05-28 20:22 ` [PATCH 2/3] watchdog: ziirave_wdt: check record length in ziirave_firm_verify() Dan Carpenter
2025-06-02 14:11 ` Guenter Roeck
2025-05-28 20:22 ` [PATCH 3/3] Input: ims-pcu - Check record size in ims_pcu_flash_firmware() Dan Carpenter
2025-05-28 23:26 ` Kees Cook [this message]
2025-06-02 11:00 ` Dan Carpenter
2025-05-30 23:14 ` Dmitry Torokhov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=202505281611.A024D45E@keescook \
--to=kees@kernel.org \
--cc=dan.carpenter@linaro.org \
--cc=dlechner@baylibre.com \
--cc=dmitry.torokhov@gmail.com \
--cc=erick.archer@outlook.com \
--cc=gustavoars@kernel.org \
--cc=javier.carrasco.cruz@gmail.com \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.