2016-11-26 12:05 GMT-08:00 Eric Dumazet <erdl...@gmail.com>: >> Hi Eric, >> >> The crash happens when the kernel tries to access shadow for nonmapped >> memory. >> >> The issue here is an integer overflow which happens in >> neigh_resolve_output(). >> skb_network_offset(skb) can return negative number, but __skb_pull() >> accepts unsigned int as len. >> As a result, the least significat bit in higher 32 bits of skb->data >> gets set and we get an out-of-bounds with offset of 4 GB. >> >> I've attached a short reproducer, but you either need KASAN or to add >> a BUG_ON to see the crash. >> In this reproducer skb_network_offset() becomes negative after merging >> two ipv6 fragments. >> >> I actually see multiple places where skb_network_offset() is used as >> an argument to skb_pull(). >> So I guess every place can potentially be buggy. > > Well, I think the intent is to accept a negative number. > > This definitely was assumed by commit e1f165032c8bade authors ! > > I guess they were using a 32bit kernel for their tests.
Correct fix would be to use skb_push(skb, -skb_network_offset(skb)); As done in other locations...