git: 24a205e32805 - stable/13 - Fix undefined behaviour in the USB controllers

From: Andrew Turner <andrew_at_FreeBSD.org>
Date: Tue, 22 Feb 2022 16:40:18 UTC
The branch stable/13 has been updated by andrew:

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

commit 24a205e32805e7e6ee2b8ce564770772ff730d30
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2021-12-29 12:10:49 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2022-02-22 16:23:07 +0000

    Fix undefined behaviour in the USB controllers
    
    The USB controller drivers assume they can cast a NULL pointer to a
    struct and find the address of a member. KUBSan complains about this so
    replace with the __offsetof and __containerof macros that use either a
    builtin function where available, or the same NULL pointer on older
    compilers without the builtin.
    
    Reviewers: hselasky
    
    Subscribers: imp
    
    Reviewed by:    hselasky
    Sponsored by:   The FreeBSD Foundation
    Differential Revision: https://reviews.freebsd.org/D33865
    
    (cherry picked from commit a3cea156801790d0bbbb4cd9bede0ece8742af82)
---
 sys/dev/usb/controller/atmegadci.c |  3 +--
 sys/dev/usb/controller/avr32dci.c  |  3 +--
 sys/dev/usb/controller/dwc_otg.c   |  3 +--
 sys/dev/usb/controller/musb_otg.c  |  3 +--
 sys/dev/usb/controller/uss820dci.c |  3 +--
 sys/dev/usb/controller/xhci.c      | 12 ++++++------
 6 files changed, 11 insertions(+), 16 deletions(-)

diff --git a/sys/dev/usb/controller/atmegadci.c b/sys/dev/usb/controller/atmegadci.c
index 1f91948c4ccd..a52b8ef0c19c 100644
--- a/sys/dev/usb/controller/atmegadci.c
+++ b/sys/dev/usb/controller/atmegadci.c
@@ -79,8 +79,7 @@
 #include <dev/usb/controller/atmegadci.h>
 
 #define	ATMEGA_BUS2SC(bus) \
-   ((struct atmegadci_softc *)(((uint8_t *)(bus)) - \
-    ((uint8_t *)&(((struct atmegadci_softc *)0)->sc_bus))))
+    __containerof(bus, struct atmegadci_softc, sc_bus)
 
 #define	ATMEGA_PC2SC(pc) \
    ATMEGA_BUS2SC(USB_DMATAG_TO_XROOT((pc)->tag_parent)->bus)
diff --git a/sys/dev/usb/controller/avr32dci.c b/sys/dev/usb/controller/avr32dci.c
index eaf0f8261b92..d999f1982e9e 100644
--- a/sys/dev/usb/controller/avr32dci.c
+++ b/sys/dev/usb/controller/avr32dci.c
@@ -78,8 +78,7 @@
 #include <dev/usb/controller/avr32dci.h>
 
 #define	AVR32_BUS2SC(bus) \
-   ((struct avr32dci_softc *)(((uint8_t *)(bus)) - \
-    ((uint8_t *)&(((struct avr32dci_softc *)0)->sc_bus))))
+    __containerof(bus, struct avr32dci_softc, sc_bus)
 
 #define	AVR32_PC2SC(pc) \
    AVR32_BUS2SC(USB_DMATAG_TO_XROOT((pc)->tag_parent)->bus)
diff --git a/sys/dev/usb/controller/dwc_otg.c b/sys/dev/usb/controller/dwc_otg.c
index 421b95593b3a..869c44c3bb1a 100644
--- a/sys/dev/usb/controller/dwc_otg.c
+++ b/sys/dev/usb/controller/dwc_otg.c
@@ -90,8 +90,7 @@
 #include <dev/usb/controller/dwc_otgreg.h>
 
 #define	DWC_OTG_BUS2SC(bus) \
-   ((struct dwc_otg_softc *)(((uint8_t *)(bus)) - \
-    ((uint8_t *)&(((struct dwc_otg_softc *)0)->sc_bus))))
+    __containerof(bus, struct dwc_otg_softc, sc_bus)
 
 #define	DWC_OTG_PC2UDEV(pc) \
    (USB_DMATAG_TO_XROOT((pc)->tag_parent)->udev)
diff --git a/sys/dev/usb/controller/musb_otg.c b/sys/dev/usb/controller/musb_otg.c
index 24eba2a9a552..9dd24a837316 100644
--- a/sys/dev/usb/controller/musb_otg.c
+++ b/sys/dev/usb/controller/musb_otg.c
@@ -82,8 +82,7 @@
 #define	MUSBOTG_INTR_ENDPT 1
 
 #define	MUSBOTG_BUS2SC(bus) \
-   ((struct musbotg_softc *)(((uint8_t *)(bus)) - \
-   USB_P2U(&(((struct musbotg_softc *)0)->sc_bus))))
+    __containerof(bus, struct musbotg_softc, sc_bus)
 
 #define	MUSBOTG_PC2SC(pc) \
    MUSBOTG_BUS2SC(USB_DMATAG_TO_XROOT((pc)->tag_parent)->bus)
diff --git a/sys/dev/usb/controller/uss820dci.c b/sys/dev/usb/controller/uss820dci.c
index b2e112b07f6e..4fc6d5dbfea2 100644
--- a/sys/dev/usb/controller/uss820dci.c
+++ b/sys/dev/usb/controller/uss820dci.c
@@ -77,8 +77,7 @@
 #include <dev/usb/controller/uss820dci.h>
 
 #define	USS820_DCI_BUS2SC(bus) \
-   ((struct uss820dci_softc *)(((uint8_t *)(bus)) - \
-    ((uint8_t *)&(((struct uss820dci_softc *)0)->sc_bus))))
+    __containerof(bus, struct uss820dci_softc, sc_bus)
 
 #define	USS820_DCI_PC2SC(pc) \
    USS820_DCI_BUS2SC(USB_DMATAG_TO_XROOT((pc)->tag_parent)->bus)
diff --git a/sys/dev/usb/controller/xhci.c b/sys/dev/usb/controller/xhci.c
index 10e37c97c254..db2aad057bc0 100644
--- a/sys/dev/usb/controller/xhci.c
+++ b/sys/dev/usb/controller/xhci.c
@@ -336,7 +336,7 @@ xhci_reset_command_queue_locked(struct xhci_softc *sc)
 	/* set up command ring control base address */
 	addr = buf_res.physaddr;
 	phwr = buf_res.buffer;
-	addr += (uintptr_t)&((struct xhci_hw_root *)0)->hwr_commands[0];
+	addr += __offsetof(struct xhci_hw_root, hwr_commands[0]);
 
 	DPRINTF("CRCR=0x%016llx\n", (unsigned long long)addr);
 
@@ -392,7 +392,7 @@ xhci_start_controller(struct xhci_softc *sc)
 	memset(pdctxa, 0, sizeof(*pdctxa));
 
 	addr = buf_res.physaddr;
-	addr += (uintptr_t)&((struct xhci_dev_ctx_addr *)0)->qwSpBufPtr[0];
+	addr += __offsetof(struct xhci_dev_ctx_addr, qwSpBufPtr[0]);
 
 	/* slot 0 points to the table of scratchpad pointers */
 	pdctxa->qwBaaDevCtxAddr[0] = htole64(addr);
@@ -423,7 +423,7 @@ xhci_start_controller(struct xhci_softc *sc)
 
 	phwr = buf_res.buffer;
 	addr = buf_res.physaddr;
-	addr += (uintptr_t)&((struct xhci_hw_root *)0)->hwr_events[0];
+	addr += __offsetof(struct xhci_hw_root, hwr_events[0]);
 
 	/* reset hardware root structure */
 	memset(phwr, 0, sizeof(*phwr));
@@ -463,7 +463,7 @@ xhci_start_controller(struct xhci_softc *sc)
 
 	/* set up command ring control base address */
 	addr = buf_res.physaddr;
-	addr += (uintptr_t)&((struct xhci_hw_root *)0)->hwr_commands[0];
+	addr += __offsetof(struct xhci_hw_root, hwr_commands[0]);
 
 	DPRINTF("CRCR=0x%016llx\n", (unsigned long long)addr);
 
@@ -1152,7 +1152,7 @@ xhci_interrupt_poll(struct xhci_softc *sc)
 	 */
 
 	addr = buf_res.physaddr;
-	addr += (uintptr_t)&((struct xhci_hw_root *)0)->hwr_events[i];
+	addr += __offsetof(struct xhci_hw_root, hwr_events[i]);
 
 	/* try to clear busy bit */
 	addr |= XHCI_ERDP_LO_BUSY;
@@ -1216,7 +1216,7 @@ retry:
 	usb_pc_cpu_flush(&sc->sc_hw.root_pc);
 
 	addr = buf_res.physaddr;
-	addr += (uintptr_t)&((struct xhci_hw_root *)0)->hwr_commands[i];
+	addr += __offsetof(struct xhci_hw_root, hwr_commands[i]);
 
 	sc->sc_cmd_addr = htole64(addr);