NetBSD-Bugs archive

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

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



The following reply was made to PR kern/52226; it has been noted by GNATS.

From: Alexander Mihalicyn <alexander%mihalicyn.com@localhost>
To: gnats-bugs%netbsd.org@localhost
Cc: 
Subject: Re: kern/52226: Freeze (infinite loop) in kernel on double lua module require
Date: Thu, 11 May 2017 22:43:01 +0300

 --94eb2c0b9ba2226d5f054f44cd5b
 Content-Type: text/plain; charset="UTF-8"
 
 Dear Marc Balmer,
 
 We discuss about this problem with Lourival more than month ago. I checked
 that fix not applied to current source tree and report about problem with
 patch. ;)
 
 Regards,
 Alexander
 
 On Thu, May 11, 2017 at 10:20 PM, Marc Balmer <marc%msys.ch@localhost> wrote:
 
 > The following reply was made to PR kern/52226; it has been noted by GNATS.
 >
 > From: Marc Balmer <marc%msys.ch@localhost>
 > To: gnats-bugs%NetBSD.org@localhost
 > Cc:
 > Subject: Re: kern/52226: Freeze (infinite loop) in kernel on double lua
 > module
 >  require
 > Date: Thu, 11 May 2017 21:19:44 +0200
 >
 >  As lneto helped with the fix, will he commit it?
 >
 >  Am 11.05.17 um 20:20 schrieb alexander%mihalicyn.com@localhost:
 >  >> 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;
 >  >
 >
 >
 
 --94eb2c0b9ba2226d5f054f44cd5b
 Content-Type: text/html; charset="UTF-8"
 Content-Transfer-Encoding: quoted-printable
 
 <div dir=3D"ltr"><div><div><div><div>Dear Marc Balmer,<br></div><br></div>W=
 e discuss about this problem with Lourival more than month ago. I checked t=
 hat fix not applied to current source tree and report about problem with pa=
 tch. ;)<br><br></div>Regards,<br></div>Alexander<br><div><div><div><div><di=
 v><div><div><div><div><div class=3D"gmail_extra"><br><div class=3D"gmail_qu=
 ote">On Thu, May 11, 2017 at 10:20 PM, Marc Balmer <span dir=3D"ltr">&lt;<a=
  href=3D"mailto:marc%msys.ch@localhost"; target=3D"_blank">marc%msys.ch@localhost</a>&gt;</span>=
  wrote:<br><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bor=
 der-left:1px #ccc solid;padding-left:1ex">The following reply was made to P=
 R kern/52226; it has been noted by GNATS.<br>
 <br>
 From: Marc Balmer &lt;<a href=3D"mailto:marc%msys.ch@localhost";>marc%msys.ch@localhost</a>&gt;<=
 br>
 To: gnats-bugs%NetBSD.org@localhost<br>
 Cc:<br>
 Subject: Re: kern/52226: Freeze (infinite loop) in kernel on double lua mod=
 ule<br>
 =C2=A0require<br>
 Date: Thu, 11 May 2017 21:19:44 +0200<br>
 <br>
 =C2=A0As lneto helped with the fix, will he commit it?<br>
 <br>
 =C2=A0Am 11.05.17 um 20:20 schrieb <a href=3D"mailto:alexander%mihalicyn.co@localhost=
 m">alexander%mihalicyn.com@localhost</a>:<br>
 =C2=A0&gt;&gt; Number:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A052226<br>
 =C2=A0&gt;&gt; Category:=C2=A0 =C2=A0 =C2=A0 =C2=A0kern<br>
 =C2=A0&gt;&gt; Synopsis:=C2=A0 =C2=A0 =C2=A0 =C2=A0Freeze (infinite loop) i=
 n kernel on double lua module require<br>
 =C2=A0&gt;&gt; Confidential:=C2=A0 =C2=A0no<br>
 =C2=A0&gt;&gt; Severity:=C2=A0 =C2=A0 =C2=A0 =C2=A0serious<br>
 =C2=A0&gt;&gt; Priority:=C2=A0 =C2=A0 =C2=A0 =C2=A0medium<br>
 =C2=A0&gt;&gt; Responsible:=C2=A0 =C2=A0 kern-bug-people<br>
 =C2=A0&gt;&gt; State:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 open<br>
 =C2=A0&gt;&gt; Class:=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 sw-bug<br>
 =C2=A0&gt;&gt; Submitter-Id:=C2=A0 =C2=A0net<br>
 =C2=A0&gt;&gt; Arrival-Date:=C2=A0 =C2=A0Thu May 11 18:20:00 +0000 2017<br>
 =C2=A0&gt;&gt; Originator:=C2=A0 =C2=A0 =C2=A0Alexander Mihalicyn<br>
 =C2=A0&gt;&gt; Release:=C2=A0 =C2=A0 =C2=A0 =C2=A0 7.1<br>
 =C2=A0&gt;&gt; Organization:<br>
 =C2=A0&gt;&gt; Environment:<br>
 =C2=A0&gt; NetBSD netbsd 7.1 NetBSD 7.1 (GENERIC.201703111743Z) i386<br>
 =C2=A0&gt;&gt; Description:<br>
 =C2=A0&gt; Problem with not checking that lua module already required and m=
 odule 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 infini=
 te loop in kernel...<br>
 =C2=A0&gt;<br>
 =C2=A0&gt; Take a look on <a href=3D"https://github.com/IIJ-NetBSD/netbsd-s=
 rc/blob/master/sys/modules/lua/lua.c" rel=3D"noreferrer" target=3D"_blank">=
 https://github.com/IIJ-NetBSD/<wbr>netbsd-src/blob/master/sys/<wbr>modules/=
 lua/lua.c</a> (function lua_require(lua_State *L)).<br>
 =C2=A0&gt;<br>
 =C2=A0&gt; If we try to double require lua module we got a list with node p=
 ointing to itself:<br>
 =C2=A0&gt; line 524:<br>
 =C2=A0&gt; LIST_INSERT_HEAD(&amp;s-&gt;lua_<wbr>modules, md, mod_next);<br>
 =C2=A0&gt;<br>
 =C2=A0&gt; Before this line we need to check, that our module not loaded ye=
 t.<br>
 =C2=A0&gt;&gt; How-To-Repeat:<br>
 =C2=A0&gt; Possible exploitation is very simple:<br>
 =C2=A0&gt; /root/test.lua:<br>
 =C2=A0&gt; systm =3D require &#39;systm&#39;<br>
 =C2=A0&gt;<br>
 =C2=A0&gt; execute commands:<br>
 =C2=A0&gt; luactl create s1<br>
 =C2=A0&gt; luactl load s1 /root/test.lua<br>
 =C2=A0&gt; luactl load s1 /root/test.lua<br>
 =C2=A0&gt; luactl destroy s1<br>
 =C2=A0&gt;<br>
 =C2=A0&gt; Houston, we have a problem!<br>
 =C2=A0&gt;<br>
 =C2=A0&gt; Thanks to lneto (lneto%NetBSD.org@localhost) for help and support ;)<br>
 =C2=A0&gt;&gt; Fix:<br>
 =C2=A0&gt; --- a/sys/modules/lua/lua.c<br>
 =C2=A0&gt; +++ b/sys/modules/lua/lua.c<br>
 =C2=A0&gt; @@ -487,8 +487,21 @@ lua_require(lua_State *L)<br>
 =C2=A0&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 devic=
 e_printf(sc_self,<br>
 =C2=A0&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 =C2=A0 &quot;require module %s\n&quot;,<br>
 =C2=A0&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 =C2=A0 md-&gt;mod_name);<br>
 =C2=A0&gt; +<br>
 =C2=A0&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* add module to loaded list in state */=
 <br>
 =C2=A0&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 luaL_requiref(L, md-&gt;mod_name,=
  md-&gt;open, 0);<br>
 =C2=A0&gt;<br>
 =C2=A0&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 /* check that module not loaded yet befo=
 re increasing refcount and adding to state modules list */<br>
 =C2=A0&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 LIST_FOREACH(m, &amp;s-&gt;lua_modules, =
 mod_next)<br>
 =C2=A0&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 if (m =3D=3D=
  md) {<br>
 =C2=A0&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 =C2=A0 =C2=A0 if (lua_verbose)<br>
 =C2=A0&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 device_printf(sc_self,<br>
 =C2=A0&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 &=
 quot;required module %s already loaded\n&quot;,<br>
 =C2=A0&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 m=
 -&gt;mod_name);<br>
 =C2=A0&gt; +<br>
 =C2=A0&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
 =A0 =C2=A0 =C2=A0 return 1;<br>
 =C2=A0&gt; +=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 }<br>
 =C2=A0&gt; +<br>
 =C2=A0&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 md-&gt;refcount++;<br>
 =C2=A0&gt;=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 LIST_INSERT_HEAD(&amp;s-&gt;lua_<=
 wbr>modules, md, mod_next);<br>
 =C2=A0&gt; return 1;<br>
 =C2=A0&gt;<br>
 <br>
 </blockquote></div><br></div></div></div></div></div></div></div></div></di=
 v></div></div>
 
 --94eb2c0b9ba2226d5f054f44cd5b--
 



Home | Main Index | Thread Index | Old Index