Re: Race condition in TLS distribution
Magnus Henoch <[email protected]> Tue, 20 Oct 2015 17:51:02 +0100
| Newsgroups | gmane.comp.lang.erlang.bugs |
|---|---|
| Message-ID | <CAJ67tHoKSMndubBj5=_43Zbtf5uDYzK6bmJcf4aeoEMFXuv2nA@mail.gmail.com> |
I just noticed an alternative solution in the example uds_server.erl. It jumps through a number of hoops to get the priv directory even if the code server is not running: https://github.com/erlang/otp/blob/maint/lib/kernel/examples/uds_dist/src/uds_server.erl#L107-L148 Perhaps the crypto module could do something similar in its on_load function. Regards, Magnus On Mon, Oct 19, 2015 at 7:04 PM, Magnus Henoch <[email protected]> wrote: > Hi all, > > I'm trying to use Erlang distribution over TLS ("-proto_dist inet_tls"), > and I've stumbled upon an interesting race condition. > > The kernel supervisor starts the distribution subsystem before it starts > the code server. Therefore, it's possible for another node to establish a > connection to the distribution port while the code server is not yet > running. (Apologies for not providing a recipe for reproducing this; I > could work on that if that would be useful.) > > In that case, the TLS distribution module eventually calls > ssl:ssl_accept/2 on the connection socket. This in turn will eventually > call crypto:supports/0. That's when I got this error: > > {error_logger,{{2015,10,19},{15,1,22}}, > supervisor_report, > [{supervisor,{local,ssl_dist_sup}}, > {errorContext,child_terminated}, > {reason,{undef,[{crypto,supports,[],[]}, > > {tls_record,supported_protocol_versions,1,[{file,"tls_record.erl"},{line,322}]}, > {tls_record,supported_protocol_versions,0, > [{file,"tls_record.erl"},{line,257}]}, > {ssl,handle_options,1,[{file,"ssl.erl"},{line,617}]}, > {ssl,ssl_accept,3,[{file,"ssl.erl"},{line,228}]}, > > {ssl_tls_dist_proxy,accept_loop,4,[{file,"ssl_tls_dist_proxy.erl"},{line,152}]}]}}, > {offender,[{pid,<0.22.0>}, > {name,ssl_tls_dist_proxy}, > {mfargs,{ssl_tls_dist_proxy,start_link,[]}}, > {restart_type,permanent}, > {shutdown,4000}, > {child_type,worker}]}]} > > (though it was formatted as one long line, using the kernel's primitive > error reporter.) > > Why is that function undefined, you ask. That's because the crypto module > has an on_load function, which calls code:priv_dir/1 to figure out where > the NIF library is. Since the code server isn't running yet, > code:priv_dir/1 raises an exception, and as I just learnt from reading the > documentation, if an on_load function raises an exception (or returns > anything but 'ok'), the module is unloaded - and thus we get an 'undef' > error. > > (This will make the ssl_tls_dist_proxy process terminate. Its supervisor > will restart it, but that doesn't help: it has lost its listening socket, > and net_kernel won't ask it to open another one, rendering the node "alive" > but unable to receive connections for distribution - but that's a separate > issue.) > > I came up with the attached patch, which waits for the code server to > start before proceeding, and that fixes the problem for me. What do you > think about it? Might there be a better way to solve this? > > Regards, > Magnus > > _______________________________________________ erlang-bugs mailing list [email protected] http://erlang.org/mailman/listinfo/erlang-bugs