summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel P. Berrange <berrange@redhat.com>2016-09-06 14:56:02 +0100
committerPaolo Bonzini <pbonzini@redhat.com>2016-09-13 19:09:42 +0200
commitb72981b910097b31f4d0b9c111a2d2cfd9ee585b (patch)
treefd4b43d72ea6e6c55b2083e6ed4548ceb44f85aa
parente270d00afa58c8a2903ec85db51407abc4e3269d (diff)
downloadqemu-b72981b910097b31f4d0b9c111a2d2cfd9ee585b.tar.gz
qemu-b72981b910097b31f4d0b9c111a2d2cfd9ee585b.tar.bz2
qemu-b72981b910097b31f4d0b9c111a2d2cfd9ee585b.zip
ipmi: check return of qemu_chr_fe_write() for errors
The continue_send() method in ipmi_bmc_extern.c directly assigns the return value of qemu_chr_fe_write() to the variable tracking the I/O buffer offset. This ignores the possibility that the return value could be -1 and so will cause I/O go backwards on EAGAIN. Fortunately 'outpos' is unsigned, so can't go negative - it will become MAX_INT which will cause the loop to stop, and avoid an accidental out of bounds array access. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> Message-Id: <1473170165-540-2-git-send-email-berrange@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--hw/ipmi/ipmi_bmc_extern.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/hw/ipmi/ipmi_bmc_extern.c b/hw/ipmi/ipmi_bmc_extern.c
index 5b73983e7d..d93e3f3426 100644
--- a/hw/ipmi/ipmi_bmc_extern.c
+++ b/hw/ipmi/ipmi_bmc_extern.c
@@ -100,12 +100,16 @@ ipmb_checksum(const unsigned char *data, int size, unsigned char start)
static void continue_send(IPMIBmcExtern *ibe)
{
+ int ret;
if (ibe->outlen == 0) {
goto check_reset;
}
send:
- ibe->outpos += qemu_chr_fe_write(ibe->chr, ibe->outbuf + ibe->outpos,
- ibe->outlen - ibe->outpos);
+ ret = qemu_chr_fe_write(ibe->chr, ibe->outbuf + ibe->outpos,
+ ibe->outlen - ibe->outpos);
+ if (ret > 0) {
+ ibe->outpos += ret;
+ }
if (ibe->outpos < ibe->outlen) {
/* Not fully transmitted, try again in a 10ms */
timer_mod_ns(ibe->extern_timer,