Re: kernels > v4.12 oops/crash with ipsec-traffic: bisected to b838d5e1c5b6e57b10ec8af2268824041e3ea911: ipv4: mark DST_NOGC and remove the operation of dst_free()
From: Wolfgang Walter <hidden>
Date: 2018-09-08 01:53:41
Hello Steffen, in one of your emails to Thomas you wrote:
xfrm_lookup+0x2a is at the very beginning of xfrm_lookup(), here we find: u16 family = dst_orig->ops->family; ops has an offset of 32 bytes (20 hex) in dst_orig, so looks like dst_orig is NULL. In the forwarding case, we get dst_orig from the skb and dst_orig can't be NULL here unless the skb itself is already fishy.
Is this really true?
If xfrm_lookup is called from
__xfrm_route_forward():
int __xfrm_route_forward(struct sk_buff *skb, unsigned short family)
{
struct net *net = dev_net(skb->dev);
struct flowi fl;
struct dst_entry *dst;
int res = 1;
if (xfrm_decode_session(skb, &fl, family) < 0) {
XFRM_INC_STATS(net, LINUX_MIB_XFRMFWDHDRERROR);
return 0;
}
skb_dst_force(skb);
dst = xfrm_lookup(net, skb_dst(skb), &fl, NULL, XFRM_LOOKUP_QUEUE);
if (IS_ERR(dst)) {
res = 0;
dst = NULL;
}
skb_dst_set(skb, dst);
return res;
}
couldn't it be possible that skb_dst_force(skb) actually sets dst to NULL if
it cannot safely lock it? If it is absolutely sure that skb_dst_force() never
can set dst to NULL I wonder why it is called at all?
Here is skb_dst_force()
static inline void skb_dst_force(struct sk_buff *skb)
{
if (skb_dst_is_noref(skb)) {
struct dst_entry *dst = skb_dst(skb);
WARN_ON(!rcu_read_lock_held());
if (!dst_hold_safe(dst))
dst = NULL;
skb->_skb_refdst = (unsigned long)dst;
}
}
and dst_hold_safe() is
static inline bool dst_hold_safe(struct dst_entry *dst)
{
return atomic_inc_not_zero(&dst->__refcnt);
}
Am Freitag, 7. September 2018, 22:22:39 schrieb Wolfgang Walter:Am Freitag, 31. August 2018, 08:50:24 schrieb Steffen Klassert:quoted
On Thu, Aug 30, 2018 at 08:53:50PM +0200, Wolfgang Walter wrote:quoted
Hello, kernels > 4.12 do not work on one of our main routers. They crash as soon as ipsec-tunnels are configured and ipsec-traffic actually flows.Can you please send the backtrace of this crash?I bootet the b838d5e1c5b6e57b10ec8af2268824041e3ea911 several times but I could not record the complete trace. I think I have to log to the serial console but I can't do that before next week. What I could record ist: There is a always <IRQ> ... </IRQ> the callrace. This is the part I could see: irq_exit+0x71/0x80 do_IRQ+0x4d/0xd0 common_interrup+07a/0x7a </IRQ> RIP: 010:cpuidle_enter_state+0x11d/0x200 RSP: 0018:ffffc9000321bee0 EFLAGS: 00000282 ORIG_RAX: ffffffffffffffc4 RAX: ffff88085efde450 RBX: 0000000000000004 RCX: 00000003c9e63c13 RDX: 00000003c9e63c13 RSI: ffb03103fe35ac43 RDI: 0000000000000000 RBP: ffffe8ffff7cf600 R08: 000000000000000c R09: 0000000000000004 R10: 0000000000000400 R11: 00000003c99e56fc R12: 00000003c9e63c13 R13: 00000003c9da9567 R14: 0000000000000004 R15: ffffffff822763e0 do_idle+0xd3/0x160 cpu_startup_entry+0x14/0x20 secondary_startup_64+0xa5/0xb0 Code: 00 0f b7 83 c0 00 00 00 80 7c 02 08 01 0f 86 d3 02 00 00 41 8b 8c 24 3c 10 00 00 48 8b 6b 58 85 c9 0f 84 2f 01 00 00 48 83 e5 fe <f6> 45 60 02 0f 84 4e 01 00 00 f6 43 38 01 74 0d 80 00 bd ab 00 00 RIP: ip_forward+0xd4/0x470 RSP: ffff88085efc3cb0 CR2: 0000000000000060 ----[ end trace 7205b53c25b7b35a ]--- Kernel panic - not syncing: Fatal exception in interrupt Kernel Offset: disabled Rebooting in 60 seconds.. I got an email from Tobias Hommel and I think it is the same problem. It is very clear that it is the difference from ipv4: call dst_hold_safe() properly to ipv4: mark DST_NOGC and remove the operation of dst_free() which triggers this bug. Regards,
Regards -- Wolfgang Walter Studentenwerk München Anstalt des öffentlichen Rechts