[tor-commits] [sandboxed-tor-browser/master] Bug #20806: Make "libavcodec.so" in the sandbox configurable.

yawning at torproject.org yawning at torproject.org
Sat Dec 10 09:13:06 UTC 2016


commit 8d816d804bcad2c709dd1e2e0650cbfb6d8026db
Author: Yawning Angel <yawning at schwanenlied.me>
Date:   Sat Dec 10 08:36:27 2016 +0000

    Bug #20806: Make "libavcodec.so" in the sandbox configurable.
    
    And enable it in the UI.
    
    Like all the other privacy/feature set tradeoffs, this defaults to off.
    This doesn't prevent video/audio playback entirely since Firefox has
    built in support for certain video formats.
---
 ChangeLog                                          |  4 +-
 data/ui/gtkui.ui                                   | 47 +++++++++++++++++++---
 .../sandboxed-tor-browser/internal/dynlib/cache.go | 12 +++++-
 .../internal/sandbox/application.go                | 46 +++++++++++++++++----
 .../internal/ui/config/config.go                   | 13 ++++++
 .../internal/ui/gtk/config.go                      |  6 +++
 src/tbb_stub/tbb_stub.c                            |  3 +-
 7 files changed, 115 insertions(+), 16 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 6b30c61..3995a1c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
 Changes in version 0.0.2 - UNRELEASED:
- * Bug #20780; Shuffle and persist the ordering of internal bridges.
+ * Bug #20780: Shuffle and persist the ordering of internal bridges.
+ * Bug #20806: Add an option to disable including `libavcodec.so` in the
+   firefox container.
 
 Changes in version 0.0.1 - 2016-12-09:
  * Initial release.
diff --git a/data/ui/gtkui.ui b/data/ui/gtkui.ui
index 8d6dfd1..991268a 100644
--- a/data/ui/gtkui.ui
+++ b/data/ui/gtkui.ui
@@ -564,6 +564,43 @@
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
                         <property name="halign">start</property>
+                        <property name="label" translatable="yes">Extra Audio/Video Codecs</property>
+                      </object>
+                      <packing>
+                        <property name="expand">True</property>
+                        <property name="fill">True</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkSwitch" id="avCodecSwitch">
+                        <property name="visible">True</property>
+                        <property name="can_focus">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="fill">True</property>
+                        <property name="pack_type">end</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkBox">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_bottom">6</property>
+                    <child>
+                      <object class="GtkLabel">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="halign">start</property>
                         <property name="label" translatable="yes">Circuit Display</property>
                       </object>
                       <packing>
@@ -587,7 +624,7 @@
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">True</property>
-                    <property name="position">1</property>
+                    <property name="position">2</property>
                   </packing>
                 </child>
                 <child>
@@ -623,7 +660,7 @@
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">True</property>
-                    <property name="position">2</property>
+                    <property name="position">3</property>
                   </packing>
                 </child>
                 <child>
@@ -661,7 +698,7 @@
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">True</property>
-                    <property name="position">3</property>
+                    <property name="position">4</property>
                   </packing>
                 </child>
                 <child>
@@ -699,7 +736,7 @@
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">True</property>
-                    <property name="position">4</property>
+                    <property name="position">5</property>
                   </packing>
                 </child>
                 <child>
@@ -736,7 +773,7 @@
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">True</property>
-                    <property name="position">5</property>
+                    <property name="position">6</property>
                   </packing>
                 </child>
               </object>
diff --git a/src/cmd/sandboxed-tor-browser/internal/dynlib/cache.go b/src/cmd/sandboxed-tor-browser/internal/dynlib/cache.go
index 11f1ee3..b469b44 100644
--- a/src/cmd/sandboxed-tor-browser/internal/dynlib/cache.go
+++ b/src/cmd/sandboxed-tor-browser/internal/dynlib/cache.go
@@ -38,6 +38,10 @@ const (
 	flagElfLibc6   = 3
 )
 
+// FilterFunc is a function that implements a filter to allow rejecting
+// dependencies when resolving libraries.
+type FilterFunc func(string) error
+
 // Quoting from sysdeps/generic/dl-cache.h:
 //
 // libc5 and glibc 2.0/2.1 use the same format.  For glibc 2.2 another
@@ -80,7 +84,7 @@ func (c *Cache) GetLibraryPath(name string) string {
 // ResolveLibraries returns a map of library paths and their aliases for a
 // given set of binaries, based off the ld.so.cache, libraries known to be
 // internal, and a search path.
-func (c *Cache) ResolveLibraries(binaries []string, extraLibs []string, ldLibraryPath string) (map[string][]string, error) {
+func (c *Cache) ResolveLibraries(binaries []string, extraLibs []string, ldLibraryPath string, filterFn FilterFunc) (map[string][]string, error) {
 	searchPaths := filepath.SplitList(ldLibraryPath)
 	libraries := make(map[string]string)
 
@@ -94,6 +98,12 @@ func (c *Cache) ResolveLibraries(binaries []string, extraLibs []string, ldLibrar
 			break
 		}
 		for _, fn := range toCheck {
+			if filterFn != nil {
+				if err := filterFn(fn); err != nil {
+					return nil, err
+				}
+			}
+
 			impLibs, err := getLibraries(fn)
 			if err != nil {
 				return nil, err
diff --git a/src/cmd/sandboxed-tor-browser/internal/sandbox/application.go b/src/cmd/sandboxed-tor-browser/internal/sandbox/application.go
index 6de8a5e..64492a9 100644
--- a/src/cmd/sandboxed-tor-browser/internal/sandbox/application.go
+++ b/src/cmd/sandboxed-tor-browser/internal/sandbox/application.go
@@ -28,6 +28,7 @@ import (
 	"path/filepath"
 	"runtime"
 	"sort"
+	"strings"
 	"syscall"
 
 	"cmd/sandboxed-tor-browser/internal/dynlib"
@@ -243,8 +244,16 @@ func RunTorBrowser(cfg *config.Config, manif *config.Manifest, tor *tor.Tor) (cm
 				extraLdLibraryPath = extraLdLibraryPath + paExtraPath
 			}
 		}
-		if codec := findBestCodec(cache); codec != "" {
-			extraLibs = append(extraLibs, codec)
+
+		allowFfmpeg := false
+		if cfg.Sandbox.EnableAVCodec {
+			if codec := findBestCodec(cache); codec != "" {
+				extraLibs = append(extraLibs, codec)
+				allowFfmpeg = true
+			}
+		}
+		filterFn := func(fn string) error {
+			return filterCodecs(fn, allowFfmpeg)
 		}
 
 		// Gtk uses plugin libraries and shit for theming, and expecting
@@ -256,7 +265,7 @@ func RunTorBrowser(cfg *config.Config, manif *config.Manifest, tor *tor.Tor) (cm
 		extraLibs = append(extraLibs, gtkExtraLibs...)
 		ldLibraryPath = ldLibraryPath + gtkLibPaths
 
-		if err := h.appendLibraries(cache, binaries, extraLibs, ldLibraryPath); err != nil {
+		if err := h.appendLibraries(cache, binaries, extraLibs, ldLibraryPath, filterFn); err != nil {
 			return nil, err
 		}
 	}
@@ -268,6 +277,29 @@ func RunTorBrowser(cfg *config.Config, manif *config.Manifest, tor *tor.Tor) (cm
 	return h.run()
 }
 
+func filterCodecs(fn string, allowFfmpeg bool) error {
+	_, fn = filepath.Split(fn)
+	lfn := strings.ToLower(fn)
+
+	codecPrefixes := []string{
+		// gstreamer is always disallowed, see `findBestCodec()`.
+		"libstreamer",
+		"libgstapp",
+		"libgstvideo",
+	}
+	if !allowFfmpeg {
+		codecPrefixes = append(codecPrefixes, "libavcodec")
+	}
+
+	for _, prefix := range codecPrefixes {
+		if strings.HasPrefix(lfn, prefix) {
+			return fmt.Errorf("sandbox: Attempted to load AV codec when disabled: %v", fn)
+		}
+	}
+
+	return nil
+}
+
 func findBestCodec(cache *dynlib.Cache) string {
 	// This needs to be kept in sync with firefox. :(
 	codecs := []string{
@@ -370,7 +402,7 @@ func RunUpdate(cfg *config.Config, mar []byte) (err error) {
 			return err
 		}
 
-		if err := h.appendLibraries(cache, []string{realUpdateBin}, nil, filepath.Join(realInstallDir, "Browser")); err != nil {
+		if err := h.appendLibraries(cache, []string{realUpdateBin}, nil, filepath.Join(realInstallDir, "Browser"), nil); err != nil {
 			return err
 		}
 		extraLdLibraryPath = extraLdLibraryPath + ":" + restrictedLibDir
@@ -522,7 +554,7 @@ func RunTor(cfg *config.Config, manif *config.Manifest, torrc []byte) (cmd *exec
 
 		// XXX: For now assume that PTs will always use a subset of the tor
 		// binaries libraries.
-		if err := h.appendLibraries(cache, []string{realTorBin}, nil, realTorHome); err != nil {
+		if err := h.appendLibraries(cache, []string{realTorBin}, nil, realTorHome, nil); err != nil {
 			return nil, err
 		}
 		extraLdLibraryPath = extraLdLibraryPath + ":" + restrictedLibDir
@@ -678,7 +710,7 @@ func (h *hugbox) appendRestrictedGtk2() ([]string, string, error) {
 	return gtkLibs, gtkLibPath, nil
 }
 
-func (h *hugbox) appendLibraries(cache *dynlib.Cache, binaries []string, extraLibs []string, ldLibraryPath string) error {
+func (h *hugbox) appendLibraries(cache *dynlib.Cache, binaries []string, extraLibs []string, ldLibraryPath string, filterFn dynlib.FilterFunc) error {
 	defer runtime.GC()
 
 	// ld-linux(-x86-64).so needs special handling since it needs to be in
@@ -694,7 +726,7 @@ func (h *hugbox) appendLibraries(cache *dynlib.Cache, binaries []string, extraLi
 		ldSoAlias = filepath.Join("/lib", ldSoAliasFn)
 	}
 
-	toBindMount, err := cache.ResolveLibraries(binaries, extraLibs, ldLibraryPath)
+	toBindMount, err := cache.ResolveLibraries(binaries, extraLibs, ldLibraryPath, filterFn)
 	if err != nil {
 		return err
 	}
diff --git a/src/cmd/sandboxed-tor-browser/internal/ui/config/config.go b/src/cmd/sandboxed-tor-browser/internal/ui/config/config.go
index 9295967..d0af260 100644
--- a/src/cmd/sandboxed-tor-browser/internal/ui/config/config.go
+++ b/src/cmd/sandboxed-tor-browser/internal/ui/config/config.go
@@ -209,6 +209,10 @@ type Sandbox struct {
 	// sandbox.
 	EnablePulseAudio bool `json:"enablePulseAudio"`
 
+	// EnableAVCodec enables extra codecs via ffmpeg's libavcodec.so inside
+	// the sandbox.
+	EnableAVCodec bool `json:"enableAVCodec"`
+
 	// EnableCircuitDisplay enables the Tor Browser circuit display.
 	EnableCircuitDisplay bool `json:"enableCircuitDisplay"`
 
@@ -238,6 +242,15 @@ func (sb *Sandbox) SetEnablePulseAudio(b bool) {
 	}
 }
 
+// SetEnableAVCodec sets the sandbox libavcodec enable and marks the config
+// dirty.
+func (sb *Sandbox) SetEnableAVCodec(b bool) {
+	if sb.EnableAVCodec != b {
+		sb.EnableAVCodec = b
+		sb.cfg.isDirty = true
+	}
+}
+
 // SetEnableCircuitDisplay sets tthe circit display enable and marks the config
 // dirty.
 func (sb *Sandbox) SetEnableCircuitDisplay(b bool) {
diff --git a/src/cmd/sandboxed-tor-browser/internal/ui/gtk/config.go b/src/cmd/sandboxed-tor-browser/internal/ui/gtk/config.go
index 43e663f..f5519fe 100644
--- a/src/cmd/sandboxed-tor-browser/internal/ui/gtk/config.go
+++ b/src/cmd/sandboxed-tor-browser/internal/ui/gtk/config.go
@@ -62,6 +62,7 @@ type configDialog struct {
 	// Sandbox config elements.
 	pulseAudioBox            *gtk3.Box
 	pulseAudioSwitch         *gtk3.Switch
+	avCodecSwitch            *gtk3.Switch
 	circuitDisplaySwitch     *gtk3.Switch
 	volatileExtensionsSwitch *gtk3.Switch
 	displayBox               *gtk3.Box
@@ -111,6 +112,7 @@ func (d *configDialog) loadFromConfig() {
 	// XXX: Hide PulseAudio option if not available.
 	forceAdv := false
 	d.pulseAudioSwitch.SetActive(d.ui.Cfg.Sandbox.EnablePulseAudio)
+	d.avCodecSwitch.SetActive(d.ui.Cfg.Sandbox.EnableAVCodec)
 	d.circuitDisplaySwitch.SetActive(d.ui.Cfg.Sandbox.EnableCircuitDisplay)
 	d.volatileExtensionsSwitch.SetActive(d.ui.Cfg.Sandbox.VolatileExtensionsDir)
 	if d.ui.Cfg.Sandbox.Display != "" {
@@ -192,6 +194,7 @@ func (d *configDialog) onOk() error {
 	}
 
 	d.ui.Cfg.Sandbox.SetEnablePulseAudio(d.pulseAudioSwitch.GetActive())
+	d.ui.Cfg.Sandbox.SetEnableAVCodec(d.avCodecSwitch.GetActive())
 	d.ui.Cfg.Sandbox.SetEnableCircuitDisplay(d.circuitDisplaySwitch.GetActive())
 	d.ui.Cfg.Sandbox.SetVolatileExtensionsDir(d.volatileExtensionsSwitch.GetActive())
 	if s, err := d.displayEntry.GetText(); err != nil {
@@ -378,6 +381,9 @@ func (ui *gtkUI) initConfigDialog(b *gtk3.Builder) error {
 	if d.pulseAudioSwitch, err = getSwitch(b, "pulseAudioSwitch"); err != nil {
 		return err
 	}
+	if d.avCodecSwitch, err = getSwitch(b, "avCodecSwitch"); err != nil {
+		return err
+	}
 	if d.circuitDisplaySwitch, err = getSwitch(b, "circuitDisplaySwitch"); err != nil {
 		return err
 	}
diff --git a/src/tbb_stub/tbb_stub.c b/src/tbb_stub/tbb_stub.c
index 7d4236b..5e33859 100644
--- a/src/tbb_stub/tbb_stub.c
+++ b/src/tbb_stub/tbb_stub.c
@@ -154,8 +154,7 @@ dlopen(const char *filename, int flags)
   ret = real_dlopen(filename, flags);
 #if 0
   /* This is useful for debugging the internal/dynlib package. */
-  if (ret == NULL)
-    fprintf(stderr, "tbb_stub: dlopen('%s', %d) returned NULL\n", filename, flags);
+  fprintf(stderr, "tbb_stub: dlopen('%s', %d) returned %p\n", filename, flags, ret);
 #endif
   return ret;
 }



More information about the tor-commits mailing list