Opened 5 years ago

Last modified 8 days ago

#12631 new project

Tor Browser for ARM architecture

Reported by: mttp Owned by:
Priority: Medium Milestone:
Component: Applications/Tor Browser Version:
Severity: Normal Keywords: tbb-rbm, TorBrowserTeam201904R
Cc: gk, mcs, arma, boklm, intrigeri, peredor Actual Points:
Parent ID: Points:
Reviewer: Sponsor:

Description

The Tor Project should provide a Tor Browser compatible with the ARMv7 processor. This would provide a safe way of using Tor for users of the Samsung ARM Chromebook, the Samsung Chromebook 2, the Raspberry Pi, the Novena Open Laptop, and probably other platforms too.

Child Tickets

Change History (31)

comment:1 Changed 5 years ago by gk

Cc: gk added

comment:2 Changed 5 years ago by erinn

Keywords: needs-triage added

comment:3 Changed 4 years ago by gk

Component: Tor bundles/installationTor Browser
Keywords: tbb-gitian added; needs-triage removed

comment:4 Changed 4 years ago by mirimir

I've built Firefox in Tor Browser 4.5a4 on a Raspberry Pi 2, running Raspbian wheezy on a 32GB class 10 microSDHC card. It took 6-7 hours at 100% CPU, and I had to cool the Pi 2 with a small fan to prevent overheating. I followed the instructions in <https://trac.torproject.org/projects/tor/wiki/doc/TorBrowser/Hacking> at "Building Just Firefox" exactly, except that I commented out "ac_add_options --enable-tor-browser-update" in "~/tor-browser/.mozconfig" after configuring.

As instructed, I overwrote the Firefox folder in tor-browser_en-US (from tor-browser-linux32-4.5a4_en-US.tar.xz) with the Firefox folder from the build. Had I been using just the one Pi, that would have been sufficient. However, given that I'm using this workspace Pi with a Tor gateway Pi, a little tweaking was required.

To avoid the possibility of Tor over Tor, I deleted the Tor folder in Tor Browser. In order to have Tor Browser run without a local tor process, I added two lines to "prefs.js" in the profiles:

| user_pref("extensions.torlauncher.prompt_at_startup", false);
| user_pref("extensions.torlauncher.start_tor", false);

Once Tor Browser would run, I changed SocksPort to "192.168.2.1:9150", and disabled the TorLauncher extension. All of the expected extensions are present. On the gateway Pi, I used this "/etc/tor/torrc":

| SocksPort 127.0.0.1:9050
| SocksPort 192.168.2.1:9050
| SocksPort 192.168.2.1:9100
| SocksPort 192.168.2.1:9150
|
| SocksPolicy accept 127.0.0.1
| SocksPolicy accept 192.168.2.0/16
| SocksPolicy reject *
|
| DnsPort 127.0.0.1:53 IsolateDestPort
| DnsPort 192.168.2.1:53 IsolateDestPort
|
| VirtualAddrNetwork 10.192.0.0/10
| AutomapHostsOnResolve 1
|
| ControlPort 9151
| CookieAuthentication 1
|
| Log notice file /var/log/tor/notices.log
| RunAsDaemon 1
| DataDirectory /var/lib/tor

I don't believe that the iptables rules on the gateway Pi are relevant here, but I'll be happy to add them if desired. I installed torsocks and rinetd on the workspace Pi, and used this "/etc/rinetd.conf":

| bindaddress bindport connectaddress connectport
| 127.0.0.1 9050 192.168.2.1 9050
| 127.0.0.1 9151 192.168.2.1 9151

Browsing <https://check.torproject.org>, I get that that the browser is using Tor, and there's no warning that it's not Tor Browser. After hitting "New Tor Circuit for this Site" in Torbutton, the page reloads with a new IP address. However, Torbutton still complains that Tor isn't running, and I don't know how to fix that.

I also plan to test a deterministic build from <https://git.torproject.org/builders/tor-browser-bundle.git>. But I presume that would depend on having some version of Ubuntu with Gitian running on Raspberry Pi. I know of two possibilities so far: Ubuntu 14.04 LTS <https://wiki.ubuntu.com/ARM/RaspberryPi> and Ubuntu 14.10 / Linaro 15.01 <http://www.raspberrypi.org/forums/viewtopic.php?f=56&t=98997>. I gather that they differ in how they're compiled for ARMv7 and ARMHF.

comment:5 Changed 4 years ago by mcs

Cc: mcs added

comment:6 Changed 4 years ago by dawuud

I built Tor Browser in arch linux running on a Raspberry Pi 2.
I followed this procedure:
https://trac.torproject.org/projects/tor/wiki/doc/TorBrowser/Hacking#BuildingJustFirefox

I'd like to make many further refinements to my archlinux build procedure for TBB such as using distcc with cross compiling slaves etc.

Here's a brief explanation of how to build tor-browser in arm arch linux:

First, I git cloned https://git.torproject.org/tor-browser.git
and I checked out the "tor-browser-31.5.3esr-4.5-1-build1" branch.

Then I followed the instructions and performed prerequisite changes as described here:
https://developer.mozilla.org/en-US/docs/Mozilla/Developer_guide/Build_Instructions/Linux_Prerequisites

  1. install prerequisite arch packages:

pacman -Syu --needed base-devel zip unzip freetype2 fontconfig pkg-config \

gtk2 dbus-glib iw libidl2 python2 mercurial alsa-lib curl libnotify libxt \
mesa autoconf2.13 yasm wireless_tools gstreamer0.10 \
gstreamer0.10-base-plugins libpulse

  1. edit .mozconfig

here's the things i changed:

[human@builder tor-browser]$ git diff .mozconfig
diff --git a/.mozconfig b/.mozconfig
index f2874e8..73fd025 100755
--- a/.mozconfig
+++ b/.mozconfig
@@ -2,14 +2,22 @@

mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-@CONFIG_GUESS@
mk_add_options MOZ_APP_DISPLAYNAME="Tor Browser"

-mk_add_options MOZ_MAKE_FLAGS="-j4"
+mk_add_options MOZ_MAKE_FLAGS="-j2"

mk_add_options MOZILLA_OFFICIAL=1
mk_add_options BUILD_OFFICIAL=1


+
+mk_add_options PYTHON=/usr/bin/python2
+mk_add_options AUTOCONF=autoconf-2.13
+
+ac_add_options --with-ccache=/usr/bin/ccache
+ac_add_options --with-arm-kuser
+ac_add_options --with-arch=armv7-a
+

ac_add_options --enable-optimize
#ac_add_options --disable-optimize
ac_add_options --enable-official-branding

-ac_add_options --enable-tor-browser-update
+#ac_add_options --enable-tor-browser-update

ac_add_options --enable-update-packaging
ac_add_options --enable-signmar
ac_add_options --enable-verify-mar

@@ -21,3 +29,4 @@ ac_add_options --disable-maintenance-service

ac_add_options --disable-crashreporter
ac_add_options --disable-webrtc
#ac_add_options --disable-ctypes

+
[human@builder tor-browser]$

remarks about this .mozconfig:

  • I am using ccache... So don't set that ccache option unless you are also going to use ccache.
  • I use MOZ_MAKE_FLAGS="-j2" because the Raspberry Pi 2 only has 1G of ram.

Additionally I enabled 1G of swap on this build system so that it wouldn't crash with out-of-memory failures.

  1. building archlinux Tor Browser Bundle

I followed the procedure documented here:
https://trac.torproject.org/projects/tor/wiki/doc/TorBrowser/Hacking#BuildingJustFirefox

I used the most recent amd64 build of TBB for the skeleton... and replaced it's browser with the new as mentioned in the link.

Last edited 4 years ago by dawuud (previous) (diff)

comment:7 Changed 3 years ago by cypherpunks

Severity: Normal

While building tor-browser 5.5-1 on a debian jessie arm system (qemu, vexpress-a9), e.g.:

QEMU_AUDIO_DRV=none qemu-system-arm -m 1024M -sd jessie_armhf.img -M vexpress-a9 -cpu cortex-a9 -kernel jessie_armhf_vmlinuz_extracted -initrd jessie_armhf_initrd_extracted -append "root=/dev/mmcblk0p2 console=ttyAMA0"  -no-reboot -net nic -net user -dtb vexpress-v2p-ca9.dtb  -nographic -redir tcp:5555::22

I followed the build instructions from https://trac.torproject.org/projects/tor/wiki/doc/TorBrowser/Hacking, with no further modifications to build options.

e.g.

make $CONFIGURE_ARGS -f client.mk configure CONFIGURE_ARGS="--with-tor-browser-version=5.5-1"
make $MAKEOPTS -f client.mk build

The build options for media/libvpx specify -mfloat-abi=softfp, which breaks the arm-linux-gnueabihf toolchain as it is missing gnu/stubs-soft.h.

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=795331

Applying the author's suggested fix:

diff --git a/media/libvpx/moz.build b/media/libvpx/moz.build
index a1138f4..999ca94 100644
--- a/media/libvpx/moz.build
+++ b/media/libvpx/moz.build
@@ -65,7 +65,8 @@ if CONFIG['VPX_ARM_ASM']:

     for f in SOURCES:
         if f.endswith('.c') and 'neon' in f:
-            SOURCES[f].flags += ['-march=armv7-a', '-mthumb', '-mfloat-abi=softfp', '-mfpu=neon']
+            SOURCES[f].flags += ['-mfpu=neon']
+    #        SOURCES[f].flags += ['-march=armv7-a', '-mthumb', '-mfloat-abi=softfp', '-mfpu=neon']

and the build proceeds. I'm not sure if this fix would break platforms (e.g. Rpi 1)

comment:8 Changed 3 years ago by cypherpunks

Reporting from a Novena here. I built Tor Browser from source and set preferences to use the system Tor as shown in the start_tor_browser script. I'm running it through Xpra due to unstable drivers, so I don't have graphical acceleration. It took maybe 11 hours to compile. So it's quite slow, but not unusable I don't think. The main lag seems to be in downloading pages.

The main problems I see is that from my initial glance I didn't see Gitian working on ARM. If it requires virtualization, that's out of the question given most ARM boards don't support those hardware extensions. There may have to be containers used for reproducible builds if they aren't already.

comment:9 in reply to:  8 Changed 3 years ago by teor

Replying to cypherpunks:

The main problems I see is that from my initial glance I didn't see Gitian working on ARM. If it requires virtualization, that's out of the question given most ARM boards don't support those hardware extensions. There may have to be containers used for reproducible builds if they aren't already.

You could use a cross-compiler that runs on x86_64 but targets ARM.

It's what we do for our Windows and OS X builds.

comment:10 Changed 3 years ago by cypherpunks

Ubuntu-vm-builder (python-vm-builder), used by gitian, already supports multiple architectures, but lacks the release information for releases of ubuntu or debian for any cpu architectures other than i686 and x86_64.

gitian also supports using LXC, via libvirt, instead of Qemu-KVM. This is used by default when the gitian environment is already virtualized. libvirt also supports using a qemu backend, for example, qemu-system-arm.

Debian is also supported as a target by gitian, and debian supports a wider variety of architectures than ubuntu. A patch for python-vm-builder that includes all flavors of debian releases would be a step towards getting gitian to support other target architectures.

comment:11 Changed 2 years ago by c6h12o6

Successful compilation of Tor Browser on ASUS C201 running libreboot[1] and Debian Stretch with mainline kernel[2] following https://trac.torproject.org/projects/tor/wiki/doc/TorBrowser/Hacking#BuildingJustFirefox (and adding "ac_add_options --disable-gstreamer" to tor-browser/.mozconfig as Stretch doesn't ship gstreamer0.10) took estimated 2h.

Please reconsider officially supporting this architecture, we'd really appreciate being able to use Tails[3] on such a fast and affordable device we can trust that much.

[1] https://libreboot.org/docs/hcl/c201.html
[2] linux-image-armmp-lpae, cf. https://wiki.debian.org/InstallingDebianOn/Asus/C201#Mainline_Linux_Kernel
[3] cf. https://labs.riseup.net/code/issues/10972

Last edited 2 years ago by c6h12o6 (previous) (diff)

comment:12 Changed 2 years ago by arma

This weekend I ran into a person who was trying to hack his Firefox on arm (raspberry pi) to do the things Tor Browser does. It sure would be better if we had even unofficial builds, and even if it's only whichever arm arch is easier (maybe that's armv8?).

Is the issue that we don't have the build farm infrastructure? Or does it not build? Or does it build, but not reproducibly?

comment:13 Changed 2 years ago by arma

Cc: arma added

comment:14 in reply to:  12 Changed 2 years ago by gk

Replying to arma:

Is the issue that we don't have the build farm infrastructure? Or does it not build? Or does it build, but not reproducibly?

Definitely the first. But we need to write Gitian descriptors for building for ARM first and I suspect there are a bunch of our myriad of components that are trickier to cross-compile than others. And, yes, I assume there will be reproducibility issues. In short: I guess this will be a non-trivial amount of work.

That said: I'd be happy if a cypherpunk would show up trying to do this and would help them getting this done.

comment:15 Changed 20 months ago by gk

Keywords: tbb-rbm added; tbb-gitian removed

Moving over to rbm

comment:16 Changed 15 months ago by boklm

Cc: boklm added

comment:17 Changed 9 months ago by intrigeri

Cc: intrigeri added

comment:18 Changed 7 months ago by JeremyRand

I've been working on rbm descriptors for building for ARM target, and I successfully built Tor's Firefox fork with rbm. Caveats:

  • Code is very messy (e.g. commented out code everywhere), I need to clean it up a lot.
  • Still based on the ESR 52 version of Tor Browser; making ESR 60 work will mean figuring out how to get Rust to build (see next item).
  • The only rbm project I've tried to build is Firefox and its dependencies; it's unclear how much work will be involved in building the other projects (e.g. tor, the Go projects, and the Rust projects).
  • The workarounds for missing target libraries (i.e. using apt-get to download armhf packages and extracting them to a prefix directory) are kind of weird, maybe there's a simpler approach than what I did?
  • I want to generalize the cross-compiling stuff some more, so that in the future we could add aarch64, ppc64be, and ppc64le targets without code duplication. Right now the cross-compiling stuff is hardcoded for armhf, which is great for a proof-of-concept but not a good idea to consider merging.
  • I haven't tested build reproducibility. I don't expect any problems here, but it's too early to be confident.

All that said, if anyone would like to play with it, the source code is at https://notabug.org/JeremyRand/tor-browser-build/src/armhf (it's in the armhf branch), and some random documentation is at https://wiki.raptorcs.com/wiki/Porting/Tor_Browser . I've successfully run the resulting Firefox binary on my Asus C201 Chromebook (running Debian Stretch) and it works fine.

comment:19 in reply to:  18 Changed 7 months ago by boklm

Replying to JeremyRand:

All that said, if anyone would like to play with it, the source code is at https://notabug.org/JeremyRand/tor-browser-build/src/armhf (it's in the armhf branch), and some random documentation is at https://wiki.raptorcs.com/wiki/Porting/Tor_Browser . I've successfully run the resulting Firefox binary on my Asus C201 Chromebook (running Debian Stretch) and it works fine.

It looks like there is still a lot left to do, but very nice work!

comment:20 Changed 3 months ago by JeremyRand

Updated my rbm descriptors for ARM to work with ESR 60. https://notabug.org/JeremyRand/tor-browser-build/src/armhf-esr60 (the armhf-esr60 branch). Docs still at https://wiki.raptorcs.com/wiki/Porting/Tor_Browser . One noteworthy thing is that, due to what is probably https://bugzilla.mozilla.org/show_bug.cgi?id=1452128 , I needed to upgrade to gcc 7.3.0 / binutils 2.29.1. I don't know if that's a dealbreaker for Tor (and I haven't carefully tested whether the upgrade breaks anything on non-ARM platforms). Can anyone from Tor comment on whether the specific gcc / binutils versions used by Tor Browser were chosen for a particular reason, and whether upgrading them would be considered if it's the most straightforward way to get ARM to work?

comment:21 in reply to:  20 ; Changed 3 months ago by gk

Replying to JeremyRand:

Updated my rbm descriptors for ARM to work with ESR 60. https://notabug.org/JeremyRand/tor-browser-build/src/armhf-esr60 (the armhf-esr60 branch). Docs still at https://wiki.raptorcs.com/wiki/Porting/Tor_Browser . One noteworthy thing is that, due to what is probably https://bugzilla.mozilla.org/show_bug.cgi?id=1452128 , I needed to upgrade to gcc 7.3.0 / binutils 2.29.1. I don't know if that's a dealbreaker for Tor (and I haven't carefully tested whether the upgrade breaks anything on non-ARM platforms). Can anyone from Tor comment on whether the specific gcc / binutils versions used by Tor Browser were chosen for a particular reason, and whether upgrading them would be considered if it's the most straightforward way to get ARM to work?

Thanks for working on the ARM port, really appreciated! Updating GCC to 7.3.0 is probably no problem. Binutils 2.29.1 is trickier, though, as with binutils 2.26 we have a hard to fix reproducibility issue on Windows which currently prevents upgrading (see: #26148). We could think about using 2.29.1 just for ARM as a workaround (in case there are no reproducibility issues involved here and the Mozilla bug does not get fixed meanwhile).

Last edited 3 months ago by gk (previous) (diff)

comment:22 Changed 3 months ago by peredor

Cc: peredor added

comment:23 in reply to:  21 Changed 3 months ago by gk

Replying to gk:

Replying to JeremyRand:

Updated my rbm descriptors for ARM to work with ESR 60. https://notabug.org/JeremyRand/tor-browser-build/src/armhf-esr60 (the armhf-esr60 branch). Docs still at https://wiki.raptorcs.com/wiki/Porting/Tor_Browser . One noteworthy thing is that, due to what is probably https://bugzilla.mozilla.org/show_bug.cgi?id=1452128 , I needed to upgrade to gcc 7.3.0 / binutils 2.29.1. I don't know if that's a dealbreaker for Tor (and I haven't carefully tested whether the upgrade breaks anything on non-ARM platforms). Can anyone from Tor comment on whether the specific gcc / binutils versions used by Tor Browser were chosen for a particular reason, and whether upgrading them would be considered if it's the most straightforward way to get ARM to work?

Thanks for working on the ARM port, really appreciated! Updating GCC to 7.3.0 is probably no problem.

That's now #29335 and will happen in a couple of weeks once we start with the 9.0 alpha series and is the last missing piece as we already bumped binutils to 2.31.1.

Version 0, edited 3 months ago by gk (next)

comment:24 Changed 7 weeks ago by c6h12o6

When relying on cross-compilation we won't have builds that are reproducible on the target platform. Don't get me wrong - first of all I'd like to see an official Tor Browser for ARM, but I don't think it's future-proof to focus on the cross-compilation approach.
(JFYI: https://notabug.org/hashashini/tor-browser-build)

comment:25 Changed 5 weeks ago by JeremyRand

I've updated my rbm descriptors for (32-bit) ARM. Currently all projects that typically are built for GNU/Linux targets are built for linux-arm, with the exception of fteproxy and snowflake (and their exclusive dependencies). Since fteproxy and snowflake are optional components of Tor Browser, my inclination is to wait until the rest of this code is merged by Tor before I try to make fteproxy and/or snowflake build (they both seem more annoying to build than most of the other projects).

The resulting Tor Browser binaries appear to work fine in my testing on my Asus C201 (I connected to Tor without bridges, navigated to a JS-heavy website, used that website for a few minutes, and exited); I didn't try using the pluggable transports. There are a couple of minor bugs in the shell script that launches Tor Browser (I need to patch out the SSE2 check and make it set LD_LIBRARY_PATH), which should be easy for me to fix.

So, at this point, the focus is shifting from "make it run on ARM" to "start cleaning up the code in order to make it possible to merge". There are a number of things I want to do to improve code quality; the most obvious ones are (1) remove all the commented out code that's leftover from me throwing things at the build system to see what stuck; and (2) improve the abstraction, so that things that apply to any GNU/Linux cross-compiled target are cleanly separated from things that are specific to 32-bit ARM. If anyone wants to start looking at my code and suggest other things that I should clean up prior to a merge, by all means feel free. Or feel free to wait a few weeks for me to get the initial stages of cleanup out of the way; either way works for me.

Regarding @c6h12o6's comment: I do not see cross-compiling as a competitor to having non-x86 rbm hosts; I see them as orthogonal. My ultimate goal here is for rbm hosts using the set of {x86, ARM, and POWER} to all be able to reproduce the same hashes for targets within the set of {x86, ARM, and POWER}. There's no reason why that shouldn't be possible, modulo compiler bugs and rbm descriptor bugs that should be fixed. I personally find implementing cross-compile support to be easier given my skill set, and it seems like a good first step (hence it's what I'm implementing), but I would be highly supportive of efforts to add non-x86 rbm host support in addition to cross-compile support.

comment:26 Changed 5 weeks ago by JeremyRand

(My current code is still at ​https://notabug.org/JeremyRand/tor-browser-build/src/armhf-esr60 (the armhf-esr60 branch); and docs are still at ​https://wiki.raptorcs.com/wiki/Porting/Tor_Browser .)

comment:27 Changed 5 weeks ago by c6h12o6

Would future native builds then have to utilize the cross-toolchain (instead of the native toolchain currently used) to achieve reproducibility across different host/target combinations?

comment:28 Changed 5 weeks ago by JeremyRand

Would future native builds then have to utilize the cross-toolchain (instead of the native toolchain currently used) to achieve reproducibility across different host/target combinations?

@c6h12o6 I suspect that you'd need to use something like the "gcc-cross" project in my branch regardless of whether you're doing a cross-compile, if you want reproducible builds for non-cross build and cross builds. Which basically means you'd be building the C/C++ standard library from source rather than using the Debian-packaged one; I don't think there are any other major differences between the gcc and gcc-cross in my branch. I only made it a separate project because I didn't want the patch to get too invasive; a subsequent patch could replace all usage of gcc with gcc-cross.

comment:29 Changed 3 weeks ago by holin

I did a quick (in coding, not in building) port of the maint-8.0 branch to armhf. Can "make release-linux-arm" and the resulting package appears to work. Build time is huge on a 4-core 4 GB arm laptop, probably 30-40 hours or so.

Some ugly amd64->armhf changes were required where something like a "native" arch would be a better solution.

Rust build seems like something that's very shaky on 32-bit platforms in general, armhf included.

Haven't checked yet how much could be merged with JeremyRand's work, but I'm sure quite a bit.

Code at:
https://notabug.org/holin/tor-browser-build (maint-8.0-armhf branch)

comment:30 Changed 3 weeks ago by gk

Keywords: TorBrowserTeam201904R added

Marking this for review for April to give feedback on the patches (thanks for the work on this bug!). But I'll won't have time for that until Tor Browser 8.5 will be out.

comment:31 Changed 8 days ago by holin

My maint-8.0-armhf branch is now a bit cleaner and the x86 stuff should build like it did originally without the arm changes interfering.

I also uploaded a set of binaries to
https://sourceforge.net/projects/tor-browser-ports/
in case there's someone who'd like to test it out. So far, I've only tested basic functionality on an ARM laptop running Debian stretch.

Going forward, I'll probably import the changes over to master and try to get nightly to build. However, in the grand scheme of things, Rust and Firefox are heavy beasts and, I think, assuming tor project even considers native build an option, supporting 32-bit build platforms is not the way to go unless the said behemoths suddenly lose some serious weight.

Note: See TracTickets for help on using tickets.