Synchronet now requires the libarchive development package (e.g. libarchive-dev on Debian-based Linux distros, for more info) to build successfully.

Commit e3892691 authored by rswindell's avatar rswindell
Browse files

Implement a simple bound-checker in RingBufWrite():

if the ringbuf is shared among multiple threads (e.g. the sbbs->outbuf is
shared between output_thread() and passthru_thread()) - it was possible
for a race condition to occur between the caller would call RingBufFree
to determine the available space in the ringbuf and the call to RingBufWrite
which would happily overflow the allocated buffer if more data was
written to the ringbuf (by another thread) in the unprotected time between the
RingBufFree and RingBufWrite calls.

Now, RingBufWrite() can perform short-writes and will return a length less
than what was requested to write when there is not enough available space
to write the requested length.

Hopefully this resolves the corruption/crash issue Deuce is seeing in
sbbs's passthru_thread().
parent f3e14e0d
......@@ -165,7 +165,7 @@ DWORD RINGBUFCALL RingBufFree( RingBuf* rb )
DWORD RINGBUFCALL RingBufWrite( RingBuf* rb, const BYTE* src, DWORD cnt )
DWORD max, first, remain;
DWORD max, first, remain, fill_level;
......@@ -180,10 +180,9 @@ DWORD RINGBUFCALL RingBufWrite( RingBuf* rb, const BYTE* src, DWORD cnt )
/* allowed to write at pEnd */
max = rb->pEnd - rb->pHead + 1;
* we assume the caller has checked that there is enough room. For this reason
* we do not have to worry about head wrapping past the tail
fill_level = RINGBUF_FILL_LEVEL(rb);
if(fill_level + cnt > rb->size)
cnt = rb->size - fill_level;
if( max >= cnt ) {
first = cnt;
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment