tempesta-tech / tempesta

All-in-one solution for high performance web content delivery and advanced protection against DDoS and web attacks
https://tempesta-tech.com/
GNU General Public License v2.0
618 stars 103 forks source link

/root/tempesta/tempesta_fw/sock_srv.c:286 suspicious rcu_dereference_check() usage! #434

Closed keshonok closed 8 years ago

keshonok commented 8 years ago

I have seen this just once so far.

[ 1371.313316] ===============================
[ 1371.317998] [ INFO: suspicious RCU usage. ]
[ 1371.322689] 4.1.12+ #12 Tainted: G        W  O   
[ 1371.327904] -------------------------------
[ 1371.332590] /root/tempesta/tempesta_fw/sock_srv.c:286 suspicious rcu_dereference_check() usage!
[ 1371.341809] 
[ 1371.341809] other info that might help us debug this:
[ 1371.341809] 
[ 1371.351412] 
[ 1371.351412] rcu_scheduler_active = 1, debug_locks = 0
[ 1371.359018] 2 locks held by swapper/0/0:
[ 1371.363494]  #0:  (((&icsk->icsk_retransmit_timer))){+.-...}, at: [<ffffffff8110f8e5>] call_timer_fn+0x5/0x4b0
[ 1371.374179]  #1:  (slock-AF_INET){+.-...}, at: [<ffffffff8159fbb1>] tcp_write_timer+0x21/0x90
[ 1371.383400] 
[ 1371.383400] stack backtrace:
[ 1371.388953] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G        W  O    4.1.12+ #12
[ 1371.396882] Hardware name: Quanta                 S89/QR1-890/QSSC-890  /S89/QR1-890/QSSC-890  , BIOS S89_3A10 10/21/2010
[ 1371.408507]  0000000000000001 ffff88007c803c88 ffffffff8165fc2f 0000000000000011
[ 1371.416661]  ffffffff81c145c0 ffff88007c803cb8 ffffffff810e4637 ffff88002c558bb8
[ 1371.424807]  ffff88003bea8040 ffff88003bea8268 0000000000000006 ffff88007c803d18
[ 1371.432948] Call Trace:
[ 1371.436053]  <IRQ>  [<ffffffff8165fc2f>] dump_stack+0x4c/0x65
[ 1371.442489]  [<ffffffff810e4637>] lockdep_rcu_suspicious+0xe7/0x120
[ 1371.449438]  [<ffffffffa0683efc>] tfw_sock_srv_do_failover.isra.10+0x10c/0x130 [tempesta_fw]
[ 1371.458559]  [<ffffffff815888ff>] ? inet_csk_destroy_sock+0x8f/0x170
[ 1371.465593]  [<ffffffffa0683f2e>] tfw_sock_srv_connect_error+0xe/0x10 [tempesta_fw]
[ 1371.473935]  [<ffffffffa0681d1d>] ss_tcp_state_change+0x9d/0x2b0 [tempesta_fw]
[ 1371.481841]  [<ffffffff8158b5ae>] tcp_done+0x8e/0xa0
[ 1371.487478]  [<ffffffff8159eb15>] tcp_write_err+0x35/0x50
[ 1371.493545]  [<ffffffff8159f3f0>] tcp_retransmit_timer+0x220/0x7b0
[ 1371.500394]  [<ffffffff8159fb90>] ? tcp_write_timer_handler+0x210/0x210
[ 1371.507670]  [<ffffffff8159fa20>] tcp_write_timer_handler+0xa0/0x210
[ 1371.514676]  [<ffffffff8159fc14>] tcp_write_timer+0x84/0x90
[ 1371.520894]  [<ffffffff8110f984>] call_timer_fn+0xa4/0x4b0
[ 1371.527034]  [<ffffffff8110f8e5>] ? call_timer_fn+0x5/0x4b0
[ 1371.533268]  [<ffffffff8159fb90>] ? tcp_write_timer_handler+0x210/0x210
[ 1371.540560]  [<ffffffff8110ffc4>] run_timer_softirq+0x234/0x480
[ 1371.547157]  [<ffffffff8108e1bc>] __do_softirq+0xfc/0x640
[ 1371.553235]  [<ffffffff8108e8b5>] irq_exit+0xa5/0xb0
[ 1371.558883]  [<ffffffff8166b606>] smp_apic_timer_interrupt+0x46/0x60
[ 1371.565928]  [<ffffffff816695e3>] apic_timer_interrupt+0x73/0x80
[ 1371.572624]  <EOI>  [<ffffffff814f33f1>] ? cpuidle_enter_state+0xb1/0x380
[ 1371.580143]  [<ffffffff814f33ed>] ? cpuidle_enter_state+0xad/0x380
[ 1371.587042]  [<ffffffff814f36f7>] cpuidle_enter+0x17/0x20
[ 1371.593159]  [<ffffffff810db05d>] cpu_idle_loop+0x44d/0x580
[ 1371.599451]  [<ffffffff810db1ed>] cpu_startup_entry+0x5d/0x60
[ 1371.605925]  [<ffffffff81652a9d>] rest_init+0x13d/0x150
[ 1371.611877]  [<ffffffff81d3fff8>] start_kernel+0x4be/0x4cb
[ 1371.618088]  [<ffffffff81d3f120>] ? early_idt_handler_array+0x120/0x120
[ 1371.625434]  [<ffffffff81d3f4d7>] x86_64_start_reservations+0x2a/0x2c
[ 1371.632609]  [<ffffffff81d3f614>] x86_64_start_kernel+0x13b/0x14a
keshonok commented 8 years ago

rcu_dereference_sk_user_data() is used just in a handful of places in the Linux kernel. I have found only four kernel source files in the Linux kernel up to version 4.5. All of these places are related to the receive part of the UDP protocol and the like, i.e. backlog_rcv() callback of udplite_prot{}.

This macro definition had been introduced with this patch: torvalds/linux@559835ea7292e2f09304d81eda16f4209433245e. While the motivation for the change is clear, in my opinion the change doesn't get along very well with the RCU infrastructure. The use of this construct should occur under an explicit RCU lock which is not the case. So when CONFIG_PROVE_RCU kernel option is on, LOCKDEP will issue warnings when this macro happens to be executed outside of an RCU-locked section of code.

I believe we should explicitly use ACCESS_ONCE() macro to dereference sk->sk_user_data().

keshonok commented 8 years ago

Corrected via 21db128.