From: Yu Watanabe Date: Mon, 26 Feb 2024 03:09:52 +0000 (+0900) Subject: network: fix use-after-free in {address,route}_remove_and_cancel() X-Git-Tag: v256-rc1~734 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7036d472d016c98038347ecae86c2f0fac9a0f85;p=thirdparty%2Fsystemd.git network: fix use-after-free in {address,route}_remove_and_cancel() Fixes #31485. --- diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index e301cf153d6..49a43753c5e 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -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); diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index ee12f1664ab..3c5de98e7c9 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -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);