commit 5fffd424a5ed6043197793c7ed54c9a03ccf820d Author: Yawning Angel yawning@schwanenlied.me Date: Wed Dec 7 01:45:04 2016 +0000
Bug #20899: More PulseAudio fixes.
Instead of trying to find libpulsecore and pass the mutex creation call through with modified args, just re-implement the PI less codepath.
This is slightly more fragile since PulseAudio changing will make everyone very sad, but the implementation details haven't changed for years. --- .../internal/sandbox/pulse.go | 46 +---------- src/tbb_stub/tbb_stub.c | 88 ++++++++-------------- 2 files changed, 35 insertions(+), 99 deletions(-)
diff --git a/src/cmd/sandboxed-tor-browser/internal/sandbox/pulse.go b/src/cmd/sandboxed-tor-browser/internal/sandbox/pulse.go index c58843b..9ff8243 100644 --- a/src/cmd/sandboxed-tor-browser/internal/sandbox/pulse.go +++ b/src/cmd/sandboxed-tor-browser/internal/sandbox/pulse.go @@ -100,11 +100,6 @@ func (h *hugbox) enablePulseAudio() error { func (h *hugbox) appendRestrictedPulseAudio(cache *dynlib.Cache) ([]string, string, string, error) { const libPulse = "libpulse.so.0"
- type roBindEnt struct { - src, dst string - } - toRoBind := []roBindEnt{} - extraLibs := []string{} ldLibraryPath := "" extraLdLibraryPath := "" @@ -118,13 +113,10 @@ func (h *hugbox) appendRestrictedPulseAudio(cache *dynlib.Cache) ([]string, stri // you.
extraLibs = append(extraLibs, libPulse) + h.dir(restrictedPulseDir) ldLibraryPath = ldLibraryPath + ":" + paLibsPath extraLdLibraryPath = extraLdLibraryPath + ":" + restrictedPulseDir
- // The special handling for libpulsecore is because, we need to dlopen - // it in our stub. - - boundPulseCore := false matches, err := filepath.Glob(paLibsPath + "/*.so") if err != nil { return nil, "", "", err @@ -135,43 +127,11 @@ func (h *hugbox) appendRestrictedPulseAudio(cache *dynlib.Cache) ([]string, stri continue } _, f := filepath.Split(v) - if strings.HasPrefix(f, "libpulsecore") { - boundPulseCore = true - } - toRoBind = append(toRoBind, roBindEnt{v, filepath.Join(restrictedPulseDir, f)}) + h.roBind(v, filepath.Join(restrictedPulseDir, f), false) extraLibs = append(extraLibs, f) }
- // Debian sticks libpulsecore-blah.so in /usr/lib, unlike - // everyone else who sticks it in /usr/lib/pulseaudo, - // because fuck you. - if !boundPulseCore { - matches, err = filepath.Glob("/usr/lib/libpulsecore-*.so") - if err != nil { - return nil, "", "", err - } - for _, v := range matches { - if dynlib.ValidateLibraryClass(v) != nil { - Debugf("sandbox: Unsuitable pulsecore: %v", v) - continue - } - _, f := filepath.Split(v) - toRoBind = append(toRoBind, roBindEnt{v, filepath.Join(restrictedPulseDir, f)}) - extraLibs = append(extraLibs, f) - boundPulseCore = true - break - } - } - - // Now that we're done trying to find all the PulseAudio bits, - // actually bindmount everything into the sandbox. - if boundPulseCore { - h.dir(restrictedPulseDir) - for _, ent := range toRoBind { - h.roBind(ent.src, ent.dst, false) - } - return extraLibs, ldLibraryPath, extraLdLibraryPath, nil - } + return extraLibs, ldLibraryPath, extraLdLibraryPath, nil }
return nil, "", "", fmt.Errorf("failed to find PulseAudio libraries") diff --git a/src/tbb_stub/tbb_stub.c b/src/tbb_stub/tbb_stub.c index 5ce7bd5..7ef8b51 100644 --- a/src/tbb_stub/tbb_stub.c +++ b/src/tbb_stub/tbb_stub.c @@ -44,13 +44,11 @@ #include <dlfcn.h> #include <errno.h> #include <pthread.h> +#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <X11/Xlib.h>
-#include <glob.h> -#include <stdbool.h> - static pthread_once_t stub_init_once = PTHREAD_ONCE_INIT; static int (*real_connect)(int, const struct sockaddr *, socklen_t) = NULL; static int (*real_socket)(int, int, int) = NULL; @@ -174,78 +172,56 @@ XQueryExtension(Display *display, _Xconst char *name, int *major, int *event, in return real_XQueryExtension(display, name, major, event, error); }
-typedef struct pa_mutex pm; -static pm* (*real_pa_mutex_new)(bool, bool); - -static char * -glob_library(const char *lib_glob) { - glob_t gb; - char *lib = NULL; - size_t i; - - if (glob(lib_glob, GLOB_MARK, NULL, &gb) != 0) { - return NULL; - } - - for (i = 0; i < gb.gl_pathc; i++) { - const char *path = gb.gl_pathv[i]; - size_t plen = strlen(path); - - if (plen > 0 && path[plen] != '/') { - lib = strndup(path, plen); - break; - } - } - - globfree(&gb); - - return lib; -}
/* There are rumors that PI futexes have scary race conditions, that enable * an exploit that is being sold by the forces of darkness. On systems where * we can filter futex kernel args, we reject such calls. * - * However this breaks PulseAudio, because PI futex usage is determined at - * compile time. This fixes up the mutex creation call, to never request PI - * mutexes. + * However this breaks certain versions of PulseAudio, because PI futex + * usage is determined at compile time. This fixes up the mutex creation + * call to never request PI mutexes. + * + * The code in master may be better, since it looks like it shouldn't assert, + * but god only knows what glibc does, when I ENOSYS their futex calls. * * Thanks to the unnamed reporter who filed the issues on the tails, bug * tracker and chatted with me on IRC about it. * See: https://labs.riseup.net/code/issues/11524 - * - * Note: This could be enabled unconditionally (ie: also on x86), but since - * that platform doesn't filter syscalls by argument due to seccomp-bpf - * limitations, it seems somewhat pointless. */ +typedef struct pa_mutex { + pthread_mutex_t mutex; +} pm; + pm * pa_mutex_new(bool recursive, bool inherit_priority) { + int i; + pthread_mutexattr_t attr; + pm *m; (void) inherit_priority;
- pthread_once(&stub_init_once, stub_init); - - if (real_pa_mutex_new == NULL) { - void *handle; - char *lib; - - if ((lib = glob_library("/usr/lib/pulseaudio/libpulsecore-*.so")) == NULL) { - fprintf(stderr, "ERROR: Failed to find `libpulsecore-*.so`"); + if ((i = pthread_mutexattr_init(&attr)) != 0) { + fprintf(stderr, "ERROR: pthread_mutexattr_init(): %d\n", i); + abort(); + } + if (recursive) { + if ((i = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE)) != 0) { + fprintf(stderr, "ERROR: pthread_mutexattr_settype(PTHREAD_MUTEX_RECURSIVE): %d\n", i); abort(); } + }
- if ((handle = real_dlopen(lib, RTLD_LAZY|RTLD_LOCAL)) == NULL) { - fprintf(stderr, "ERROR: Failed to dlopen() libpulsecore.so: %s\n", dlerror()); - abort(); - } - free(lib); + m = malloc(sizeof(*m)); + if (m == NULL) { + fprintf(stderr, "ERROR: Failed to allocate PulseAudio mutex\n"); + abort(); + }
- if ((real_pa_mutex_new = dlsym(handle, "pa_mutex_new")) == NULL) { - fprintf(stderr, "ERROR: Failed to find `pa_mutex_new()` symbol: %s\n", dlerror()); - abort(); - } - dlclose(handle); + if ((i = pthread_mutex_init(&m->mutex, &attr)) != 0) { + fprintf(stderr, "ERROR: pthread_mutex_init(): %d\n", i); + abort(); } - return real_pa_mutex_new(recursive, false); + + return m; }
/* Initialize the stub. */
tor-commits@lists.torproject.org