Skip to content

Draft: Tor and Mullvad Browser for linux-arm64 (native and cross builds)

NoisyCoil requested to merge NoisyCoil/tor-browser-build:linux-arm64 into main

Merge Info

Related Issues



  • Immediate: patchset needed as soon as possible
  • Next Minor Stable Release: patchset that needs to be verified in nightly before backport
  • Eventually: patchset that needs to be verified in alpha before backport
  • No Backport (preferred): patchset for the next major stable

(Optional) Justification

  • Emergency security update: patchset fixes CVEs, 0-days, etc
  • Censorship event: patchset enables censorship circumvention
  • Critical bug-fix: patchset fixes a bug in core-functionality
  • Consistency: patchset which would make development easier if it were in both the alpha and release branches; developer tools, build system changes, etc
  • Sponsor required: patchset required for sponsor
  • Other: new feature

Issue Tracking


Request Reviewer

  • Request review from an applications developer depending on modified system:
    • NOTE: if the MR modifies multiple areas, please /cc all the relevant reviewers (since gitlab only allows 1 reviewer)
    • accessibility : henry
    • android : clairehurst, dan
    • build system : boklm
    • extensions : ma1
    • firefox internals (XUL/JS/XPCOM) : ma1
    • fonts : pierov
    • frontend (implementation) : henry
    • frontend (review) : donuts, richard
    • localization : henry, pierov
    • macos : clairehurst, dan
    • nightly builds : boklm
    • rebases/release-prep : boklm, dan, ma1, pierov, richard
    • security : ma1
    • signing : boklm, richard
    • updater : pierov
    • misc/other : pierov, richard

Change Description

This MR adds linux-arm64 support to the Tor and Mullvad Browsers. The {tor,mullvad,base}browser-$CHANNEL-linux-aarch64 targets support both x86_64 cross-compilation and arm64 native builds. Cross-compilation is the default. Native compilation is enabled by adding a linux-cross: 0 entry to the var key in rbm.local.conf, as in

  local_conf: 1
  linux-cross: 0

(rbm.local.conf itself can of course be copied from rbm.local.conf.example). Both the browsers currently build on both platforms and run on Fedora Asahi Remix 39 (Fedora on Apple Silicon). I didn't test the basebrowser, but since the other two work, that one should too. The Tor Browser is able to connect to onion sites, and to connect via bridges too.

To set up cross-compilation, I took control of an apparently unused build variable: var/linux-cross. This is set to 0 in all but the {tor,base}browser-arm targets, which in turn are never built. Of course, if I am mistaken and that variable was actually used, the code can be refactored to a separate path. When possible I recycled the old var/linux-cross == 1 content.


nasm is not built as it is not needed for arm64.

When cross-compiling:

  • two sets of binutils + gcc are built, native x86_64 and cross arm64
  • clang and rust are built only once with native x86_64 and cross arm64 support
  • python, cbindgen and node are built only for x86_64
  • go can automatically compile for both x86_64 and arm64, so there was nothing to do here (except for !945)

When compiling natively:

  • bootstrapping go from C code (as you know) requires building Go 1.4, which did not support arm64 as the host architecture. Thanks to a patch by Heikki Lindholm, we can however compile an arm (as in "32-bit arm") go1.4, which in turn can compile an arm64 go1.19. As it stands, therefore, the Tor Browser can be natively compiled only on arm64 platforms which support running 32-bit arm instructions, which excludes e.g. Apple Silicon. To natively build the Tor Browser on Asahi Linux, have a look at the instructions here and use my linux-arm64-asahi branch. (Fixed. Fully native compilation is now supported and this MR builds on Asahi Linux too)

Things that need to be worked out

  • I was unable to template the target replacements in go projects, so I had to remove those replacements. This breaks non-linux builds, so it must be fixed as a priority. (Fixed)
  • When and only when cross-compiling arm64 from x86_64, most of the binaries in the tor-expert-bundle are dynamically linked to for stack-protection. My system does not have that library, so I had to include it in the bundle to be loaded via LD_LIBRARY_PATH to make the Tor Browser work. I suspect the reason why is pulled in is I'm compiling the gcc cross-compiler without hardening (following a hint I found in projects/gcc/build itself; native builds, on the other hand, have hardening enabled when compiling gcc). One could try building the cross compiler with hardening enabled to see what happens. (I was wrong, hardening the compiler itself had nothing to do with this. The issue was caused by the fact that the cross gcc didn't know the target glibc version at configure time, so it couldn't assume that is not needed and linked against it when hardening the binaries in tor-expert-bundle. This is fixed now.)
  • I was unable to use clang as the linker for the aarch64-linux-gnu target while compiling rust from x86_64. When I selected clang, it tried to pull in the native x86_64 GNU ld when linking arm64 binaries, so it understandably failed. To solve this, I had to explicitly select aarch64-linux-gnu-gcc as the linker for the aarch64-linux-gnu target. This is not necessarily a bad thing, but I thought I should mention it anyway.
  • Most of the patches in projects/firefox should really go into the respective Tor or Mullvad Browser repos. (Done)
  • Choosing whether to compile natively or to cross-compile should be more user-friendly, e.g. it should be decided via an option in rbm.local.conf. I was unable to template an integer to put in rbm.conf's targets/linux-aarch64/var/linux-cross. (It was in fact already possible to do so, so I updated the instructions above)


While I rewrote most of the arm64 enablement from scratch, a huge thanks goes to Heikki Lindholm both for years of maintenance and builds of the Tor Browser for arm64, and for the content of some of the patches that went either into this MR or in its early versions - most notably the go-bootstrap, browser and parts of the firefox patches. Also, I had good knowledge of his patchset, so in many cases I ended up doing what he is doing (e.g. the target replacement suppression, not in use anymore).

How Tested

Tor and Mullvad Browser, cross and native, nightly and alpha builds tested, the browsers run on Debian 9 (Stretch) and Fedora Asahi Remix 39 with no apparent issues.

Edited by NoisyCoil

Merge request reports