Bug #7610
closedhttp: reachable assertion when memcap reached during rule reload
Description
Suricata can crash with HTTP traffic due to assertion "DetectEngineStateResetTxs" if reaching the memcap in between rule reloads.
This happens when suricata reaches HTTP memcap in "HTPCallbackRequestStart", cannot allocate "tx_ud" via "HTPCalloc" call and in the meantime there is a rule reload. When processing the following packet, in "DetectRunSetup", since the flow detection engine version is now different than the detection engine one due to the version bump happened in the rule reload, suricata will run "DetectEngineStateResetTxs".
In "DetectEngineStateResetTxs", the flow will be in a valid state but "AppLayerParserGetTxData" will return a NULL pointer (due to the previous allocation failure), thus triggering the subsequent BUG_ON statement and crashing suricata.
This bug seems to have been introduced by commit: 1ad71b96daa2b2655691cfce2a15ccd754d9b290
Attaching sample pcap to reproduce.
To reproduce:
- Use default suricata yaml and set `http.memcap: 113`. This will give enough memory to allocate the "HtpState" but will fail in creating the "HtpTxUserData" structure.
- Create dummy interface: ip link add dev dummy0 type dummy && ip link set dev dummy0 up
- Run suricata with command line: ./src/.libs/suricata -c suricata.yaml -k none --runmode=single -I dummy0
- Replay pcap (any pcap with an HTTP transaction should do). To reliably trigger the crash replay the first 4 packets, one packet at a time via: tcpreplay -i dummy0 -o crash.pcap. This to ensure we send the HTTP request before the rule reload.
- Trigger a rule reload: kill -s SIGUSR2 `pidof suricata`
- Send one more packet via tcpreplay and it should trigger the crash.
Files