<div dir="ltr">Hello,<div><br></div><div>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.</div><div><br></div><div>Lukas</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Feb 17, 2017 at 10:20 AM, Salikhov Dinislam <span dir="ltr"><<a href="mailto:Dinislam.Salikhov@kaspersky.com" target="_blank">Dinislam.Salikhov@kaspersky.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="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 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.<br>
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_ become invalid.<br>
6. The driver manipulates with already freed data.<br>
<br>
Unfortunately, I don't have the minimal code sample reproducing the issue.<br>
The described behavior is observed only on high loads and leads to VM crash.<br>
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.<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 megabytes-size binaries are passed to port_control(), that's why I haven't done a PR.<span class="HOEnZb"><font color="#888888"><br>
<br>
Salikhov Dinislam<br>
</font></span><br>______________________________<wbr>_________________<br>
erlang-bugs mailing list<br>
<a href="mailto:erlang-bugs@erlang.org">erlang-bugs@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-bugs" rel="noreferrer" target="_blank">http://erlang.org/mailman/<wbr>listinfo/erlang-bugs</a><br>
<br></blockquote></div><br></div>