Avoid use-after-free on streams, due to message callbacks

When sending outbound stream RPC messages, a callback is
used to re-enable stream data transmission. If the stream
aborts while one of these messages is outstanding, the
stream may have been free'd by the time it is invoked. This
results in a use-after-free error

* daemon/stream.c: Ref-count streams to avoid use-after-free
This commit is contained in:
Daniel P. Berrange 2011-08-31 17:01:01 +01:00
parent b6263c1801
commit 1b72ad2eaa

View File

@ -38,6 +38,7 @@
struct daemonClientStream { struct daemonClientStream {
daemonClientPrivatePtr priv; daemonClientPrivatePtr priv;
int refs;
virNetServerProgramPtr prog; virNetServerProgramPtr prog;
@ -102,6 +103,8 @@ daemonStreamMessageFinished(virNetMessagePtr msg,
stream->tx = 1; stream->tx = 1;
daemonStreamUpdateEvents(stream); daemonStreamUpdateEvents(stream);
daemonFreeClientStream(NULL, stream);
} }
@ -299,6 +302,7 @@ daemonCreateClientStream(virNetServerClientPtr client,
return NULL; return NULL;
} }
stream->refs = 1;
stream->priv = priv; stream->priv = priv;
stream->prog = prog; stream->prog = prog;
stream->procedure = header->proc; stream->procedure = header->proc;
@ -326,6 +330,10 @@ int daemonFreeClientStream(virNetServerClientPtr client,
if (!stream) if (!stream)
return 0; return 0;
stream->refs--;
if (stream->refs)
return 0;
VIR_DEBUG("client=%p, proc=%d, serial=%d", VIR_DEBUG("client=%p, proc=%d, serial=%d",
client, stream->procedure, stream->serial); client, stream->procedure, stream->serial);
@ -727,6 +735,7 @@ daemonStreamHandleRead(virNetServerClientPtr client,
if (msg) { if (msg) {
msg->cb = daemonStreamMessageFinished; msg->cb = daemonStreamMessageFinished;
msg->opaque = stream; msg->opaque = stream;
stream->refs++;
ret = virNetServerProgramSendStreamData(remoteProgram, ret = virNetServerProgramSendStreamData(remoteProgram,
client, client,
msg, msg,