Currently Tor Browser crashes immediately on startup if a proc filesystem is not mounted on /proc. This also affects the upstream firefox code, so it technically is a Mozilla bug.
too much recursionSegmentation fault (core dumped)
/proc contains a large amount of information about the host system that can be used to fingerprint/identify users and additionally historically has been the source or part of many kernel security problems.
While this problem can be mitigated by a MAC system (eg: AppArmor) to constrain what Firefox can access under /proc, the ideal fix is for Firefox to support running without /proc, while degrading gracefully (there is no truly ubiquitous MAC system available on all common Linux distributions by default, and the problem is severe enough that it should be resolved correctly).
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Child items 0
Show closed items
No child items are currently assigned. Use child items to break down this issue into smaller parts.
Linked items 0
Link issues together to show that they're related.
Learn more.
AFAIK no, but I will admit that I didn't look very hard through bugzilla. It's probably a fairly uncommon use case, so I'm not sure how much upstream will care about it.
There are at least two issues that I know of that prevent running Firefox without /proc mounted.
The first is that Firefox uses /proc/self/task to see if it spawned any threads. The warning can be ignored on any kernel that supports SECCOMP_FILTER_FLAG_TSYNC (>= 3.17), but may result in "bad" if the kernel is old, and no, I do not remember what the bad is.
The second is that Firefox will crash with too much recursion if /proc is not mounted. The culprit there is that Firefox will query the stack size with pthread_attr_getstack() which will return a stack size of 0, if /proc is not mounted for the default thread (tid == pid).
Note that there may be other horrific things that happen, or other things that break without /proc, but I was not able to find any at the time that I cared about this. Finding and debugging such things is left as an exercise for the student. Fixing this properly probably requires upstream to care about this use case.
If SECCOMP_FILTER_FLAG_TSYNC isn't available and /proc/self/task can't be listed, the sandbox can't start. The process is already multithreaded, so we have to signal all the threads to tell them to apply seccomp, and we don't have access to the libc's internal list of threads (or the lock protecting it) so we have to ask the kernel via procfs.
I've identified all (hopefully) the callers in the parent firefox and the child plugin_container (nothing unique in plugin_container though that isn't called in the parent). The spawned glxtest also has lots of reads going to /proc as well.
For patch verification, what's the procedure for hiding /proc from a process in general?
If SECCOMP_FILTER_FLAG_TSYNC isn't available and /proc/self/task can't be listed, the sandbox can't start. The process is already multithreaded, so we have to signal all the threads to tell them to apply seccomp, and we don't have access to the libc's internal list of threads (or the lock protecting it) so we have to ask the kernel via procfs.
I've identified all (hopefully) the callers in the parent firefox and the child plugin_container (nothing unique in plugin_container though that isn't called in the parent). The spawned glxtest also has lots of reads going to /proc as well.
For patch verification, what's the procedure for hiding /proc from a process in general?
I don't know but you could mess with Yawning's sandboxed-tor-browser (which brought this issue up in the first place), see: #20773 (closed) and the patch for it in 95857360ec7f84cf9f0a01855c15881c89919133.
I suspect that glibc relies on /proc only for the initial thread. It is possible that for the initial thread you can get the stack base address and size using getcontext(2). In particular, if pthread_getattr_np fails or pthread_attr_getstack returns null, and the thread in question is the process's initial thread, then it is possible that
As mentioned by cypherpunks, the issue here only occurs on the main thread which you can verify with a little spelunking through the glibc source. The relevant query APIs work expected on non-main threads since pthreads populates the required info in memory.
Verifying a patch now on TreeHerder that fixes this issue by reading the !__libc_stack_end symbol (glibc sets this void* to the first stack frame during program init). Solution suggested by mozilla's jld, and the folks in #jsapi (those paying attention at least) didn't seem offended at the idea of doing so for the main thread.