Off by one in milter-greylist.c
2009-06-28 by Pascal Lalonde
Hello,
I hit a bug while running milter-greylist (from CVS, 4.3.2, on OpenBSD 4.5).
Some message would make milter-greylist segfault:
Program received signal SIGSEGV, Segmentation fault.
[Switching to process 2409, thread 0x833bd000]
0x01813e55 in memcpy () from /usr/lib/libc.so.50.1
(gdb) bt
#0 0x01813e55 in memcpy () from /usr/lib/libc.so.50.1
#1 0x1c003dae in real_body (ctx=0x85ab4c00, chunk=0x87389750 "On Fri,
Jun 19, 2009 at 09:47:35AM +0100, Michal wrote:\r\n> Someone once
said this too me\r\n> \r\n> \"Comparing FreeBSD and OpenBSD, FreeBSD
is generally better at disk-related\r\n> I/O whereas OpenBSD
handl"..., size=2224) at milter-greylist.c:853
#2 0x1c0028f6 in mlfi_body (ctx=0x85ab4c00, chunk=0x87389750 "On Fri,
Jun 19, 2009 at 09:47:35AM +0100, Michal wrote:\r\n> Someone once
said this too me\r\n> \r\n> \"Comparing FreeBSD and OpenBSD, FreeBSD
is generally better at disk-related\r\n> I/O whereas OpenBSD
handl"..., size=2224) at milter-greylist.c:252
#3 0x0c6b6f36 in st_bodychunk (g=0x8b1) at
/usr/src/gnu/usr.sbin/sendmail/libmilter/engine.c:1428
#4 0x0c6b5eb9 in mi_engine (ctx=0x85ab4c00) at
/usr/src/gnu/usr.sbin/sendmail/libmilter/engine.c:404
#5 0x0c6b5c19 in mi_handle_session (ctx=0x85ab4c00) at
/usr/src/gnu/usr.sbin/sendmail/libmilter/handler.c:45
#6 0x0c6b52ab in mi_thread_handle_wrapper (arg=0x85ab4c00) at
/usr/src/gnu/usr.sbin/sendmail/libmilter/listener.c:579
#7 0x0f18337f in _thread_start () at
/usr/src/lib/libpthread/uthread/uthread_create.c:240
#8 0x0000002b in ?? ()
#9 0x00000000 in ?? ()
(gdb) frame 1
#1 0x1c003dae in real_body (ctx=0x85ab4c00, chunk=0x87389750 "On Fri,
Jun 19, 2009 at 09:47:35AM +0100, Michal wrote:\r\n> Someone once
said this too me\r\n> \r\n> \"Comparing FreeBSD and OpenBSD,
FreeBSD is generally better at disk-related\r\n> I/O whereas
OpenBSD handl"..., size=2224) at milter-greylist.c:853
853 memcpy(b->b_lines + priv->priv_buflen, chunk, i + 1);
(gdb) info locals
stat = 0
priv = (struct mlfi_priv *) 0x8b189800
b = (struct body *) 0x7e414ee0
linelen = 2224
i = 2224
(gdb) frame 2
#2 0x1c0028f6 in mlfi_body (ctx=0x85ab4c00, chunk=0x87389750 "On Fri,
Jun 19, 2009 at 09:47:35AM +0100, Michal wrote:\r\n> Someone once
said this too me\r\n> \r\n> \"Comparing FreeBSD and OpenBSD, FreeBSD
is generally better at disk-related\r\n> I/O whereas OpenBSD
handl"..., size=2224) at milter-greylist.c:252
252 r = real_body(ctx, chunk, size);
(gdb) info locals
r = 0
(gdb) inspect chunk
$5 = (unsigned char *) 0x87389750 "On Fri, Jun 19, 2009 at 09:47:35AM
+0100, Michal wrote:\r\n> Someone once said this too me\r\n> \r\n>
\"Comparing FreeBSD and OpenBSD, FreeBSD is generally better at
disk-related\r\n> I/O whereas OpenBSD handl"...
(gdb) inspect size
$6 = 2224
(gdb) inspect linelen
$12 = 2224
(gdb) inspect i
$13 = 2224
(gdb) inspect chunk[2224]
Cannot access memory at address 0x8738a000
(gdb) inspect chunk[2223]
$14 = 10 '\n'
The following seems to fix the issue. I've been running for a week without
crashes:
Index: milter-greylist.c
===================================================================
RCS file: /milter-greylist/milter-greylist/milter-greylist.c,v
retrieving revision 1.219
diff -u -r1.219 milter-greylist.c
--- milter-greylist.c 23 May 2009 22:55:25 -0000 1.219
+++ milter-greylist.c 28 Jun 2009 18:45:48 -0000
@@ -850,7 +850,7 @@
priv->priv_buf = NULL;
}
- memcpy(b->b_lines + priv->priv_buflen, chunk, i + 1);
+ memcpy(b->b_lines + priv->priv_buflen, chunk, i);
b->b_lines[linelen] = '\0';
priv->priv_buflen = 0;
Makes sense, since a few lines ealier you have:
++i; /* Use i as byte counter */
--
Pascal