commit 8d816d804bcad2c709dd1e2e0650cbfb6d8026db Author: Yawning Angel yawning@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; }
tor-commits@lists.torproject.org