mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 10:33:41 +02:00
ethtool: cmis: require exact CDB reply length
Malicious SFP module could respond with rpl_len longer than
what cmis_cdb_process_reply() expected, leading to OOB writes.
Malicious HW is a bit theoretical but some modules may just
be buggy and/or the reads may occasionally get corrupted,
so let's protect the kernel.
The existing check protects from short replies. We need to
protect from long ones, too. All callers that pass a non-zero
rpl_exp_len cast the reply payload to a fixed-layout struct
and read fields at fixed offsets, with no version negotiation
or short-reply handling:
- cmis_cdb_validate_password()
- cmis_cdb_module_features_get()
- cmis_fw_update_fw_mng_features_get()
so let's assume that responses longer than expected do not
have to be handled gracefully here. Add a warning message
to make the debug easier in case my understanding is wrong...
Note that page_data->length (argument of kmalloc) comes from
last arg to ethtool_cmis_page_init() which is rpl_exp_len.
Note2 that AIs also like to point out overflows in args->req.payload
itself (which is a fixed-size 120 B buffer, on the stack),
but callers should be reading structs defined by the standard,
so protecting from requests for more data than max seem like
defensive programming.
Fixes: a39c84d796 ("ethtool: cmis_cdb: Add a layer for supporting CDB commands")
Reviewed-by: Danielle Ratson <danieller@nvidia.com>
Link: https://patch.msgid.link/20260522231312.1710836-7-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
760d04ebad
commit
6c3f999a9d
|
|
@ -513,8 +513,13 @@ static int cmis_cdb_process_reply(struct net_device *dev,
|
|||
}
|
||||
|
||||
rpl = (struct ethtool_cmis_cdb_rpl *)page_data->data;
|
||||
if ((args->rpl_exp_len > rpl->hdr.rpl_len + rpl_hdr_len) ||
|
||||
!rpl->hdr.rpl_chk_code) {
|
||||
if (rpl->hdr.rpl_len != args->rpl_exp_len) {
|
||||
netdev_warn(dev, "CDB reply length mismatch, expected %u got %u\n",
|
||||
args->rpl_exp_len, rpl->hdr.rpl_len);
|
||||
err = -EIO;
|
||||
goto out;
|
||||
}
|
||||
if (!rpl->hdr.rpl_chk_code) {
|
||||
err = -EIO;
|
||||
goto out;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user