net: fix unsafe set_memory_rw from softirq
on x86 system with net.core.bpf_jit_enable = 1
sudo tcpdump -i eth1 'tcp port 22'
causes the warning:
[ 56.766097] Possible unsafe locking scenario:
[ 56.766097]
[ 56.780146] CPU0
[ 56.786807] ----
[ 56.793188] lock(&(&vb->lock)->rlock);
[ 56.799593] <Interrupt>
[ 56.805889] lock(&(&vb->lock)->rlock);
[ 56.812266]
[ 56.812266] *** DEADLOCK ***
[ 56.812266]
[ 56.830670] 1 lock held by ksoftirqd/1/13:
[ 56.836838] #0: (rcu_read_lock){.+.+..}, at: [<
ffffffff8118f44c>] vm_unmap_aliases+0x8c/0x380
[ 56.849757]
[ 56.849757] stack backtrace:
[ 56.862194] CPU: 1 PID: 13 Comm: ksoftirqd/1 Not tainted 3.12.0-rc3+ #45
[ 56.868721] Hardware name: System manufacturer System Product Name/P8Z77 WS, BIOS 3007 07/26/2012
[ 56.882004]
ffffffff821944c0 ffff88080bbdb8c8 ffffffff8175a145 0000000000000007
[ 56.895630]
ffff88080bbd5f40 ffff88080bbdb928 ffffffff81755b14 0000000000000001
[ 56.909313]
ffff880800000001 ffff880800000000 ffffffff8101178f 0000000000000001
[ 56.923006] Call Trace:
[ 56.929532] [<
ffffffff8175a145>] dump_stack+0x55/0x76
[ 56.936067] [<
ffffffff81755b14>] print_usage_bug+0x1f7/0x208
[ 56.942445] [<
ffffffff8101178f>] ? save_stack_trace+0x2f/0x50
[ 56.948932] [<
ffffffff810cc0a0>] ? check_usage_backwards+0x150/0x150
[ 56.955470] [<
ffffffff810ccb52>] mark_lock+0x282/0x2c0
[ 56.961945] [<
ffffffff810ccfed>] __lock_acquire+0x45d/0x1d50
[ 56.968474] [<
ffffffff810cce6e>] ? __lock_acquire+0x2de/0x1d50
[ 56.975140] [<
ffffffff81393bf5>] ? cpumask_next_and+0x55/0x90
[ 56.981942] [<
ffffffff810cef72>] lock_acquire+0x92/0x1d0
[ 56.988745] [<
ffffffff8118f52a>] ? vm_unmap_aliases+0x16a/0x380
[ 56.995619] [<
ffffffff817628f1>] _raw_spin_lock+0x41/0x50
[ 57.002493] [<
ffffffff8118f52a>] ? vm_unmap_aliases+0x16a/0x380
[ 57.009447] [<
ffffffff8118f52a>] vm_unmap_aliases+0x16a/0x380
[ 57.016477] [<
ffffffff8118f44c>] ? vm_unmap_aliases+0x8c/0x380
[ 57.023607] [<
ffffffff810436b0>] change_page_attr_set_clr+0xc0/0x460
[ 57.030818] [<
ffffffff810cfb8d>] ? trace_hardirqs_on+0xd/0x10
[ 57.037896] [<
ffffffff811a8330>] ? kmem_cache_free+0xb0/0x2b0
[ 57.044789] [<
ffffffff811b59c3>] ? free_object_rcu+0x93/0xa0
[ 57.051720] [<
ffffffff81043d9f>] set_memory_rw+0x2f/0x40
[ 57.058727] [<
ffffffff8104e17c>] bpf_jit_free+0x2c/0x40
[ 57.065577] [<
ffffffff81642cba>] sk_filter_release_rcu+0x1a/0x30
[ 57.072338] [<
ffffffff811108e2>] rcu_process_callbacks+0x202/0x7c0
[ 57.078962] [<
ffffffff81057f17>] __do_softirq+0xf7/0x3f0
[ 57.085373] [<
ffffffff81058245>] run_ksoftirqd+0x35/0x70
cannot reuse jited filter memory, since it's readonly,
so use original bpf insns memory to hold work_struct
defer kfree of sk_filter until jit completed freeing
tested on x86_64 and i386
Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
Acked-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>