Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TclCurl curl::versioninfo core dump, buffer overflow in curlVersion() #25

Closed
apiskors opened this issue Jan 11, 2024 · 6 comments · Fixed by #26
Closed

TclCurl curl::versioninfo core dump, buffer overflow in curlVersion() #25

apiskors opened this issue Jan 11, 2024 · 6 comments · Fixed by #26

Comments

@apiskors
Copy link

With tclcurl in Ubuntu 22.04.03 LTS, simply calling curl::version immediately core dumps, with a buffer overflow in __vsprintf_internal and curlVersion. Stack trace and other details below. This did not happen in earlier versions of Ubuntu, neither 20.04 nor 18.04. I have not tested on any other systems.

This is a really easy bug to reproduce with TclCurl, but I do not know whether the real problem is in TclCurl, libcurl, or something specific to how Ubuntu or Debian builds those libraries. I looked for Ubuntu and Debian tclcurl bug trackers, and could not find any that seem to actually be in use, instead of abandoned and ignored. Thus I'm reporting it here.

Reproduce the problem:

$ /usr/bin/tclsh8.6
% package require TclCurl
7.22.0
% package ifneeded TclCurl 7.22.0
load /usr/lib/tcltk/TclCurl7.22.0/libTclCurl7.22.0.so
source /usr/lib/tcltk/TclCurl7.22.0/tclcurl.tcl
% curl::versioninfo -features
IPV6 SSL LIBZ NTLM ASYNCHDNS SPNEGO LARGEFILE IDN
% curl::versioninfo -protocols
dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp

% curl::version
*** buffer overflow detected ***: terminated
Aborted (core dumped)

$ gdb -c ~/core.1657856 -e /usr/bin/tclsh8.6
(gdb) bt
#0  __pthread_kill_implementation (no_tid=0, signo=6, threadid=139884358782464) at ./nptl/pthread_kill.c:44
#1  __pthread_kill_internal (signo=6, threadid=139884358782464) at ./nptl/pthread_kill.c:78
#2  __GI___pthread_kill (threadid=139884358782464, signo=signo@entry=6) at ./nptl/pthread_kill.c:89
#3  0x00007f395d642476 in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4  0x00007f395d6287f3 in __GI_abort () at ./stdlib/abort.c:79
#5  0x00007f395d689676 in __libc_message (action=action@entry=do_abort, fmt=fmt@entry=0x7f395d7db92e "*** %s ***: terminated\n") at ../sysdeps/posix/libc_fatal.c:155
#6  0x00007f395d7363aa in __GI___fortify_fail (msg=msg@entry=0x7f395d7db8d4 "buffer overflow detected") at ./debug/fortify_fail.c:26
#7  0x00007f395d734d26 in __GI___chk_fail () at ./debug/chk_fail.c:28
#8  0x00007f395d6818df in _IO_str_chk_overflow (fp=<optimized out>, c=<optimized out>) at ./libio/iovsprintf.c:35
#9  0x00007f395d68de34 in __GI__IO_default_xsputn (n=<optimized out>, data=<optimized out>, f=<optimized out>) at ./libio/genops.c:399
#10 __GI__IO_default_xsputn (f=0x7fff2cd296a0, data=<optimized out>, n=177) at ./libio/genops.c:370
#11 0x00007f395d67700c in outstring_func (done=24, length=177, 
    string=0x7f395d4c4060 "libcurl/7.81.0 GnuTLS/3.7.3 zlib/1.2.11 brotli/1.0.9 zstd/1.4.8 libidn2/2.3.2 libpsl/0.21.0 (+libidn2/2.3.2) libssh/0.9.6/openssl/zlib nghttp2/1.43.0 librtmp/2.3 OpenLDAP/2.5.16", 
    s=0x7fff2cd296a0) at ../libio/libioP.h:947
#12 __vfprintf_internal (s=s@entry=0x7fff2cd296a0, format=format@entry=0x7f395da21007 "TclCurl Version %s (%s)", ap=ap@entry=0x7fff2cd297e0, mode_flags=mode_flags@entry=6) at ./stdio-common/vfprintf-internal.c:1517
#13 0x00007f395d681989 in __vsprintf_internal (
    string=0x7fff2cd298c0 "TclCurl Version 7.22.0 (libcurl/7.81.0 GnuTLS/3.7.3 zlib/1.2.11 brotli/1.0.9 zstd/1.4.8 libidn2/2.3.2 libpsl/0.21.0 (+libidn2/2.3.2) libssh/0.9.6/openssl/zlib nghttp2/1.43.0 librtmp/2.3 OpenLDAP/2.5.", maxlen=<optimized out>, format=0x7f395da21007 "TclCurl Version %s (%s)", args=args@entry=0x7fff2cd297e0, mode_flags=6) at ./libio/iovsprintf.c:95
#14 0x00007f395d734841 in ___sprintf_chk (s=<optimized out>, flag=<optimized out>, slen=<optimized out>, format=<optimized out>) at ./debug/sprintf_chk.c:40
#15 0x00007f395da189d2 in curlVersion () from /usr/lib/tcltk/TclCurl7.22.0/libTclCurl7.22.0.so
#16 0x00007f395d896d32 in TclNRRunCallbacks () from /lib/x86_64-linux-gnu/libtcl8.6.so
#17 0x00007f395d924ab4 in Tcl_RecordAndEvalObj () from /lib/x86_64-linux-gnu/libtcl8.6.so
#18 0x00007f395d94b0a7 in Tcl_MainEx () from /lib/x86_64-linux-gnu/libtcl8.6.so
#19 0x000055a953909109 in ?? ()
#20 0x0000000000000000 in ?? ()
(gdb) exit

More info on the software versions where the crash occurred:

$ grep DISTRIB_DESCRIPTION /etc/lsb-release
DISTRIB_DESCRIPTION="Ubuntu 22.04.3 LTS"
$ /usr/bin/curl --version
curl 7.81.0 (x86_64-pc-linux-gnu) libcurl/7.81.0 OpenSSL/3.0.2 zlib/1.2.11 brotli/1.0.9 zstd/1.4.8 libidn2/2.3.2 libpsl/0.21.0 (+libidn2/2.3.2) libssh/0.9.6/openssl/zlib nghttp2/1.43.0 librtmp/2.3 OpenLDAP/2.5.16
Release-Date: 2022-01-05
Protocols: dict file ftp ftps gopher gophers http https imap imaps ldap ldaps mqtt pop3 pop3s rtmp rtsp scp sftp smb smbs smtp smtps telnet tftp 
Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL TLS-SRP UnixSockets zstd

$ dpkg -l 'libcurl*'
Desired=Unknown/Install/Remove/Purge/Hold
| Status=Not/Inst/Conf-files/Unpacked/halF-conf/Half-inst/trig-aWait/Trig-pend
|/ Err?=(none)/Reinst-required (Status,Err: uppercase=bad)
||/ Name                  Version            Architecture Description
+++-=====================-==================-============-==============================================================
un  libcurl3              <none>             <none>       (no description available)
ii  libcurl3-gnutls:amd64 7.81.0-1ubuntu1.15 amd64        easy-to-use client-side URL transfer library (GnuTLS flavour)
un  libcurl3-nss          <none>             <none>       (no description available)
ii  libcurl4:amd64        7.81.0-1ubuntu1.15 amd64        easy-to-use client-side URL transfer library (OpenSSL flavour)
un  libcurl4-gnutls-dev   <none>             <none>       (no description available)

$ dpkg -S /usr/lib/tcltk/TclCurl7.22.0/libTclCurl7.22.0.so
tclcurl: /usr/lib/tcltk/TclCurl7.22.0/libTclCurl7.22.0.so
$ dpkg -S /usr/bin/tclsh8.6
tcl8.6: /usr/bin/tclsh8.6
$ dpkg -S /usr/bin/curl
curl: /usr/bin/curl
$ apt show tcl8.6 | grep Version
Version: 8.6.12+dfsg-1build1
$ apt show tclcurl | grep Version
Version: 7.22.0+hg20160822-3
$ apt show curl | grep Version
Version: 7.81.0-1ubuntu1.15
$ apt show libcurl4:amd64 | grep Version
Version: 7.81.0-1ubuntu1.15
@apiskors
Copy link
Author

We ran into this other seemingly unrelated problem:

curl/curl#10830
SFTP error: Failure establishing ssh session:

For us, the fix for that was to rebuild the stock Ubuntu 22.04.3 LTS curl source packages "--with-libssh2 --without-libssh". In other words, no changes to the source code, just switching the curl library to use ssh-2 instead of ssh-1. Surprisingly, doing that ALSO made the TclCurl curl::versioninfo crash above go away! Now curl::versioninfo works normally again.

@bovine
Copy link
Member

bovine commented Jan 25, 2024

did you build your TclCurl from source, or was it a binary install?

@apiskors
Copy link
Author

All binary installs, the stock binary packages from Ubuntu 22.04.03 on x86-64. That's what crashed on curl::version.

Later, we rebuilt the Ubuntu curl source package using the different configure option, which coincidentally made the crash go away. That did not touch the TclCurl package at all, but of course changed the Curl library, which TclCurl uses. Maybe that means the original Ubuntu binary package build was bad in some way. Or maybe there's a real bug that's still in there somewhere, but hidden somehow by our switch from libssh to libssh2. I don't know, I'm just guessing.

@bovine
Copy link
Member

bovine commented Jan 25, 2024

My question was specifically about the origin of your TclCurl, not libcurl.

ABI differences are probably the cause if TclCurl was compiled against one version of libcurl, and then the libcurl was changed or replaced with a different version or binary distribution (without recompiling TclCurl).

@apiskors
Copy link
Author

ALL our packages were stock binary packages from Ubuntu, including TclCurl. TclCurl still is. The only thing we changed was rebuilding the Curl source package with different configure options, which, surprisingly, made the crash go away.

@bovine bovine linked a pull request Aug 13, 2024 that will close this issue
@bovine
Copy link
Member

bovine commented Aug 13, 2024

I believe this was caused by a char tclversion[200]; in the curlVersion function that was being overflowed by the string:

% string length "curl 7.81.0 (x86_64-pc-linux-gnu) libcurl/7.81.0 OpenSSL/3.0.2 zlib/1.2.11 brotli/1.0.9 zstd/1.4.8 libidn2/2.3.2 libpsl/0.21.0 (+libidn2/2.3.2) libssh/0.9.6/openssl/zlib nghttp2/1.43.0 librtmp/2.3 OpenLDAP/2.5.16"
212

The associated PR has a fix to eliminate that fixed-size buffer.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants