summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2016-01-12 16:06:21 +0100
committerThomas Haller <thaller@redhat.com>2016-01-12 16:24:38 +0100
commit2b54bd6a53b165f12b8eefe5232ea20cc9d3440c (patch)
tree457762212e93f04f40d60577ffd48c502595065d
parentddc6d97f00e81cd422bb4d48adcadff70018de0f (diff)
dispatcher: fix use-after-free in complete_script()
complete_request() possibly frees the request, making the @script and @request a dangling pointer. We must not use those pointers, except a plain pointer- comparison.
-rw-r--r--callouts/nm-dispatcher.c24
1 files changed, 13 insertions, 11 deletions
diff --git a/callouts/nm-dispatcher.c b/callouts/nm-dispatcher.c
index 7106103e30..43d34eb7e7 100644
--- a/callouts/nm-dispatcher.c
+++ b/callouts/nm-dispatcher.c
@@ -323,21 +323,25 @@ static void
complete_script (ScriptInfo *script)
{
Handler *handler;
+ Request *request;
gboolean wait = script->wait;
+ request = script->request;
+
if (wait) {
/* for "wait" scripts, try to schedule the next blocking script.
* If that is successful, return (as we must wait for its completion). */
- if (dispatch_one_script (script->request))
+ if (dispatch_one_script (request))
return;
}
- handler = script->request->handler;
+ handler = request->handler;
- nm_assert (!wait || handler->current_request == script->request);
+ nm_assert (!wait || handler->current_request == request);
- /* Try to complete the request. */
- complete_request (script->request);
+ /* Try to complete the request. @request will be possibly free'd,
+ * making @script and @request a dangling pointer. */
+ complete_request (request);
if (!wait) {
/* this was a "no-wait" script. We either completed the request,
@@ -346,20 +350,18 @@ complete_script (ScriptInfo *script)
* requests. However, if this was the last "no-wait" script and
* there are "wait" scripts ready to run, launch them.
*/
- if ( handler->current_request == script->request
- && script->request->num_scripts_nowait == 0) {
+ if ( handler->current_request == request
+ && handler->current_request->num_scripts_nowait == 0) {
- if (dispatch_one_script (script->request))
+ if (dispatch_one_script (handler->current_request))
return;
- complete_request (script->request);
+ complete_request (handler->current_request);
} else
return;
}
while (next_request (handler, NULL)) {
- Request *request;
-
request = handler->current_request;
if (dispatch_one_script (request))