]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
octeontx2-af: validate body pcifunc in rvu_mbox_handler_rep_event_notify
authorMichael Bommarito <michael.bommarito@gmail.com>
Wed, 20 May 2026 15:41:57 +0000 (11:41 -0400)
committerJakub Kicinski <kuba@kernel.org>
Mon, 25 May 2026 19:49:33 +0000 (12:49 -0700)
rvu_mbox_handler_rep_event_notify() in drivers/net/ethernet/marvell/
octeontx2/af/rvu_rep.c queues a sender-controlled REP_EVENT_NOTIFY
request body verbatim, and rvu_rep_up_notify() then forwards
event->pcifunc (the nested body field, distinct from the
AF-normalised header pcifunc) into rvu_get_pfvf(), rvu_get_pf() and
the AF->PF mailbox device index without any bounds check.

A VF attached to a PF that has been put into switchdev
representor mode reaches this path: the VF mailbox handler
otx2_pfvf_mbox_handler() forwards every message id including
MBOX_MSG_REP_EVENT_NOTIFY to AF without an allowlist, and the AF
dispatcher rewrites only msg->pcifunc, leaving struct
rep_event::pcifunc attacker-controlled.  The sibling
rvu_mbox_handler_esw_cfg() refuses requests whose header pcifunc
is not rvu->rep_pcifunc; this handler has no equivalent gate.

An out-of-range body pcifunc selects an &rvu->pf[]/&rvu->hwvf[]
element past the allocated array and, for RVU_EVENT_MAC_ADDR_CHANGE,
turns into a six-byte attacker-chosen OOB ether_addr_copy() target
inside the queued worker; KASAN reports a slab-out-of-bounds write
in rvu_rep_wq_handler.

Reject malformed requests at the handler entry by gating on
is_pf_func_valid(), which is already the canonical PF/VF range check
in this driver; expose it via rvu.h so callers in rvu_rep.c can use
it instead of open-coding the same range arithmetic.

Fixes: b8fea84a0468 ("octeontx2-pf: Add support to sync link state between representor and VFs")
Cc: stable@vger.kernel.org
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Link: https://patch.msgid.link/20260520154157.1439319-1-michael.bommarito@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/marvell/octeontx2/af/rvu.c
drivers/net/ethernet/marvell/octeontx2/af/rvu.h
drivers/net/ethernet/marvell/octeontx2/af/rvu_rep.c

index e40b79076358d2c7be38b58a309fee17cf84cf3e..3cf131508ecfe542de9ed2564923f854edc6855b 100644 (file)
@@ -436,7 +436,7 @@ struct rvu_pfvf *rvu_get_pfvf(struct rvu *rvu, int pcifunc)
                return &rvu->pf[rvu_get_pf(rvu->pdev, pcifunc)];
 }
 
-static bool is_pf_func_valid(struct rvu *rvu, u16 pcifunc)
+bool is_pf_func_valid(struct rvu *rvu, u16 pcifunc)
 {
        int pf, vf, nvfs;
        u64 cfg;
index a466181cf908263e1188bdbcbe0215686f541d7e..de3fbd3d15d607a659d844fffe05adaa267de2e1 100644 (file)
@@ -917,6 +917,7 @@ u16 rvu_get_rsrc_mapcount(struct rvu_pfvf *pfvf, int blkaddr);
 struct rvu_pfvf *rvu_get_pfvf(struct rvu *rvu, int pcifunc);
 void rvu_get_pf_numvfs(struct rvu *rvu, int pf, int *numvfs, int *hwvf);
 bool is_block_implemented(struct rvu_hwinfo *hw, int blkaddr);
+bool is_pf_func_valid(struct rvu *rvu, u16 pcifunc);
 bool is_pffunc_map_valid(struct rvu *rvu, u16 pcifunc, int blktype);
 int rvu_get_lf(struct rvu *rvu, struct rvu_block *block, u16 pcifunc, u16 slot);
 int rvu_lf_reset(struct rvu *rvu, struct rvu_block *block, int lf);
index 901f6fd40fd49e7ffbdf1d2b92e1aa8b3908c01d..a2781e0f504e3e95657ff24926dc92755d90db6f 100644 (file)
@@ -97,6 +97,14 @@ int rvu_mbox_handler_rep_event_notify(struct rvu *rvu, struct rep_event *req,
 {
        struct rep_evtq_ent *qentry;
 
+       /* The mailbox dispatcher normalises only the header pcifunc; the
+        * nested struct rep_event::pcifunc body field is sender-controlled
+        * and is later used by rvu_rep_up_notify() to index rvu->pf[] /
+        * rvu->hwvf[].  Reject out-of-range body selectors before queueing.
+        */
+       if (!is_pf_func_valid(rvu, req->pcifunc))
+               return -EINVAL;
+
        qentry = kmalloc_obj(*qentry, GFP_ATOMIC);
        if (!qentry)
                return -ENOMEM;