git: c59a5fbd8a2e - main - ena: Fix driver unload crash

From: Marcin Wojtas <mw_at_FreeBSD.org>
Date: Tue, 04 Jul 2023 14:00:11 UTC
The branch main has been updated by mw:

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

commit c59a5fbd8a2ef68ed0842cbb1df4450edd654129
Author:     Arthur Kiyanovski <akiyano@amazon.com>
AuthorDate: 2023-05-21 12:31:54 +0000
Commit:     Marcin Wojtas <mw@FreeBSD.org>
CommitDate: 2023-07-04 13:57:15 +0000

    ena: Fix driver unload crash
    
    When ena_detach is called, we first call ether_ifdetach(),
    which destroys internal addresses of ifp. One such address
    is ifp->if_addr->ifa_addr. Then during ena_destroy_device(),
    if_link_state_change() is called, eventually trying to access
    ifp->if_addr->ifa_addr->sa_family. This causes an access
    to garbage memory and crashes the kernel.
    
    Ticket [1] was opened to the FreeBSD community to add null
    check in the code of if_link_state_change().
    A fix was submitted in commit [2], however it was noted
    that it is our driver's responsibilty to not call
    if_link_state_change() after calling ether_ifdetach().
    
    This commit makes sure if_link_state_change() is not called
    after ether_ifdetach().
    
    [1]: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=270813
    [2]: https://reviews.freebsd.org/D39614
    
    Fixes: 32f63fa7f975 ("Split ENA reset routine into restore and destroy stages")
    MFC after: 2 weeks
    Sponsored by: Amazon, Inc.
---
 sys/dev/ena/ena.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sys/dev/ena/ena.c b/sys/dev/ena/ena.c
index a62b99d5ee1b..8429dcd3390f 100644
--- a/sys/dev/ena/ena.c
+++ b/sys/dev/ena/ena.c
@@ -3291,7 +3291,8 @@ ena_destroy_device(struct ena_adapter *adapter, bool graceful)
 	if (!ENA_FLAG_ISSET(ENA_FLAG_DEVICE_RUNNING, adapter))
 		return;
 
-	if_link_state_change(ifp, LINK_STATE_DOWN);
+	if (!graceful)
+		if_link_state_change(ifp, LINK_STATE_DOWN);
 
 	ENA_TIMER_DRAIN(adapter);