inetd crashes VKERNEL
Nicolas Thery
nthery at gmail.com
Sat Jul 5 08:05:07 PDT 2008
2008/7/4 Thomas Nikolajsen <thomas.nikolajsen at mail.dk>:
> inetd crashes VKERNEL, see below;
> it crashes almost every time.
>
> Also: I get no DDB prompt when VKERNEL crashes;
> using vkernel w/o SMP I do get DDB prompt.
>
> -thomas
> -
> root at vonzales0# inetd
> root at vonzales0# panic: memory chunk 0x53f09190 is already free!
> mp_lock = 00000001; cpuid = 1
> Trace beginning at frame 0x56fc3b38
> panic(56fc3b5c,53f09190,53f080d0,53f09190,56fc3b84) at 0x80b3e80
> panic(81f607c,53f09190,53f09190,53f08000,4140048c) at 0x80b3e80
> kfree(53f09190,8226980,281460a0,1,0) at 0x80b196f
> so_pru_ctloutput(567f1ea0,56fc3c54,570bff00,56fc3c07,53f347a8) at 0x80e35b2
> sosetopt(567f1ea0,56fc3c54,56ffdaf0,822028c,5671fb98) at 0x80e45e4
> kern_setsockopt(4,56fc3c54,1,0,15) at 0x80e7a54
> sys_setsockopt(56fc3c98,6,0,0,56707c80) at 0x80e84c4
I can't reproduce the bug maybe because the suspicious code I mention
below seems
exercised by IPv6 only and I haven't configured that.
It looks like so_pru_ctloutput() passes an invalid sopt_val to
kfree(). This code was changed
recently:
http://leaf.dragonflybsd.org/mailarchive/commits/2008-06/msg00123.html
There is some pointer arithmetic on sopt_val in soopt_mcopyout() that
may cause the panic you
observe. sopt_val ends up pointing past the data copied from the
mbuf. Maybe this is
intentional as the code is old (imported straight from fbsd 4 and is
still in fbsd head). This
would allow to append more data later on. On the other hand, maybe
that's a bug. Only a
networking savvy person could say.
In the latter case, you could try the following (untested) patch:
Index: src2/sys/kern/uipc_socket.c
===================================================================
--- src2.orig/sys/kern/uipc_socket.c 2008-06-27 18:24:46.000000000 +0200
+++ src2/sys/kern/uipc_socket.c 2008-07-05 12:08:49.000000000 +0200
@@ -1646,23 +1646,24 @@ soopt_mcopyout(struct sockopt *sopt, str
{
struct mbuf *m0 = m;
size_t valsize = 0;
+ void *val;
if (sopt->sopt_val == NULL)
return 0;
+ val = sopt->sopt_val;
while (m != NULL && sopt->sopt_valsize >= m->m_len) {
if (sopt->sopt_td != NULL) {
int error;
- error = copyout(mtod(m, char *), sopt->sopt_val,
- m->m_len);
+ error = copyout(mtod(m, char *), val, m->m_len);
if (error != 0) {
m_freem(m0);
return (error);
}
} else
- bcopy(mtod(m, char *), sopt->sopt_val, m->m_len);
+ bcopy(mtod(m, char *), val, m->m_len);
sopt->sopt_valsize -= m->m_len;
- sopt->sopt_val = (caddr_t)sopt->sopt_val + m->m_len;
+ val = (caddr_t)val + m->m_len;
valsize += m->m_len;
m = m->m_next;
}
Cheers,
Nicolas
More information about the Bugs
mailing list