Skip to content

Commit

Permalink
api: fix a buffer overflow in x86emu_log()
Browse files Browse the repository at this point in the history
There seems to be an assumption that vsnprintf() returns a number of
characters that were written. That is actually not the case -- it
returns number of characters that *would* have been written regardless
of truncation to specified size.

Therefore, on x86emu_log() that would cross the buffer end will move
.log.ptr beyond the end of the buffer, and the subsequent .flush()
will be called back with a size argument larger than the buffer.

Moreover, given the .flush() is essentially only invoked upon
x86emu_clear_log(), this is almost bound to happen for instances that
run for a long time.

Let's solve the buffer fillup differently: 1.) flush the buffer when it
fills up (we'd be crossing the buffer boundary) and 2.) make sure
.log.ptr is allways clipped to point inside the allocated buffer.
  • Loading branch information
lkundrak committed Nov 3, 2024
1 parent 5c7c8f7 commit b211241
Showing 1 changed file with 13 additions and 11 deletions.
24 changes: 13 additions & 11 deletions api.c
Original file line number Diff line number Diff line change
Expand Up @@ -337,19 +337,21 @@ API_SYM void x86emu_log(x86emu_t *emu, const char *format, ...)

if(!emu || !emu->log.ptr) return;

size = emu->log.size - (emu->log.ptr - emu->log.buf);

va_start(args, format);
if(size > 0) {
size = vsnprintf(emu->log.ptr, size, format, args);
if(size > 0) {
emu->log.ptr += size;
}
else {
*emu->log.ptr = 0;
}
size = vsnprintf(emu->log.ptr, LOG_FREE(emu), format, args);
va_end(args);

if (emu->log.ptr + size > emu->log.buf + emu->log.size) {
x86emu_clear_log(emu, 1);
va_start(args, format);
size = vsnprintf(emu->log.ptr, emu->log.size, format, args);
va_end(args);
}
va_end(args);

if (size > 0)
emu->log.ptr += size;
if (emu->log.ptr > emu->log.buf + emu->log.size)
emu->log.ptr = emu->log.buf + emu->log.size;
}


Expand Down

0 comments on commit b211241

Please sign in to comment.