Skip to content

Mod Security compiled with D_FORTIFY_SOURCE=2 results in crashes with lua scripts #1703

Closed
@monkburger

Description

@monkburger

When trying to use custom LUA scripts for parsing POST/upload requests and Mod Security was compiled with D_FORTIFY_SOURCE=2, this results in the following:

*** Error in `/usr/sbin/httpd': corrupted double-linked list: 0x00007f652002cb90 ***

This happens on GCC 4.8.5, 4.9x (any builds) on CentOS7.

Enabling some debugging (compiling modsec with symbols et al) reveals the following:


Core was generated by `/usr/sbin/httpd -k start'.
--
Program terminated with signal 11, Segmentation fault.
w#0  0x00007f21d22acb2d in lua_pushlstring (L=L@entry=0x55d64baa1110, s=0x55d64baa0f28 "POST /wp-login.php HTTP/1.1\n\nCookie: wordpress_test_cookie=WP Cookie check\n", len=0x2be) at lapi.c:447
447	  luaC_checkGC(L);
gdb$ where
#0  0x00007f21d22acb2d in lua_pushlstring (L=L@entry=0x55d64baa1110, s=0x55d64baa0f28 "POST /wp-login.php HTTP/1.1\n\nCookie: wordpress_test_cookie=WP Cookie check\n", len=0x2be) at lapi.c:447
#1  0x00007f21d3414a2d in l_getvar (L=0x55d64baa1110) at msc_lua.c:270
#2  0x00007f21d22b1324 in luaD_precall (L=L@entry=0x55d64baa1110, func=func@entry=0x55d64baa1540, nresults=nresults@entry=0x1) at ldo.c:319
#3  0x00007f21d22bbe57 in luaV_execute (L=L@entry=0x55d64baa1110, nexeccalls=0x2, nexeccalls@entry=0x1) at lvm.c:590
#4  0x00007f21d22b174d in luaD_call (L=0x55d64baa1110, func=0x55d64baa1500, nResults=<optimized out>) at ldo.c:377
#5  0x00007f21d22b0a6e in luaD_rawrunprotected (L=L@entry=0x55d64baa1110, f=f@entry=0x7f21d22ac050 <f_call>, ud=ud@entry=0x7ffc4dc3b6f0) at ldo.c:116
#6  0x00007f21d22b18da in luaD_pcall (L=L@entry=0x55d64baa1110, func=func@entry=0x7f21d22ac050 <f_call>, u=u@entry=0x7ffc4dc3b6f0, old_top=0x30, ef=<optimized out>) at ldo.c:463
#7  0x00007f21d22ad44d in lua_pcall (L=L@entry=0x55d64baa1110, nargs=nargs@entry=0x0, nresults=nresults@entry=0x0, errfunc=errfunc@entry=0x0) at lapi.c:821
#8  0x00007f21d3414ef0 in lua_execute (script=0x55d64b80ed50, param=param@entry=0x0, msr=msr@entry=0x55d64ba7e918, rule=0x55d64b80d398, error_msg=error_msg@entry=0x7ffc4dc3b7a0) at msc_lua.c:477
#9  0x00007f21d34252dd in msre_action_exec_execute (msr=0x55d64ba7e918, mptmp=<optimized out>, rule=<optimized out>, action=0x55d64b80ddc8) at re_actions.c:2227
#10 0x00007f21d3428f9e in msre_perform_nondisruptive_actions (msr=msr@entry=0x55d64ba7e918, rule=rule@entry=0x55d64b80d398, mptmp=mptmp@entry=0x55d64ba9f0b8, actionset=<optimized out>) at re.c:2506
#11 0x00007f21d342cb91 in execute_operator (var=var@entry=0x55d64ba9f808, rule=rule@entry=0x55d64b80d398, msr=msr@entry=0x55d64ba7e918, acting_actionset=acting_actionset@entry=0x55d64b80c6e8, mptmp=mptmp@entry=0x55d64ba9f0b8) at re.c:2769
#12 0x00007f21d342dd7c in msre_rule_process_normal (msr=<optimized out>, rule=0x55d64b80d398) at re.c:3301
#13 msre_rule_process (msr=<optimized out>, rule=0x55d64b80d398) at re.c:3382
#14 msre_ruleset_process_phase (ruleset=<optimized out>, msr=msr@entry=0x55d64ba7e918) at re.c:1773
#15 0x00007f21d340d638 in modsecurity_process_phase_request_body (msr=0x55d64ba7e918) at modsecurity.c:598
#16 modsecurity_process_phase (msr=msr@entry=0x55d64ba7e918, phase=phase@entry=0x2) at modsecurity.c:844
#17 0x00007f21d340c4c2 in hook_request_late (r=<optimized out>) at mod_security2.c:1081
#18 0x000055d64a337a90 in ap_run_fixups (r=0x55d64ba7cf50) at request.c:83
#19 0x000055d64a33a44a in ap_process_request_internal (r=r@entry=0x55d64ba7cf50) at request.c:358
#20 0x000055d64a3588c8 in ap_process_async_request (r=r@entry=0x55d64ba7cf50) at http_request.c:434
#21 0x000055d64a358bb4 in ap_process_request (r=r@entry=0x55d64ba7cf50) at http_request.c:471
#22 0x000055d64a354a9d in ap_process_http_sync_connection (c=0x55d64b9441e0) at http_core.c:210
#23 ap_process_http_connection (c=0x55d64b9441e0) at http_core.c:251
#24 0x000055d64a34c010 in ap_run_process_connection (c=0x55d64b9441e0) at connection.c:42
#25 0x000055d64a34c568 in ap_process_connection (c=c@entry=0x55d64b9441e0, csd=<optimized out>) at connection.c:226
#26 0x00007f21d86319e9 in child_main (child_num_arg=child_num_arg@entry=0x0, child_bucket=child_bucket@entry=0x0) at prefork.c:615
#27 0x00007f21d8631c42 in make_child (s=0x55d64b6c63e0, slot=slot@entry=0x0, bucket=0x0) at prefork.c:716
#28 0x00007f21d8631cb6 in startup_children (number_to_start=0x5) at prefork.c:735
#29 0x00007f21d863260b in prefork_run (_pconf=<optimized out>, plog=0x55d64b6ca358, s=0x55d64b6c63e0) at prefork.c:904
#30 0x000055d64a3234de in ap_run_mpm (pconf=0x55d64b69d138, plog=0x55d64b6ca358, s=0x55d64b6c63e0) at mpm_common.c:94
#31 0x000055d64a31be73 in main (argc=0x3, argv=0x7ffc4dc3c098) at main.c:795
(gdb) list
442  }
443
444
445  LUA_API void lua_pushlstring (lua_State *L, const char *s, size_t len) {
446    lua_lock(L);
447    luaC_checkGC(L);
448    setsvalue2s(L, L->top, luaS_newlstr(L, s, len));
449    api_incr_top(L);
450    lua_unlock(L);
451  }

We're using the following lua script for testing against WordPress (WP is in Russian)


#!/usr/bin/lua
 
function main()
 local cType= m.getvar("REQUEST_HEADERS.Content-Type","none")
 
local serverVars = {
["REQUEST_URI"]		="",
["QUERY_STRING"]	="",
["REMOTE_ADDR"]		="",
}
 
 
for var in pairs(serverVars) do
temp = m.getvar(var,"none")
if temp == nil then
temp="NONE"
end
serverVars[var]=temp
end
 
 
local content=m.getvar("FULL_REQUEST","urlDecodeUni")
 
 
end
main()

Here's modsec debug logging of what happens, ie:


[07/Mar/2018:17:22:44 --0600] [whatever.me/sid#55c314d61af0][rid#55c314fb8e90][/wp-cron.php][8] Lua: Executing script: /localbkp/block_ip/debug.lua
[07/Mar/2018:17:22:44 --0600] [whatever.me/sid#55c314d61af0][rid#55c314fb8e90][/wp-cron.php][9] T (0) urlDecodeUni: "POST /wp-cron.php?doing_wp_cron=1520464964.5650479793548583984375 HTTP/1.1\n\nContent-Type: application/x-www-form-urlencoded\n\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00q\x02\x00\x00\x00\x00\x00\x00@\x1f\xfd\x14\xc3U\x00\x00\bb\x00\x00\x00\x00\x00\x00\xa0\xd4\xfc\x14\xc3U\x00\x00`\xd4\xfc\x14\xc3U\x00\x00\xd8\xd0\xfc\x14\xc3U\x00\x00\b\xd3\xfc\x14\xc3U\x00\x00tS\xfd\x14\xc3U\x00\x00P\xd6\xfc\x14\xc3U\x00\x00\xe0\xd3\xfc\x14\xc3U\x00\x00\xa8\xd3\xfc\x14\xc3U\x00\x00\x90\xd2\xfc\x14\xc3U\x00\x00-\x00\x00\x00\b\x00\x00\x00\x01\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x0

Here's our modsec2.conf settings:

SecRequestBodyAccess On
SecRequestBodyLimitAction ProcessPartial
 
SecRule REQUEST_METHOD "POST" "id:2221,chain,pass,phase:2 "
SecRule REQUEST_BODY_LENGTH "@lt 10000000" "exec:/whatever/debug.lua "

These RPM Macro for CFLAGS does NOT result in crashes:

%__global_cflags        -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=1 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches %{_hardened_cflags} %{_performance_cflags}

%__global_cflags        -Os -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=1 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches %{_hardened_cflags} %{_performance_cflags}

%__global_cflags        -O1 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=1 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches %{_hardened_cflags} %{_performance_cflags}


But these crash for us:

%__global_cflags        -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches %{_hardened_cflags} %{_performance_cflags}

%__global_cflags        -O1 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches %{_hardened_cflags} %{_performance_cflags}

%__global_cflags        -Os -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches %{_hardened_cflags} %{_performance_cflags}

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions