* [PATCH v2] media: dvb-frontends: si2168: validate firmware record length
@ 2026-07-15 8:39 Pengpeng Hou
0 siblings, 0 replies; only message in thread
From: Pengpeng Hou @ 2026-07-15 8:39 UTC (permalink / raw)
To: Mauro Carvalho Chehab
Cc: Pengpeng Hou, linux-media, linux-kernel, Laura Abbott, stable
The new Si2168 firmware format stores one command in each 17-byte record:
the first byte is the command length and the remaining 16 bytes are the
command data.
The existing check only compares the length with SI2168_ARGLEN, which
protects the destination command array but not the current firmware record.
A length from 17 through SI2168_ARGLEN makes cmd_init() copy from the next
record, or past the firmware blob for the final record. An empty firmware
file also passes the modulo test before fw->data[0] is read.
Reject empty files and require each new-format command length to fit the
16-byte payload of its record before copying it.
Fixes: 47810b4341ac ("[media] si2168: Bounds check firmware")
Cc: stable@vger.kernel.org
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
---
Changes since v1:
- Reject empty firmware blobs before reading the first record byte.
- Name the old and new record sizes while retaining the current-record
payload bound.
Link: https://lore.kernel.org/r/20260705084706.62129-1-pengpeng@iscas.ac.cn
drivers/media/dvb-frontends/si2168.c | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/drivers/media/dvb-frontends/si2168.c b/drivers/media/dvb-frontends/si2168.c
index 8bc3b6eb1dd3..182c2b671508 100644
--- a/drivers/media/dvb-frontends/si2168.c
+++ b/drivers/media/dvb-frontends/si2168.c
@@ -11,6 +11,9 @@
static const struct dvb_frontend_ops si2168_ops;
+#define SI2168_NEW_FIRMWARE_RECORD_SIZE 17
+#define SI2168_OLD_FIRMWARE_RECORD_SIZE 8
+
static void cmd_init(struct si2168_cmd *cmd, const u8 *buf, int wlen, int rlen)
{
memcpy(cmd->args, buf, wlen);
@@ -459,11 +462,15 @@ static int si2168_init(struct dvb_frontend *fe)
dev_info(&client->dev, "downloading firmware from file '%s'\n",
dev->firmware_name);
- if ((fw->size % 17 == 0) && (fw->data[0] > 5)) {
+ if (fw->size &&
+ fw->size % SI2168_NEW_FIRMWARE_RECORD_SIZE == 0 &&
+ fw->data[0] > 5) {
/* firmware is in the new format */
- for (remaining = fw->size; remaining > 0; remaining -= 17) {
+ for (remaining = fw->size; remaining > 0;
+ remaining -= SI2168_NEW_FIRMWARE_RECORD_SIZE) {
len = fw->data[fw->size - remaining];
- if (len > SI2168_ARGLEN) {
+ if (len > SI2168_ARGLEN ||
+ len >= SI2168_NEW_FIRMWARE_RECORD_SIZE) {
ret = -EINVAL;
break;
}
@@ -473,10 +480,13 @@ static int si2168_init(struct dvb_frontend *fe)
if (ret)
break;
}
- } else if (fw->size % 8 == 0) {
+ } else if (fw->size &&
+ fw->size % SI2168_OLD_FIRMWARE_RECORD_SIZE == 0) {
/* firmware is in the old format */
- for (remaining = fw->size; remaining > 0; remaining -= 8) {
- cmd_init(&cmd, &fw->data[fw->size - remaining], 8, 1);
+ for (remaining = fw->size; remaining > 0;
+ remaining -= SI2168_OLD_FIRMWARE_RECORD_SIZE) {
+ cmd_init(&cmd, &fw->data[fw->size - remaining],
+ SI2168_OLD_FIRMWARE_RECORD_SIZE, 1);
ret = si2168_cmd_execute(client, &cmd);
if (ret)
break;
--
2.43.0
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2026-07-15 8:39 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-15 8:39 [PATCH v2] media: dvb-frontends: si2168: validate firmware record length Pengpeng Hou
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox