git: b0cfa27c91c4 - main - cxgbe(4): Avoid racy access to requested_fec in sysctl_requested_fec

From: Navdeep Parhar <np_at_FreeBSD.org>
Date: Fri, 14 Nov 2025 08:44:06 UTC
The branch main has been updated by np:

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

commit b0cfa27c91c400dcf3e8441cc04f9e5300c7c3af
Author:     Navdeep Parhar <np@FreeBSD.org>
AuthorDate: 2025-11-14 07:45:59 +0000
Commit:     Navdeep Parhar <np@FreeBSD.org>
CommitDate: 2025-11-14 07:45:59 +0000

    cxgbe(4): Avoid racy access to requested_fec in sysctl_requested_fec
    
    PR:             289121
    Reported by:    Qiu-ji Chen
    MFC after:      1 week
    Sponsored by:   Chelsio Communications
    Differential Revision:  https://reviews.freebsd.org/D52199
---
 sys/dev/cxgbe/t4_main.c | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/sys/dev/cxgbe/t4_main.c b/sys/dev/cxgbe/t4_main.c
index 4ce8d71ed86f..9bd5e02fabf0 100644
--- a/sys/dev/cxgbe/t4_main.c
+++ b/sys/dev/cxgbe/t4_main.c
@@ -9007,7 +9007,7 @@ sysctl_requested_fec(SYSCTL_HANDLER_ARGS)
 	struct adapter *sc = pi->adapter;
 	struct link_config *lc = &pi->link_cfg;
 	int rc;
-	int8_t old;
+	int8_t old = lc->requested_fec;
 
 	if (req->newptr == NULL) {
 		struct sbuf *sb;
@@ -9016,16 +9016,15 @@ sysctl_requested_fec(SYSCTL_HANDLER_ARGS)
 		if (sb == NULL)
 			return (ENOMEM);
 
-		sbuf_printf(sb, "%b", lc->requested_fec, t4_fec_bits);
+		sbuf_printf(sb, "%b", old, t4_fec_bits);
 		rc = sbuf_finish(sb);
 		sbuf_delete(sb);
 	} else {
 		char s[8];
 		int n;
 
-		snprintf(s, sizeof(s), "%d",
-		    lc->requested_fec == FEC_AUTO ? -1 :
-		    lc->requested_fec & (M_FW_PORT_CAP32_FEC | FEC_MODULE));
+		snprintf(s, sizeof(s), "%d", old == FEC_AUTO ? -1 :
+		    old & (M_FW_PORT_CAP32_FEC | FEC_MODULE));
 
 		rc = sysctl_handle_string(oidp, s, sizeof(s), req);
 		if (rc != 0)
@@ -9042,7 +9041,10 @@ sysctl_requested_fec(SYSCTL_HANDLER_ARGS)
 		if (rc)
 			return (rc);
 		PORT_LOCK(pi);
-		old = lc->requested_fec;
+		if (lc->requested_fec != old) {
+			rc = EBUSY;
+			goto done;
+		}
 		if (n == FEC_AUTO)
 			lc->requested_fec = FEC_AUTO;
 		else if (n == 0 || n == FEC_NONE)