commit 6a89049c0d1200302a59f74e71151466ddae5582 Author: Sukhbir Singh sukhbir@torproject.org Date: Tue Aug 7 10:08:30 2018 -0400
Bug 25485: Fix libstdc++.so.6 compatibility for Tor Browser
We ship our version of libstdc++.so.6 for backward compatibility of Tor Browser on older systems like Ubuntu 16.04. However, a newer version of the library may be installed on the user's system and we should detect and use that. This commit adds support for detecting the library using a C++ program that uses the latest ABI; if the program executes, we should use the system library, and if not (for the older systems), we add our libstdc++.so.6 to LD_LIBRARY_PATH. --- projects/firefox/abicheck.cc | 35 ++++++++++++++++++++++ projects/firefox/build | 4 +++ projects/firefox/config | 2 ++ .../tor-browser/RelativeLink/start-tor-browser | 7 +++++ projects/tor/build | 4 ++- 5 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/projects/firefox/abicheck.cc b/projects/firefox/abicheck.cc new file mode 100644 index 0000000..cbecafa --- /dev/null +++ b/projects/firefox/abicheck.cc @@ -0,0 +1,35 @@ +/* + * Bug 25485: Browser/TorBrowser/Tor/libstdc++.so.6: version `CXXABI_1.3.11' not found + * This program is borrowed from + * https://en.cppreference.com/w/cpp/error/uncaught_exception and is useful in + * determining the latest C++ ABI. Specifically this program requires + * `GLIBCXX_3.4.22` which we use to compare the version of the installed + * libstdc++.so.6 and the bundled version. If the program executes + * successfully, that means we should use the system version of libstdc++.so.6 + * and if not, that means we should use the bundled version. + */ + +#include <iostream> +#include <exception> +#include <stdexcept> + +struct Foo { + int count = std::uncaught_exceptions(); + ~Foo() { + std::cout << (count == std::uncaught_exceptions() + ? "~Foo() called normally\n" + : "~Foo() called during stack unwinding\n"); + } +}; + +int main() +{ + Foo f; + try { + Foo f; + std::cout << "Exception thrown\n"; + throw std::runtime_error("test exception"); + } catch (const std::exception& e) { + std::cout << "Exception caught: " << e.what() << '\n'; + } +} diff --git a/projects/firefox/build b/projects/firefox/build index da1e71b..4dd0945 100644 --- a/projects/firefox/build +++ b/projects/firefox/build @@ -237,6 +237,10 @@ ELSE; END; %]
+[% IF c("var/linux") %] + /var/tmp/dist/gcc/bin/g++ $rootdir/abicheck.cc -o Browser/abicheck +[% END %] + [% c('tar', { tar_src => [ browserdir ], tar_args => '-czf ' _ dest_dir _ '/' _ c('filename') _ '/tor-browser.tar.gz', diff --git a/projects/firefox/config b/projects/firefox/config index 3284ed4..02a380d 100644 --- a/projects/firefox/config +++ b/projects/firefox/config @@ -116,3 +116,5 @@ input_files: - project: fxc2 name: fxc2 enable: '[% c("var/windows") %]' + - filename: abicheck.cc + enable: '[% c("var/linux") %]' diff --git a/projects/tor-browser/RelativeLink/start-tor-browser b/projects/tor-browser/RelativeLink/start-tor-browser index 6639f44..47fbdef 100755 --- a/projects/tor-browser/RelativeLink/start-tor-browser +++ b/projects/tor-browser/RelativeLink/start-tor-browser @@ -274,7 +274,14 @@ if [ $SYSARCHITECTURE -ne $TORARCHITECTURE ]; then fi
LD_LIBRARY_PATH="${HOME}/TorBrowser/Tor/" +# Check if the system has a more recent version of libstdc++.so.6; if yes, use +# that instead of the bundled version. +./abicheck >/dev/null 2>&1 +if [ $? -ne 0 ]; then + LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${HOME}/TorBrowser/Tor/libstdc++/" +fi export LD_LIBRARY_PATH + [% IF ! c("var/release") %] export SELFRANDO_write_layout_file= [% END %] diff --git a/projects/tor/build b/projects/tor/build index 8f129d6..89a5418 100644 --- a/projects/tor/build +++ b/projects/tor/build @@ -47,12 +47,14 @@ openssldir=/var/tmp/dist/openssl # LD_LIBRARY_PATH value to the Tor Browser with the newer one. Thus, we copy # the libstdc++ into the directory with the libs tor depends on, too. See bug # 13359 for further details. - cp /var/tmp/dist/gcc/[% c("var/libdir") %]/libstdc++.so.6 "$distdir/Tor/" + mkdir -p "$distdir/Tor/libstdc++" + cp /var/tmp/dist/gcc/[% c("var/libdir") %]/libstdc++.so.6 "$distdir/Tor/libstdc++/" [% IF c("var/asan") -%] cp /var/tmp/dist/gcc/[% c("var/libdir") %]/libasan.so.3 "$distdir/Tor/" cp /var/tmp/dist/gcc/[% c("var/libdir") %]/libubsan.so.0 "$distdir/Tor/" [% END -%] chmod 700 "$distdir"/Tor/*.so* + chmod 700 "$distdir"/Tor/libstdc++/*.so* # This is needed to make RPATH unavailable. See bug 9150. export LD_LIBRARY_PATH="$distdir/Tor/" [% END %]