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.
This commit is contained in:
@@ -323,21 +323,25 @@ static void
|
|||||||
complete_script (ScriptInfo *script)
|
complete_script (ScriptInfo *script)
|
||||||
{
|
{
|
||||||
Handler *handler;
|
Handler *handler;
|
||||||
|
Request *request;
|
||||||
gboolean wait = script->wait;
|
gboolean wait = script->wait;
|
||||||
|
|
||||||
|
request = script->request;
|
||||||
|
|
||||||
if (wait) {
|
if (wait) {
|
||||||
/* for "wait" scripts, try to schedule the next blocking script.
|
/* for "wait" scripts, try to schedule the next blocking script.
|
||||||
* If that is successful, return (as we must wait for its completion). */
|
* If that is successful, return (as we must wait for its completion). */
|
||||||
if (dispatch_one_script (script->request))
|
if (dispatch_one_script (request))
|
||||||
return;
|
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. */
|
/* Try to complete the request. @request will be possibly free'd,
|
||||||
complete_request (script->request);
|
* making @script and @request a dangling pointer. */
|
||||||
|
complete_request (request);
|
||||||
|
|
||||||
if (!wait) {
|
if (!wait) {
|
||||||
/* this was a "no-wait" script. We either completed the request,
|
/* 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
|
* requests. However, if this was the last "no-wait" script and
|
||||||
* there are "wait" scripts ready to run, launch them.
|
* there are "wait" scripts ready to run, launch them.
|
||||||
*/
|
*/
|
||||||
if ( handler->current_request == script->request
|
if ( handler->current_request == request
|
||||||
&& script->request->num_scripts_nowait == 0) {
|
&& handler->current_request->num_scripts_nowait == 0) {
|
||||||
|
|
||||||
if (dispatch_one_script (script->request))
|
if (dispatch_one_script (handler->current_request))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
complete_request (script->request);
|
complete_request (handler->current_request);
|
||||||
} else
|
} else
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (next_request (handler, NULL)) {
|
while (next_request (handler, NULL)) {
|
||||||
Request *request;
|
|
||||||
|
|
||||||
request = handler->current_request;
|
request = handler->current_request;
|
||||||
|
|
||||||
if (dispatch_one_script (request))
|
if (dispatch_one_script (request))
|
||||||
|
Reference in New Issue
Block a user