https://lists.gnumonks.org/pipermail/ulogd/2005-August/000776.html
authorMark Huang <mlhuang@cs.princeton.edu>
Thu, 10 Aug 2006 17:50:14 +0000 (17:50 +0000)
committerMark Huang <mlhuang@cs.princeton.edu>
Thu, 10 Aug 2006 17:50:14 +0000 (17:50 +0000)
http://lists.netfilter.org/pipermail/netfilter/2006-January/064509.html
https://lists.gnumonks.org/pipermail/ulogd/2006-April/000853.html

Fix kernel panic on various SMP machines. The culprit is a null ub->skb
in ulog_send(). I believe that this can occur for the following
reason. If ulog_timer() has already been scheduled on one CPU and is
spinning on the lock, and ipt_ulog_packet() flushes the queue on another
CPU by calling ulog_send() right before it exits (because the threshold
is reached), there will be no skbuff when ulog_timer() acquires the lock
and calls ulog_send(). Cancelling the timer in ulog_send() doesn't help
because it has already been scheduled and is running on the first CPU.

There are two solutions that I can see: re-allocate ub->skb at the end of
ipt_ulog_packet(), just like it does toward the beginning of the function. But
the problem will still happen if the allocation fails. The second solution,
is to just return from ulog_send() if ub->skb is null.

net/ipv4/netfilter/ipt_ULOG.c

index c84cc03..f2b2171 100644 (file)
@@ -120,6 +120,11 @@ static void ulog_send(unsigned int nlgroupnum)
        if (ub->qlen > 1)
                ub->lastnlh->nlmsg_type = NLMSG_DONE;
 
+       if (!ub->skb) {
+               DEBUGP("ipt_ULOG: ulog_send: nothing to send\n");
+               return;
+       }
+
        NETLINK_CB(ub->skb).dst_group = nlgroupnum + 1;
        DEBUGP("ipt_ULOG: throwing %d packets to netlink group %u\n",
                ub->qlen, nlgroupnum + 1);