The header check of a received BAR channel message copies the 16-bit
module_id field into a uint8_t local before comparing it with the
handler table size, and the callers then index
zxdh_msg_recv_func_tbl[] with the full untruncated value. Any
module_id whose low byte is below ZXDH_BAR_MSG_MODULE_NUM passes the
check, so a sender can select among about 25,500 slots past the
100-entry table, and a synchronous message makes the PF call whatever
word it finds there. With the default gcc build the reachable slots
inside g_seqid_ring hold small integers set at init, so one forged
message from a VF jumps to a low address and kills the PF process.
Widen the local to uint16_t and drop the (uint8_t) cast so the check
compares the same value the callers use as the index. This is the
only place a received module_id is validated; the send side already
compares the full value. Valid ids 0-99 are unaffected.
Fixes: 3630ac8bd81f ("net/zxdh: configure interrupt")
Cc: [email protected]
Signed-off-by: Junlong Wang <[email protected]>
---
drivers/net/zxdh/zxdh_msg.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/zxdh/zxdh_msg.c b/drivers/net/zxdh/zxdh_msg.c
index 95b2f5a60b..77b8df2f12 100644
--- a/drivers/net/zxdh/zxdh_msg.c
+++ b/drivers/net/zxdh/zxdh_msg.c
@@ -960,7 +960,7 @@ static uint16_t
zxdh_bar_chan_msg_header_check(struct zxdh_bar_msg_header *msg_header)
{
uint16_t len = 0;
- uint8_t module_id = 0;
+ uint16_t module_id = 0;
if (msg_header->valid != ZXDH_BAR_MSG_CHAN_USED) {
PMD_MSG_LOG(ERR, "recv header ERR: valid label is not used");
@@ -968,7 +968,7 @@ zxdh_bar_chan_msg_header_check(struct zxdh_bar_msg_header
*msg_header)
}
module_id = msg_header->module_id;
- if (module_id >= (uint8_t)ZXDH_BAR_MSG_MODULE_NUM) {
+ if (module_id >= ZXDH_BAR_MSG_MODULE_NUM) {
PMD_MSG_LOG(ERR, "recv header ERR: invalid module_id: %u",
module_id);
return ZXDH_BAR_MSG_ERR_MODULE;
}
--
2.27.0