CVE-2026-12313
Overview
Background
- `SandboxBroker`
- Gecko’s privileged Linux broker process that mediates filesystem requests from sandboxed content processes against a path
Policy. - `SandboxBroker::SymlinkPath`
- a
realpath(3)-derived routine that canonicalizes a requestedpath, resolving symlinks and computing the effective permissions. - Path traversal
- using
..components in a path to reference directories above an intended root, escaping the confinement the policy assumes. - `Policy`
- the per-process allowlist mapping canonical path prefixes to granted access
perms.
Root Cause Analysis
The vulnerable code path is SandboxBroker::SymlinkPath in SandboxBrokerRealpath.cpp, which resolved a content-process-supplied path before matching it against the broker’s Policy. The routine’s invariant is that the resolved path it returns is fully canonical and stays within the paths the Policy grants, but its symlink/component walk did not reliably neutralize .. segments, so a crafted path containing /../ (or one equal to, starting with, or ending in ..) could be steered outside the intended subtree while still passing the subsequent permission check.
The fix adds an early guard that computes path_len and rejects any path matching those four .. patterns with errno = EPERM before resolution begins. This works because refusing to resolve any path bearing a traversal component removes the attacker’s ability to construct a canonical result that lands outside the allowed prefix, forcing such requests to fail closed rather than be brokered.
SymlinkPath to canonicalize away .. traversal components before the Policy check, when it could instead produce an out-of-bounds path; the fix rejects ..-bearing inputs outright with EPERM so no traversal request is ever resolved or authorized.Attack Path
- Compromise or drive a content process The attacker obtains code execution (or attacker-controlled path input) inside a sandboxed process that issues brokered filesystem requests.
- Craft a traversal path
The attacker submits a
pathcontaining a/../component (or one that is.., begins with../, or ends with/..) to the broker. - Bypass canonicalization
SandboxBroker::SymlinkPathresolves the path such that the..steers the result outside the subtree thePolicyintended to allow. - Pass the policy check The resolved path matches an allowed prefix, so the broker grants access and performs the operation on a file outside sandbox confinement.
- Read or act on restricted files The attacker leverages the brokered access to disclose information or widen its foothold, weakening the sandbox boundary.
Impact Assessment
.. traversal in brokered path requests, yielding information disclosure and a step toward sandbox escape. This occurs in the privileged broker’s evaluation of content-process requests on Linux. The precondition is attacker-controlled path input reaching SandboxBroker::SymlinkPath, typically from a compromised or coerced content process.Changed Functions
| Function | Change | Notes |
|---|---|---|
ifsecurity/sandbox/linux/broker/SandboxBrokerRealpath.cpp |
modified |
Files Changed
security/sandbox/linux/broker/SandboxBrokerRealpath.cpp
Audit Directions
- Traversal-before-canonicalizationAudit every broker or IPC path handler that matches a policy against a path it canonicalizes; verify
..components are neutralized or rejected before, not after, the authorization decision. - Fail-open resolutionReview
realpath-style routines ported into privileged code for edge cases where malformed or relative inputs yield a usable path instead of an error, and confirm they fail closed. - Untrusted path inputsTrace all content-process-supplied strings that reach
SandboxBrokerand confirm each is validated at the trust boundary rather than assumed canonical.
Patch
diff --git a/security/sandbox/linux/broker/SandboxBrokerRealpath.cpp b/security/sandbox/linux/broker/SandboxBrokerRealpath.cpp
index 04de4a56cc4..a5195672b78 100644
--- a/security/sandbox/linux/broker/SandboxBrokerRealpath.cpp
+++ b/security/sandbox/linux/broker/SandboxBrokerRealpath.cpp
@@ -45,6 +45,7 @@ static char sccsid[] = "@(#)realpath.c 8.1 (Berkeley) 2/16/94";
#include "base/string_util.h"
#include "SandboxBroker.h"
+#include "SandboxLogging.h"
// Original copy in, but not usable from here:
// toolkit/crashreporter/google-breakpad/src/common/linux/linux_libc_support.cc
@@ -74,7 +75,7 @@ char* SandboxBroker::SymlinkPath(const Policy* policy,
char* __restrict resolved, int* perms) {
struct stat sb;
char *p, *q, *s;
- size_t left_len, resolved_len, backup_allowed;
+ size_t left_len, resolved_len, backup_allowed, path_len;
unsigned symlinks;
int m, slen;
char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX];
@@ -90,6 +91,13 @@ char* SandboxBroker::SymlinkPath(const Policy* policy,
errno = ENOENT;
return (nullptr);
}
+ path_len = strlen(path);
+ if (strstr(path, "/../") || strcmp(path, "..") == 0 ||
+ strncmp(path, "../", 3) == 0 ||
+ (path_len >= 3 && strcmp(path + path_len - 3, "/..") == 0)) {
+ errno = EPERM;
+ return (nullptr);
+ }
if (resolved == nullptr) {
resolved = (char*)malloc(PATH_MAX);
if (resolved == nullptr) return (nullptr);