Bug #1041

inetd crashes VKERNEL

Added by thomas.nikolajsen almost 6 years ago. Updated almost 6 years ago.

Status:ClosedStart date:
Priority:NormalDue date:
Assignee:-% Done:

0%

Category:-
Target version:-

Description

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@vonzales0# inetd
root@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
syscall2(56fc3d40,6,53f348c8,56707c80,0) at 0x81e036e
user_trap(56fc3d40,53f348c8,81df98c,0,81e0ba2) at 0x81e0598
go_user(56fc3d38,0,0,7b,0) at 0x81e099b
Debugger("panic")

CPU1 stopping CPUs: 0x00000001

History

#1 Updated by nthery almost 6 years ago

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

#2 Updated by nthery almost 6 years ago

Forget this, soopt_mcopyout() is called during getsockopt() but the
crash ocurred during setsockopt()...

#3 Updated by aoiko almost 6 years ago

I'm not a networking savvy person (working on it) but having spent some time
on ctloutput functions lately it seems like an outright bug to me. Even if
some code was depending on it, this behavior violates POLA and would need to
go anyway.

Right, but soopt_mcopyin() does the exact same thing ;) Nice catch. Things
seem to work here with these two changes (+ SOPTF_KVA), wanna commit it?

Aggelos

#4 Updated by nthery almost 6 years ago

Oops missed that. Thanks.

Ok. I'll fix soopt_mcopy{in,out} tonight.

Cheers,
Nicolas

#5 Updated by nthery almost 6 years ago

Done.

#6 Updated by thomas.nikolajsen almost 6 years ago

Thanks!

I can't crash vkernel anymore.

-thomas

Also available in: Atom PDF