lshd buffer overrun. Possibly remote root compromise.
Niels Möller
nisse@lysator.liu.se
18 Sep 2003 22:29:03 +0200
Summary:
PLEASE DISABLE LSHD SERVICE. Apply below patch.
Simon Josefsson <jas@extundo.com> writes:
> FWIW, I can reproduce it:
>
> lshd: write_buffer: do_write length = 256
> lshd: write_buffer: do_write closure->length = 293
> lshd: garbage collecting...
> lshd: gc_mark: Memory corrupted!
> Aborted
>
> I think it has nothing to do with the actual bits sent, but rather
> that some earlier random data caused the code to take a rarely tested
> execution path, which has garbage collect bugs in it, which is
> discovered a while later.
I'm afraid it's worse than that. It seems to be a genuine buffer
overrun, on the heap. It's the buffer in read_line.c,
/* GABA:
(class
(name read_line)
(super read_handler)
(vars
(handler object line_handler)
(e object exception_handler)
; Line buffer
(pos . uint32_t)
(buffer array uint8_t MAX_LINE)))
*/
The below patch should fix the bug. It's a case of checking for an
error, reporting it, and then forgetting to return from the function.
Instead the code just went on overwriting the buffer. Pretty
embarrassing.
diff -u -a -r1.31 read_line.c
--- src/read_line.c 16 Feb 2003 21:30:11 -0000 1.31
+++ src/read_line.c 18 Sep 2003 20:02:48 -0000
@@ -100,6 +100,7 @@
/* Too long line */
EXCEPTION_RAISE(self->e,
make_protocol_exception(0, "Line too long."));
+ return available;
}
/* Ok, now we have a line. Copy it into the buffer. */
The buggy code was checked in a little more than four years ago,
1999-08-22, at about this time of day.
I'm *not* going to bet that it isn't exploitable. I'll try to get new
releases out within a few days, until then, I recommend that you apply
the above patch to lshd and recompile, or disable lshd service.
Thanks to Bennett Todd for reporting the problem.
Sorry about the trouble. Regards,
/Niels