NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/52226: Freeze (infinite loop) in kernel on double lua module require



>Number:         52226
>Category:       kern
>Synopsis:       Freeze (infinite loop) in kernel on double lua module require
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu May 11 18:20:00 +0000 2017
>Originator:     Alexander Mihalicyn
>Release:        7.1
>Organization:
>Environment:
NetBSD netbsd 7.1 NetBSD 7.1 (GENERIC.201703111743Z) i386
>Description:
Problem with not checking that lua module already required and module loading two times. After that we got a list structure corrupted (one of the node pointing to itself). If we iterate over that list we got infinite loop in kernel...

Take a look on https://github.com/IIJ-NetBSD/netbsd-src/blob/master/sys/modules/lua/lua.c (function lua_require(lua_State *L)).

If we try to double require lua module we got a list with node pointing to itself:
line 524:
LIST_INSERT_HEAD(&s->lua_modules, md, mod_next);

Before this line we need to check, that our module not loaded yet.
>How-To-Repeat:
Possible exploitation is very simple:
/root/test.lua:
systm = require 'systm'

execute commands:
luactl create s1
luactl load s1 /root/test.lua
luactl load s1 /root/test.lua
luactl destroy s1

Houston, we have a problem!

Thanks to lneto (lneto%NetBSD.org@localhost) for help and support ;)
>Fix:
--- a/sys/modules/lua/lua.c
+++ b/sys/modules/lua/lua.c
@@ -487,8 +487,21 @@ lua_require(lua_State *L)
 					device_printf(sc_self,
 					    "require module %s\n",
 					    md->mod_name);
+
+				/* add module to loaded list in state */
 				luaL_requiref(L, md->mod_name, md->open, 0);
 
+				/* check that module not loaded yet before increasing refcount and adding to state modules list */
+				LIST_FOREACH(m, &s->lua_modules, mod_next)
+					if (m == md) {
+						if (lua_verbose)
+							device_printf(sc_self,
+								"required module %s already loaded\n",
+								m->mod_name);
+
+						return 1;
+					}
+
 				md->refcount++;
 				LIST_INSERT_HEAD(&s->lua_modules, md, mod_next);
return 1;



Home | Main Index | Thread Index | Old Index