High firefox Logic Error 🔧 Commit mapped

Overview

High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Impacthigh
DescriptionSandbox escape due to use-after-free in the DOM: Core & HTML component
ComponentDOM
Bug ClassLogic Error
Tracker2068406
Fix commit3d39d95ab1c8 (firefox) +23/-1
CISA KEVNot listed
CreditedMozilla
Disclosed2026-09-29

Files Changed

  • dom/ipc/FilePickerParent.cpp
  • widget/gtk/nsFilePicker.cpp
  • widget/nsBaseFilePicker.cpp
  • widget/nsBaseFilePicker.h
diff --git a/dom/ipc/FilePickerParent.cpp b/dom/ipc/FilePickerParent.cpp
index a896c358915..f9e088ada34 100644
--- a/dom/ipc/FilePickerParent.cpp
+++ b/dom/ipc/FilePickerParent.cpp
@@ -12,6 +12,7 @@
 #include "mozilla/dom/FileBlobImpl.h"
 #include "mozilla/dom/FileSystemSecurity.h"
 #include "mozilla/dom/IPCBlobUtils.h"
+#include "nsBaseFilePicker.h"
 #include "nsComponentManagerUtils.h"
 #include "nsIFile.h"
 #include "nsISimpleEnumerator.h"
@@ -303,7 +304,8 @@ mozilla::ipc::IPCResult FilePickerParent::RecvOpen(
   if (!aDisplayDirectory.IsEmpty()) {
     nsCOMPtr<nsIFile> localFile;
     if (NS_SUCCEEDED(
-            NS_NewLocalFile(aDisplayDirectory, getter_AddRefs(localFile)))) {
+            NS_NewLocalFile(aDisplayDirectory, getter_AddRefs(localFile))) &&
+        localFile && nsBaseFilePicker::IsReadableDirectory(*localFile)) {
       mFilePicker->SetDisplayDirectory(localFile);
     }
   } else if (!aDisplaySpecialDirectory.IsEmpty()) {
diff --git a/widget/gtk/nsFilePicker.cpp b/widget/gtk/nsFilePicker.cpp
index b6bcca3e0e2..5f8cf9670e9 100644
--- a/widget/gtk/nsFilePicker.cpp
+++ b/widget/gtk/nsFilePicker.cpp
@@ -806,6 +806,11 @@ already_AddRefed<nsIFile> nsFilePicker::GetDefaultPath() {
   } else if (sPrevDisplayDirectory) {
     sPrevDisplayDirectory->Clone(getter_AddRefs(defaultPath));
   }
+
+  if (!defaultPath || !IsReadableDirectory(*defaultPath)) {
+    return nullptr;
+  }
+
   return defaultPath.forget();
 }
 
diff --git a/widget/nsBaseFilePicker.cpp b/widget/nsBaseFilePicker.cpp
index 28afe90f711..5d88f17ddc7 100644
--- a/widget/nsBaseFilePicker.cpp
+++ b/widget/nsBaseFilePicker.cpp
@@ -292,6 +292,11 @@ NS_IMETHODIMP nsBaseFilePicker::SetDisplayDirectory(nsIFile* aDirectory) {
     mDisplayDirectory = nullptr;
     return NS_OK;
   }
+
+  if (!IsReadableDirectory(*aDirectory)) {
+    return NS_ERROR_FAILURE;
+  }
+
   nsCOMPtr<nsIFile> directory;
   nsresult rv = aDirectory->Clone(getter_AddRefs(directory));
   if (NS_FAILED(rv)) {
@@ -403,6 +408,14 @@ bool nsBaseFilePicker::IsWithinInputProtectionTimeRange(
   return (aNow - aShowTime).ToMilliseconds() < double(aProtectionMs);
 }
 
+// static
+bool nsBaseFilePicker::IsReadableDirectory(nsIFile& aDirectory) {
+  bool isDirectory = false;
+  bool isReadable = false;
+  return NS_SUCCEEDED(aDirectory.IsDirectory(&isDirectory)) && isDirectory &&
+         NS_SUCCEEDED(aDirectory.IsReadable(&isReadable)) && isReadable;
+}
+
 bool nsBaseFilePicker::IsContentInitiated() const {
   if (!mBrowsingContext || !mBrowsingContext->IsContent()) {
     return false;
diff --git a/widget/nsBaseFilePicker.h b/widget/nsBaseFilePicker.h
index 4a1780bf38c..6eba0d369e5 100644
--- a/widget/nsBaseFilePicker.h
+++ b/widget/nsBaseFilePicker.h
@@ -64,6 +64,8 @@ class nsBaseFilePicker : public nsIFilePicker {
                                                mozilla::TimeStamp aNow,
                                                uint32_t aProtectionMs);
 
+  static bool IsReadableDirectory(nsIFile& aDirectory);
+
  protected:
   virtual ~nsBaseFilePicker();
 
Loading diff…