git: c6522961cf5e - stable/13 - cxgbe tom: Force unsigned modulus for queue indices.

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Fri, 03 Feb 2023 00:06:43 UTC
The branch stable/13 has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=c6522961cf5ef7ecc5f4da49620f68f6e2125a0c

commit c6522961cf5ef7ecc5f4da49620f68f6e2125a0c
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2022-05-04 22:59:44 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2023-02-02 23:28:59 +0000

    cxgbe tom: Force unsigned modulus for queue indices.
    
    The final transmit and receive queue indices need to be positive
    values.  However, since txq_idx and rxq_idx are signed (to permit
    using -1 to as a marker for uninitialized values), using %= with
    another integer type (vi->nofld[tr]xq) yielded a sign-extended modulus
    value.  This resulted in negative queue indices and a buffer underrun
    when arc4random() returned a value with the sign bit set.  Use a
    temporary unsigned variable to hold the "raw" queue index to force
    unsigned modulus.
    
    This worked previously because the modulus was previously applied
    directly to the return value of arc4random() which is unsigned before
    the result was assigned to txq_idx and rxq_idx.
    
    Discussed with: np
    Fixes:          db28d4a0cd1c cxgbe/t4_tom: Support for round-robin selection of offload queues.
    Sponsored by:   Chelsio Communications
    
    (cherry picked from commit b483b6b256b2957f857db9092ef3c420a5143972)
---
 sys/dev/cxgbe/tom/t4_tom.c | 19 +++++++++----------
 1 file changed, 9 insertions(+), 10 deletions(-)

diff --git a/sys/dev/cxgbe/tom/t4_tom.c b/sys/dev/cxgbe/tom/t4_tom.c
index 25a63b992287..0fbcde5e0b57 100644
--- a/sys/dev/cxgbe/tom/t4_tom.c
+++ b/sys/dev/cxgbe/tom/t4_tom.c
@@ -1138,6 +1138,7 @@ init_conn_params(struct vi_info *vi , struct offload_settings *s,
 	struct inpcb *inp = sotoinpcb(so);
 	struct tcpcb *tp = intotcpcb(inp);
 	u_long wnd;
+	u_int q_idx;
 
 	MPASS(s->offload != 0);
 
@@ -1222,23 +1223,21 @@ init_conn_params(struct vi_info *vi , struct offload_settings *s,
 
 	/* Tx queue for this connection. */
 	if (s->txq == QUEUE_RANDOM)
-		cp->txq_idx = arc4random();
+		q_idx = arc4random();
 	else if (s->txq == QUEUE_ROUNDROBIN)
-		cp->txq_idx = atomic_fetchadd_int(&vi->txq_rr, 1);
+		q_idx = atomic_fetchadd_int(&vi->txq_rr, 1);
 	else
-		cp->txq_idx = s->txq;
-	cp->txq_idx %= vi->nofldtxq;
-	cp->txq_idx += vi->first_ofld_txq;
+		q_idx = s->txq;
+	cp->txq_idx = vi->first_ofld_txq + q_idx % vi->nofldtxq;
 
 	/* Rx queue for this connection. */
 	if (s->rxq == QUEUE_RANDOM)
-		cp->rxq_idx = arc4random();
+		q_idx = arc4random();
 	else if (s->rxq == QUEUE_ROUNDROBIN)
-		cp->rxq_idx = atomic_fetchadd_int(&vi->rxq_rr, 1);
+		q_idx = atomic_fetchadd_int(&vi->rxq_rr, 1);
 	else
-		cp->rxq_idx = s->rxq;
-	cp->rxq_idx %= vi->nofldrxq;
-	cp->rxq_idx += vi->first_ofld_rxq;
+		q_idx = s->rxq;
+	cp->rxq_idx = vi->first_ofld_rxq + q_idx % vi->nofldrxq;
 
 	if (SOLISTENING(so)) {
 		/* Passive open */