Re: Port driver use-after-free
Lukas Larsson <[email protected]> Tue, 21 Feb 2017 09:47:09 +0100
| Newsgroups | gmane.comp.lang.erlang.bugs |
|---|---|
| Message-ID | <CAP3zBqNfB_JLFH5Dx8zmC5XeDi3fTuZmN0JS=_2Y4ez5e-6pdw@mail.gmail.com> |
--===============5983759396355999728== Content-Type: multipart/alternative; boundary=001a11353442eec0480549066cb3 --001a11353442eec0480549066cb3 Content-Type: text/plain; charset=UTF-8 Hello, Thanks for the bug report and fix. The solution which I will include upstream is to add a call to erts_emasculate_writable_binary in the code that your patch deleted. Lukas On Fri, Feb 17, 2017 at 10:20 AM, Salikhov Dinislam < [email protected]> wrote: > Hello, > > Failure scenario: > 1. A process calls erlang:port_control() and passes a binary to port > driver. > 2. The driver is not invoked immediately, so the binary's refc is > incremented and the pointers to binary and to binary's data are kept in > struct ErtsProc2PortSigData_ for later call. The process is in pending > queue. > 3. The pending process is the only one having the refcount to binary. > 4. An event occurs causing garbage collecting of the pending process. > 5. The binary is relocated, so the pointers kept in ErtsProc2PortSigData_ > become invalid. > 6. The driver manipulates with already freed data. > > Unfortunately, I don't have the minimal code sample reproducing the issue. > The described behavior is observed only on high loads and leads to VM > crash. > The issue presents in OTP-18.3 release. I didn't try it for later > releases, but I couldn't find any related fixes done either. > > The memory for binary was first allocated as: > 0x481a39 <do_erts_alcu_alloc+270> > 0x481c06 <erts_alcu_alloc_thr_pref+135> > 0x58db08 <erts_alloc+75> > 0x58dc91 <erts_bin_nrml_alloc+68> > 0x591362 <erts_bs_append+1566> > 0x44177b <process_main+51114> > 0x508a27 <sched_thread_func+499> > 0x68f72d <thr_wrapper+235> > > And then reallocated as: > 0x482026 <do_erts_alcu_realloc+190> > 0x4828f9 <realloc_thr_pref+257> > 0x482ac1 <erts_alcu_realloc_thr_pref+51> > 0x585984 <erts_realloc_fnf+81> > 0x586200 <erts_bin_realloc+110> > 0x58caac <sweep_off_heap+1277> > 0x58a37e <major_collection+3163> > 0x586ca8 <erts_garbage_collect+493> > 0x43c36b <process_main+29594> > 0x508a27 <sched_thread_func+499> > 0x68f72d <thr_wrapper+235> > > In the attachment there is a patch with a quick fix for the issue. > The idea is to always copy the data passed to the port driver if the > actual call is pended. > It is fine for small data, but can lead to performance degradation if > megabytes-size binaries are passed to port_control(), that's why I haven't > done a PR. > > Salikhov Dinislam > > _______________________________________________ > erlang-bugs mailing list > [email protected] > http://erlang.org/mailman/listinfo/erlang-bugs > > --001a11353442eec0480549066cb3 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr">Hello,<div><br></div><div>Thanks for the bug report and fi= x. The solution which I will include upstream is to add a call to=C2=A0erts= _emasculate_writable_binary in the code that your patch deleted.</div><div>= <br></div><div>Lukas</div></div><div class=3D"gmail_extra"><br><div class= =3D"gmail_quote">On Fri, Feb 17, 2017 at 10:20 AM, Salikhov Dinislam <span = dir=3D"ltr"><<a href=3D"mailto:[email protected]" target= =3D"_blank">[email protected]</a>></span> wrote:<br><block= quote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc= solid;padding-left:1ex">Hello,<br> <br> Failure scenario:<br> 1. A process calls erlang:port_control() and passes a binary to port driver= .<br> 2. The driver is not invoked immediately, so the binary's refc is incre= mented and the pointers to binary and to binary's data are kept in stru= ct ErtsProc2PortSigData_ for later call. The process is in pending queue.<b= r> 3. The pending process is the only one having the refcount to binary.<br> 4. An event occurs causing garbage collecting of the pending process.<br> 5. The binary is relocated, so the pointers kept in ErtsProc2PortSigData_ b= ecome invalid.<br> 6. The driver manipulates with already freed data.<br> <br> Unfortunately, I don't have the minimal code sample reproducing the iss= ue.<br> The described behavior is observed only on high loads and leads to VM crash= .<br> The issue presents in=C2=A0 OTP-18.3 release. I didn't try it for later= releases, but I couldn't find any related fixes done either.<br> <br> The memory for binary was first allocated as:<br> 0x481a39 <do_erts_alcu_alloc+270><br> 0x481c06 <erts_alcu_alloc_thr_pref+135><br> 0x58db08 <erts_alloc+75><br> 0x58dc91 <erts_bin_nrml_alloc+68><br> 0x591362 <erts_bs_append+1566><br> 0x44177b <process_main+51114><br> 0x508a27 <sched_thread_func+499><br> 0x68f72d <thr_wrapper+235><br> <br> And then reallocated as:<br> 0x482026 <do_erts_alcu_realloc+190><br> 0x4828f9 <realloc_thr_pref+257><br> 0x482ac1 <erts_alcu_realloc_thr_pref+51<wbr>><br> 0x585984 <erts_realloc_fnf+81><br> 0x586200 <erts_bin_realloc+110><br> 0x58caac <sweep_off_heap+1277><br> 0x58a37e <major_collection+3163><br> 0x586ca8 <erts_garbage_collect+493><br> 0x43c36b <process_main+29594><br> 0x508a27 <sched_thread_func+499><br> 0x68f72d <thr_wrapper+235><br> <br> In the attachment there is a patch with a quick fix for the issue.<br> The idea is to always copy the data passed to the port driver if the actual= call is pended.<br> It is fine for small data, but can lead to performance degradation if megab= ytes-size binaries are passed to port_control(), that's why I haven'= ;t done a PR.<span class=3D"HOEnZb"><font color=3D"#888888"><br> <br> Salikhov Dinislam<br> </font></span><br>______________________________<wbr>_________________<br> erlang-bugs mailing list<br> <a href=3D"mailto:[email protected]">[email protected]</a><br> <a href=3D"http://erlang.org/mailman/listinfo/erlang-bugs" rel=3D"noreferre= r" target=3D"_blank">http://erlang.org/mailman/<wbr>listinfo/erlang-bugs</a= ><br> <br></blockquote></div><br></div> --001a11353442eec0480549066cb3-- --===============5983759396355999728== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ erlang-bugs mailing list [email protected] http://erlang.org/mailman/listinfo/erlang-bugs --===============5983759396355999728==--