git: e70ff92d2431 - main - ice: Add malformed virtchnl injection points
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 17 Sep 2026 16:40:16 UTC
The branch main has been updated by kbowling:
URL: https://cgit.FreeBSD.org/src/commit/?id=e70ff92d243104834ad40581c3562a55d7525cc8
commit e70ff92d243104834ad40581c3562a55d7525cc8
Author: Kevin Bowling <kbowling@FreeBSD.org>
AuthorDate: 2026-08-19 03:18:53 +0000
Commit: Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2026-09-17 16:36:36 +0000
ice: Add malformed virtchnl injection points
Extend the optional ice(4) failure injection facility with semantic
corruption points for queue configuration, RSS keys and tables, and
interrupt mappings.
Each point mutates an otherwise valid request after the common
virtchnl length check. This exercises the PF semantic validators with a
real VF while preserving the normal wire format and mailbox path.
The queue point selects unaligned Tx or Rx bases, an unaligned or
unrepresentable receive buffer, an invalid frame size, duplicate queue
IDs, or a bad VSI. The RSS points select short advertised data or an
out-of-range LUT entry. The interrupt point selects an invalid ITR,
traffic on vector zero, duplicate vectors, or a bad VSI.
The points remain absent unless the kernel is built with
options DRIVER_FAILPOINTS and retain the existing PF and VF selectors.
MFC after: 2 weeks
Sponsored by: BBOX.io
Differential Revision: https://reviews.freebsd.org/D59021
---
sys/dev/ice/ice_iov.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 72 insertions(+)
diff --git a/sys/dev/ice/ice_iov.c b/sys/dev/ice/ice_iov.c
index eab735820f8e..0c5d49ebf5b1 100644
--- a/sys/dev/ice/ice_iov.c
+++ b/sys/dev/ice/ice_iov.c
@@ -1421,6 +1421,41 @@ ice_vc_cfg_vsi_qs_msg(struct ice_softc *sc, struct ice_vf *vf, u8 *msg_buf)
int i, error = 0;
vqci = (struct virtchnl_vsi_queue_config_info *)msg_buf;
+ ICE_FAIL_POINT_CODE_COND(sc, _debug_fail_point_ice_iov,
+ malformed_queues, ice_iov_fail_vf_matches(vf->vf_num),
+ FAIL_POINT_NONSLEEPABLE, {
+ switch (RETURN_VALUE) {
+ case 1:
+ vqci->qpair[0].txq.dma_ring_addr |= 1;
+ break;
+ case 2:
+ vqci->qpair[0].rxq.dma_ring_addr |= 1;
+ break;
+ case 3:
+ vqci->qpair[0].rxq.databuffer_size++;
+ break;
+ case 4:
+ vqci->qpair[0].rxq.max_pkt_size = 0;
+ break;
+ case 5:
+ if (vqci->num_queue_pairs > 1) {
+ vqci->qpair[1].txq.queue_id =
+ vqci->qpair[0].txq.queue_id;
+ vqci->qpair[1].rxq.queue_id =
+ vqci->qpair[0].rxq.queue_id;
+ } else {
+ vqci->qpair[0].txq.queue_id++;
+ }
+ break;
+ case 6:
+ vqci->qpair[0].rxq.databuffer_size =
+ ICE_VC_MAX_RX_BUFFER + BIT(ICE_RLAN_CTX_DBUF_S);
+ break;
+ default:
+ vqci->vsi_id++;
+ break;
+ }
+ });
if (vqci->vsi_id != vsi->idx || vqci->num_queue_pairs == 0 ||
vqci->num_queue_pairs > sizeof(queue_map) * NBBY ||
@@ -1569,6 +1604,11 @@ ice_vc_cfg_rss_key_msg(struct ice_softc *sc, struct ice_vf *vf, u8 *msg_buf)
struct ice_vsi *vsi = vf->vsi;
vrk = (struct virtchnl_rss_key *)msg_buf;
+ ICE_FAIL_POINT_CODE_COND(sc, _debug_fail_point_ice_iov,
+ malformed_rss_key, ice_iov_fail_vf_matches(vf->vf_num),
+ FAIL_POINT_NONSLEEPABLE, {
+ vrk->key_len--;
+ });
if (vrk->vsi_id != vsi->idx) {
device_printf(sc->dev,
@@ -1619,6 +1659,14 @@ ice_vc_cfg_rss_lut_msg(struct ice_softc *sc, struct ice_vf *vf, u8 *msg_buf)
struct ice_vsi *vsi = vf->vsi;
vrl = (struct virtchnl_rss_lut *)msg_buf;
+ ICE_FAIL_POINT_CODE_COND(sc, _debug_fail_point_ice_iov,
+ malformed_rss_lut, ice_iov_fail_vf_matches(vf->vf_num),
+ FAIL_POINT_NONSLEEPABLE, {
+ if (RETURN_VALUE == 1)
+ vrl->lut_entries--;
+ else
+ vrl->lut[0] = vsi->num_rx_queues;
+ });
if (vrl->vsi_id != vsi->idx) {
device_printf(sc->dev,
@@ -1824,6 +1872,30 @@ ice_vc_cfg_irq_map_msg(struct ice_softc *sc, struct ice_vf *vf, u8 *msg_buf)
u16 rxqs_seen, txqs_seen, valid_rxqs, valid_txqs, vector;
vimi = (struct virtchnl_irq_map_info *)msg_buf;
+ ICE_FAIL_POINT_CODE_COND(sc, _debug_fail_point_ice_iov,
+ malformed_irq_map, ice_iov_fail_vf_matches(vf->vf_num),
+ FAIL_POINT_NONSLEEPABLE, {
+ switch (RETURN_VALUE) {
+ case 1:
+ vimi->vecmap[0].rxitr_idx = VIRTCHNL_ITR_IDX_NO_ITR + 1;
+ break;
+ case 2:
+ vimi->vecmap[0].vector_id = 0;
+ vimi->vecmap[0].rxq_map = 1;
+ break;
+ case 3:
+ if (vimi->num_vectors > 1) {
+ vimi->vecmap[1].vector_id =
+ vimi->vecmap[0].vector_id;
+ } else {
+ vimi->vecmap[0].vsi_id++;
+ }
+ break;
+ default:
+ vimi->vecmap[0].vsi_id++;
+ break;
+ }
+ });
if (vimi->num_vectors == 0 ||
vimi->num_vectors > vf->num_irq_vectors ||