Skip to content

Commit

Permalink
esx_stream: Fix NULL dereferences
Browse files Browse the repository at this point in the history
A wrong reordering caused "priv" to be derefenced before the NULL-check
in esxStreamSend and esxStreamRecvFlags.

Fixes: 12e19f1
Signed-off-by: Tim Wiederhake <[email protected]>
Reviewed-by: Michal Privoznik <[email protected]>
  • Loading branch information
Tim Wiederhake committed Mar 17, 2022
1 parent 1dfd308 commit 5e1da78
Showing 1 changed file with 55 additions and 47 deletions.
102 changes: 55 additions & 47 deletions src/esx/esx_stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,8 +198,8 @@ esxStreamTransfer(esxStreamPrivate *priv, bool blocking)
static int
esxStreamSend(virStreamPtr stream, const char *data, size_t nbytes)
{
int result = -1;
esxStreamPrivate *priv = stream->privateData;
VIR_LOCK_GUARD lock = virLockGuardLock(&priv->curl->lock);

if (nbytes == 0)
return 0;
Expand All @@ -214,29 +214,33 @@ esxStreamSend(virStreamPtr stream, const char *data, size_t nbytes)
return -1;
}

priv->buffer = (char *)data;
priv->buffer_size = nbytes;
priv->buffer_used = nbytes;
VIR_WITH_MUTEX_LOCK_GUARD(&priv->curl->lock) {
priv->buffer = (char *)data;
priv->buffer_size = nbytes;
priv->buffer_used = nbytes;

if (stream->flags & VIR_STREAM_NONBLOCK) {
if (esxStreamTransfer(priv, false) < 0)
return -1;
if (stream->flags & VIR_STREAM_NONBLOCK) {
if (esxStreamTransfer(priv, false) < 0)
return -1;

if (priv->buffer_used >= priv->buffer_size)
return -2;
} else /* blocking */ {
do {
int status = esxStreamTransfer(priv, true);
if (priv->buffer_used >= priv->buffer_size)
return -2;
} else /* blocking */ {
do {
int status = esxStreamTransfer(priv, true);

if (status < 0)
return -1;
if (status < 0)
return -1;

if (status > 0)
break;
} while (priv->buffer_used > 0);
}

if (status > 0)
break;
} while (priv->buffer_used > 0);
result = priv->buffer_size - priv->buffer_used;
}

return priv->buffer_size - priv->buffer_used;
return result;
}

static int
Expand All @@ -245,8 +249,8 @@ esxStreamRecvFlags(virStreamPtr stream,
size_t nbytes,
unsigned int flags)
{
int result = -1;
esxStreamPrivate *priv = stream->privateData;
VIR_LOCK_GUARD lock = virLockGuardLock(&priv->curl->lock);

virCheckFlags(0, -1);

Expand All @@ -263,40 +267,44 @@ esxStreamRecvFlags(virStreamPtr stream,
return -1;
}

priv->buffer = data;
priv->buffer_size = nbytes;
priv->buffer_used = 0;

if (priv->backlog_used > 0) {
if (priv->buffer_size > priv->backlog_used)
priv->buffer_used = priv->backlog_used;
else
priv->buffer_used = priv->buffer_size;
VIR_WITH_MUTEX_LOCK_GUARD(&priv->curl->lock) {
priv->buffer = data;
priv->buffer_size = nbytes;
priv->buffer_used = 0;

if (priv->backlog_used > 0) {
if (priv->buffer_size > priv->backlog_used)
priv->buffer_used = priv->backlog_used;
else
priv->buffer_used = priv->buffer_size;

memcpy(priv->buffer, priv->backlog, priv->buffer_used);
memmove(priv->backlog, priv->backlog + priv->buffer_used,
priv->backlog_used - priv->buffer_used);

priv->backlog_used -= priv->buffer_used;
} else if (stream->flags & VIR_STREAM_NONBLOCK) {
if (esxStreamTransfer(priv, false) < 0)
return -1;

memcpy(priv->buffer, priv->backlog, priv->buffer_used);
memmove(priv->backlog, priv->backlog + priv->buffer_used,
priv->backlog_used - priv->buffer_used);
if (priv->buffer_used <= 0)
return -2;
} else /* blocking */ {
do {
int status = esxStreamTransfer(priv, true);

priv->backlog_used -= priv->buffer_used;
} else if (stream->flags & VIR_STREAM_NONBLOCK) {
if (esxStreamTransfer(priv, false) < 0)
return -1;
if (status < 0)
return -1;

if (priv->buffer_used <= 0)
return -2;
} else /* blocking */ {
do {
int status = esxStreamTransfer(priv, true);

if (status < 0)
return -1;
if (status > 0)
break;
} while (priv->buffer_used < priv->buffer_size);
}

if (status > 0)
break;
} while (priv->buffer_used < priv->buffer_size);
result = priv->buffer_used;
}

return priv->buffer_used;
return result;
}

static int
Expand Down

0 comments on commit 5e1da78

Please sign in to comment.