]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: fix use-after-free in {address,route}_remove_and_cancel()
authorYu Watanabe <watanabe.yu+github@gmail.com>
Mon, 26 Feb 2024 03:09:52 +0000 (12:09 +0900)
committerLuca Boccassi <luca.boccassi@gmail.com>
Mon, 26 Feb 2024 11:02:13 +0000 (11:02 +0000)
Fixes #31485.

src/network/networkd-address.c
src/network/networkd-route.c

index e301cf153d6ad474386b8ff54eda42d12ce6e11c..49a43753c5e7bdffa1050573fc795cd60b9e5b4f 100644 (file)
@@ -1180,8 +1180,8 @@ int address_remove(Address *address, Link *link) {
 }
 
 int address_remove_and_cancel(Address *address, Link *link) {
+        _cleanup_(request_unrefp) Request *req = NULL;
         bool waiting = false;
-        Request *req;
 
         assert(address);
         assert(link);
@@ -1193,6 +1193,7 @@ int address_remove_and_cancel(Address *address, Link *link) {
         /* Cancel the request for the address.  If the request is already called but we have not received the
          * notification about the request, then explicitly remove the address. */
         if (address_get_request(link, address, &req) >= 0) {
+                request_ref(req); /* avoid the request freed by request_detach() */
                 waiting = req->waiting_reply;
                 request_detach(req);
                 address_cancel_requesting(address);
index ee12f1664abe46b6a2b2db8e8e1a0e5808434d86..3c5de98e7c96181439a0b640855f4d0750302890 100644 (file)
@@ -600,8 +600,8 @@ int route_remove(Route *route, Manager *manager) {
 }
 
 int route_remove_and_cancel(Route *route, Manager *manager) {
+        _cleanup_(request_unrefp) Request *req = NULL;
         bool waiting = false;
-        Request *req;
 
         assert(route);
         assert(manager);
@@ -612,6 +612,7 @@ int route_remove_and_cancel(Route *route, Manager *manager) {
         /* Cancel the request for the route. If the request is already called but we have not received the
          * notification about the request, then explicitly remove the route. */
         if (route_get_request(manager, route, &req) >= 0) {
+                request_ref(req); /* avoid the request freed by request_detach() */
                 waiting = req->waiting_reply;
                 request_detach(req);
                 route_cancel_requesting(route);