High firefox Memory Corruption 🔧 Commit mapped

Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
Impacthigh
DescriptionMemory safety bugs present in Firefox 133 and Thunderbird 133. Some of these bugs showed evidence of memory corruption and we presume that with enough effort some of these could have been exploited to run arbitrary code.
ComponentSecurity/NSS
Bug ClassMemory Corruption
Tracker1835193
Fix commit8579bc92b8e4 (firefox) +85/-116
CISA KEVNot listed
CreditedAkmat Suleimanov, Jed Davis, André Bargull, and the Mozilla Fuzzing Team
Disclosed2025-01-07

Changed Functions

FunctionChangeNotes
if
security/sandbox/linux/broker/SandboxBroker.cpp
modified
while
security/sandbox/linux/broker/SandboxBroker.cpp
modified
for
security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
modified
if
security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
modified

Files Changed

  • security/sandbox/linux/broker/SandboxBroker.cpp
  • security/sandbox/linux/broker/SandboxBroker.h
  • security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
  • security/sandbox/linux/gtest/TestBrokerPolicy.cpp
diff --git a/security/sandbox/linux/broker/SandboxBroker.cpp b/security/sandbox/linux/broker/SandboxBroker.cpp
index cca7c368598..648ab902709 100644
--- a/security/sandbox/linux/broker/SandboxBroker.cpp
+++ b/security/sandbox/linux/broker/SandboxBroker.cpp
@@ -160,34 +160,6 @@ void SandboxBroker::Policy::AddPath(int aPerms, const char* aPath,
 void SandboxBroker::Policy::AddTree(int aPerms, const char* aPath) {
   struct stat statBuf;
 
-  if (stat(aPath, &statBuf) != 0) {
-    return;
-  }
-  if (!S_ISDIR(statBuf.st_mode)) {
-    AddPath(aPerms, aPath, AddAlways);
-  } else {
-    DIR* dirp = opendir(aPath);
-    if (!dirp) {
-      return;
-    }
-    while (struct dirent* de = readdir(dirp)) {
-      if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0) {
-        continue;
-      }
-      // Note: could optimize the string handling.
-      nsAutoCString subPath;
-      subPath.Assign(aPath);
-      subPath.Append('/');
-      subPath.Append(de->d_name);
-      AddTree(aPerms, subPath.get());
-    }
-    closedir(dirp);
-  }
-}
-
-void SandboxBroker::Policy::AddDir(int aPerms, const char* aPath) {
-  struct stat statBuf;
-
   if (stat(aPath, &statBuf) != 0) {
     return;
   }
@@ -196,14 +168,14 @@ void SandboxBroker::Policy::AddDir(int aPerms, const char* aPath) {
     return;
   }
 
-  Policy::AddDirInternal(aPerms, aPath);
+  Policy::AddTreeInternal(aPerms, aPath);
 }
 
 void SandboxBroker::Policy::AddFutureDir(int aPerms, const char* aPath) {
-  Policy::AddDirInternal(aPerms, aPath);
+  Policy::AddTreeInternal(aPerms, aPath);
 }
 
-void SandboxBroker::Policy::AddDirInternal(int aPerms, const char* aPath) {
+void SandboxBroker::Policy::AddTreeInternal(int aPerms, const char* aPath) {
   // Add a Prefix permission on things inside the dir.
   nsDependentCString path(aPath);
   MOZ_ASSERT(path.Length() <= kMaxPathLen - 1);
@@ -270,7 +242,7 @@ void SandboxBroker::Policy::AddDynamic(int aPerms, const char* aPath) {
     size_t len = strlen(aPath);
     if (!len) return;
     if (aPath[len - 1] == '/') {
-      AddDir(aPerms, aPath);
+      AddTree(aPerms, aPath);
     } else {
       AddPath(aPerms, aPath);
     }
@@ -308,7 +280,7 @@ void SandboxBroker::Policy::FixRecursivePermissions() {
 
     nsAutoCString ancestor(path);
     // This is slightly different from the loop in AddAncestors: it
-    // leaves the trailing slashes attached so they'll match AddDir
+    // leaves the trailing slashes attached so they'll match AddTree
     // entries.
     while (true) {
       // Last() release-asserts that the string is not empty.  We
diff --git a/security/sandbox/linux/broker/SandboxBroker.h b/security/sandbox/linux/broker/SandboxBroker.h
index 7e8cf2c3f19..96193d2c853 100644
--- a/security/sandbox/linux/broker/SandboxBroker.h
+++ b/security/sandbox/linux/broker/SandboxBroker.h
@@ -70,7 +70,7 @@ class SandboxBroker final : private SandboxBrokerCommon,
     Policy(const Policy& aOther);
     ~Policy();
 
-    // Add permissions from AddDir/AddDynamic rules to any rules that
+    // Add permissions from AddTree/AddDynamic rules to any rules that
     // exist for their descendents, and remove any descendent rules
     // made redundant by this process.
     //
@@ -87,12 +87,9 @@ class SandboxBroker final : private SandboxBrokerCommon,
     // need to be whitelisted, but this allows adding entries for
     // them if they'll exist later.  See also the overload below.
     void AddPath(int aPerms, const char* aPath, AddCondition aCond);
-    // This adds all regular files (not directories) in the tree
-    // rooted at the given path.
-    void AddTree(int aPerms, const char* aPath);
     // A directory, and all files and directories under it, even those
     // added after creation (the dir itself must exist).
-    void AddDir(int aPerms, const char* aPath);
+    void AddTree(int aPerms, const char* aPath);
     // A directory, and all files and directories under it, even those
     // added after creation (the dir itself may not exist).
     void AddFutureDir(int aPerms, const char* aPath);
@@ -128,7 +125,7 @@ class SandboxBroker final : private SandboxBrokerCommon,
     // * No /../ path traversal
     bool ValidatePath(const char* path) const;
     void AddPrefixInternal(int aPerms, const nsACString& aPath);
-    void AddDirInternal(int aPerms, const char* aPath);
+    void AddTreeInternal(int aPerms, const char* aPath);
   };
 
   // Constructing a broker involves creating a socketpair and a
diff --git a/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp b/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
index 88f3c9d97a9..e8b23536de4 100644
--- a/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
+++ b/security/sandbox/linux/broker/SandboxBrokerPolicyFactory.cpp
@@ -301,7 +301,7 @@ static void AddLdconfigPaths(SandboxBroker::Policy* aPolicy) {
     });
   }
   for (const CacheE& e : ldConfigCache) {
-    aPolicy->AddDir(e.second, e.first.get());
+    aPolicy->AddTree(e.second, e.first.get());
   }
 }
 
@@ -315,7 +315,7 @@ static void AddLdLibraryEnvPaths(SandboxBroker::Policy* aPolicy) {
   for (const nsACString& libPath : LdLibraryEnv.Split(':')) {
     char* resolvedPath = realpath(PromiseFlatCString(libPath).get(), nullptr);
     if (resolvedPath) {
-      aPolicy->AddDir(rdonly, resolvedPath);
+      aPolicy->AddTree(rdonly, resolvedPath);
       free(resolvedPath);
     }
   }
@@ -388,16 +388,16 @@ static void AddX11Dependencies(SandboxBroker::Policy* policy) {
 
 static void AddGLDependencies(SandboxBroker::Policy* policy) {
   // Devices
-  policy->AddDir(rdwr, "/dev/dri");
+  policy->AddTree(rdwr, "/dev/dri");
   policy->AddFilePrefix(rdwr, "/dev", "nvidia");
 
   // Hardware info
   AddDriPaths(policy);
 
   // /etc and /usr/share (glvnd, libdrm, drirc, ...?)
-  policy->AddDir(rdonly, "/etc");
-  policy->AddDir(rdonly, "/usr/share");
-  policy->AddDir(rdonly, "/usr/local/share");
+  policy->AddTree(rdonly, "/etc");
+  policy->AddTree(rdonly, "/usr/share");
+  policy->AddTree(rdonly, "/usr/local/share");
 
   // Snap puts the usual /usr/share things in a different place, and
   // we'll fail to load the library if we don't have (at least) the
@@ -405,7 +405,7 @@ static void AddGLDependencies(SandboxBroker::Policy* policy) {
   if (const char* snapDesktopDir = PR_GetEnv("SNAP_DESKTOP_RUNTIME")) {
     nsAutoCString snapDesktopShare(snapDesktopDir);
     snapDesktopShare.AppendLiteral("/usr/share");
-    policy->AddDir(rdonly, snapDesktopShare.get());
+    policy->AddTree(rdonly, snapDesktopShare.get());
   }
 
   // Introduced by Snap's core24 changes there is a gpu-2404 dependency and
@@ -413,7 +413,7 @@ static void AddGLDependencies(SandboxBroker::Policy* policy) {
   if (const char* snapRoot = PR_GetEnv("SNAP")) {
     nsAutoCString snapRootString(snapRoot);
     snapRootString.AppendLiteral("/gpu-2404");
-    policy->AddDir(rdonly, snapRootString.get());
+    policy->AddTree(rdonly, snapRootString.get());
   }
 
   // Note: This function doesn't do anything about Mesa's shader
@@ -447,24 +447,24 @@ void SandboxBrokerPolicyFactory::InitContentPolicy() {
   policy->AddPath(rdonly, "/proc/sys/crypto/fips_enabled");
   policy->AddPath(rdonly, "/proc/cpuinfo");
   policy->AddPath(rdonly, "/proc/meminfo");
-  policy->AddDir(rdonly, "/sys/devices/cpu");
-  policy->AddDir(rdonly, "/sys/devices/system/cpu");
-  policy->AddDir(rdonly, "/lib");
-  policy->AddDir(rdonly, "/lib64");
-  policy->AddDir(rdonly, "/usr/lib");
-  policy->AddDir(rdonly, "/usr/lib32");
-  policy->AddDir(rdonly, "/usr/lib64");
-  policy->AddDir(rdonly, "/etc");
-  policy->AddDir(rdonly, "/usr/share");
-  policy->AddDir(rdonly, "/usr/local/share");
+  policy->AddTree(rdonly, "/sys/devices/cpu");
+  policy->AddTree(rdonly, "/sys/devices/system/cpu");
+  policy->AddTree(rdonly, "/lib");
+  policy->AddTree(rdonly, "/lib64");
+  policy->AddTree(rdonly, "/usr/lib");
+  policy->AddTree(rdonly, "/usr/lib32");
+  policy->AddTree(rdonly, "/usr/lib64");
+  policy->AddTree(rdonly, "/etc");
+  policy->AddTree(rdonly, "/usr/share");
+  policy->AddTree(rdonly, "/usr/local/share");
   // Various places where fonts reside
-  policy->AddDir(rdonly, "/usr/X11R6/lib/X11/fonts");
-  policy->AddDir(rdonly, "/nix/store");
+  policy->AddTree(rdonly, "/usr/X11R6/lib/X11/fonts");
Loading diff…