Subject: | Segfault/SIGBRT in Net::SSH2::auth_list for single auth method |
Date: | Wed, 9 Sep 2009 15:25:17 -0700 (PDT) |
To: | bug-Net-SSH2 [...] rt.cpan.org |
From: | TJ Saunders <tj [...] castaglia.org> |
Using libssh2-1.2 and Net-SSH2-0.25, I was encountering segfaults/SIGABRT
(on Ubuntu 9.04, 32-bit Intel machine) in the Net::SSH2::auth_list method
if the SSH2 server returned only a single auth method.
Using a libssh2-1.2 installation compiled using the --enable-debug libssh2
configure option, and enabling the call to libssh2_trace() in Net-SSH2,
the segfault/SIGABRT would manifest as:
[libssh2] 0.761706 Userauth: Permitted auth methods: password
[libssh2] 0.761928 Transport: Freeing session resource
*** glibc detected *** /usr/bin/perl: double free or corruption (!prev):
0x08fae140 ***
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6[0xb7daf604]
/lib/tls/i686/cmov/libc.so.6(cfree+0x96)[0xb7db15b6]
/usr/local/lib/perl/5.10.0/auto/Net/SSH2/SSH2.so(local_free+0x1d)[0xb7b3781d]
/home/tj/local/libssh2-1.2/lib/libssh2.so.1[0xb7b17d05]
/home/tj/local/libssh2-1.2/lib/libssh2.so.1(libssh2_session_free+0x1d)[0xb7b18263]
/usr/local/lib/perl/5.10.0/auto/Net/SSH2/SSH2.so(XS_Net__SSH2_DESTROY+0x1aa)[0xb7b4f3ba]
/usr/bin/perl(Perl_pp_entersub+0x552)[0x80b3c92]
/usr/bin/perl(Perl_call_sv+0x508)[0x80afc18]
/usr/bin/perl(Perl_sv_clear+0x136)[0x80c6226]
/usr/bin/perl(Perl_sv_free2+0x4a)[0x80c696a]
/usr/bin/perl(Perl_leave_scope+0xc96)[0x80e2146]
/usr/bin/perl(Perl_pop_scope+0x2c)[0x80e21fc]
/usr/bin/perl(Perl_pp_leavetry+0xe1)[0x80e54f1]
/usr/bin/perl(Perl_runops_standard+0x19)[0x80b2069]
/usr/bin/perl(perl_run+0x2e0)[0x80b04d0]
/usr/bin/perl(main+0xed)[0x8063ebd]
/lib/tls/i686/cmov/libc.so.6(__libc_start_main+0xe5)[0xb7d56775]
/usr/bin/perl[0x8063d31]
I tracked down the cause to the Safefree() call in
SSH2.xs:net_ss_auth_list:
if (GIMME_V == G_ARRAY)
count = split_comma(sp, auth);
else
PUSHs(sv_2mortal(newSVpv(auth, 0)));
Safefree(auth);
Specifically, if there is no comma in the 'auth' string returned by
libssh2_userauth_list(), then split_comma() returns 1 *without calling
mXPUSHp*. And if that is the case, then calling Safefree() on the auth
string is inappropriate, since at that point auth has been wholly
allocated by the libssh2 library, not by Perl.
I've attached a patch for SSH2.xs which addresses this by effectively
calling Safefree() on the auth string only if split_comma() returns a
count greater than 1.
Cheers,
TJ
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Had I the heavens' embroidered cloths,
Enwrought with golden and silver light,
The blue and the dim and the dark cloths
Of night and light and half-light,
I would spread the cloths under your feet.
But I, being poor, have only my dreams;
I have spread my dreams under your feet;
Tread softly because you tread on my dreams.
-William Butler Yeats
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Message body is not shown because sender requested not to inline it.