Shared security patch analysis results
AI Used: DEEPSEEK deepseek-chat--- /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_97_END/firefox-FIREFOX_RELEASE_97_END/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.double.html+++ /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_98_END/firefox-FIREFOX_RELEASE_98_END/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.double.html@@ -17,18 +17,18 @@ }); t.step(function() {-var offscreenCanvas = new OffscreenCanvas(100, 50);-var ctx = offscreenCanvas.getContext('2d');+var canvas = new OffscreenCanvas(100, 50);+var ctx = canvas.getContext('2d'); ctx.fillStyle = '#f00'; ctx.fillRect(0, 0, 100, 50); ctx.roundRect(0, 0, 100, 50, [0, 0, 20, 0]); ctx.fillStyle = '#0f0'; ctx.fill();-_assertPixel(offscreenCanvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255");-_assertPixel(offscreenCanvas, 98,1, 0,255,0,255, "98,1", "0,255,0,255");-_assertPixel(offscreenCanvas, 98,48, 255,0,0,255, "98,48", "255,0,0,255");-_assertPixel(offscreenCanvas, 1,48, 0,255,0,255, "1,48", "0,255,0,255");+_assertPixel(canvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255");+_assertPixel(canvas, 98,1, 0,255,0,255, "98,1", "0,255,0,255");+_assertPixel(canvas, 98,48, 255,0,0,255, "98,48", "255,0,0,255");+_assertPixel(canvas, 1,48, 0,255,0,255, "1,48", "0,255,0,255"); t.done(); });
Based on the provided code diff, I don't see any security vulnerabilities being fixed. The changes appear to be purely variable renaming (from `offscreenCanvas` to `canvas`) and corresponding updates to the variable name in the assertions. Here's the analysis: 1. Vulnerability Existed: no No vulnerability found [File: testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.roundrect.4.radii.3.double.html] [Lines: 17-18, 24-27] Old Code: ``` var offscreenCanvas = new OffscreenCanvas(100, 50); var ctx = offscreenCanvas.getContext('2d'); _assertPixel(offscreenCanvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255"); ``` Fixed Code: ``` var canvas = new OffscreenCanvas(100, 50); var ctx = canvas.getContext('2d'); _assertPixel(canvas, 1,1, 0,255,0,255, "1,1", "0,255,0,255"); ``` The changes are purely cosmetic/refactoring in nature and don't appear to address any security issues. The functionality remains exactly the same, just with a different variable name.
If an attacker could control the contents of an iframe sandboxed with <code>allow-popups</code> but not <code>allow-scripts</code>, they were able to craft a link that, when clicked, would lead to JavaScript execution in violation of the sandbox. This vulnerability affects Firefox < 98, Firefox ESR < 91.7, and Thunderbird < 91.7.
--- /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_97_END/firefox-FIREFOX_RELEASE_97_END/ipc/chromium/src/chrome/common/ipc_message.h+++ /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_98_END/firefox-FIREFOX_RELEASE_98_END/ipc/chromium/src/chrome/common/ipc_message.h@@ -74,11 +74,6 @@ ASYNC = 1, };- enum Interrupt {- NOT_INTERRUPT = 0,- INTERRUPT = 1,- };- enum Constructor { NOT_CONSTRUCTOR = 0, CONSTRUCTOR = 1,@@ -102,7 +97,7 @@ SYNC_BIT = 0x0020, REPLY_BIT = 0x0040, REPLY_ERROR_BIT = 0x0080,- INTERRUPT_BIT = 0x0100,+ /* UNUSED = 0x0100, */ COMPRESS_BIT = 0x0200, COMPRESSALL_BIT = 0x0400, CONSTRUCTOR_BIT = 0x0800,@@ -116,15 +111,13 @@ constexpr HeaderFlags(NestedLevel level, PriorityValue priority, MessageCompression compression,- Constructor constructor, Sync sync,- Interrupt interrupt, Reply reply)+ Constructor constructor, Sync sync, Reply reply) : mFlags(level | (priority << 2) | (compression == COMPRESSION_ENABLED ? COMPRESS_BIT : compression == COMPRESSION_ALL ? COMPRESSALL_BIT : 0) | (constructor == CONSTRUCTOR ? CONSTRUCTOR_BIT : 0) | (sync == SYNC ? SYNC_BIT : 0) |- (interrupt == INTERRUPT ? INTERRUPT_BIT : 0) | (reply == REPLY ? REPLY_BIT : 0)) {} NestedLevel Level() const {@@ -143,7 +136,6 @@ bool IsConstructor() const { return (mFlags & CONSTRUCTOR_BIT) != 0; } bool IsSync() const { return (mFlags & SYNC_BIT) != 0; }- bool IsInterrupt() const { return (mFlags & INTERRUPT_BIT) != 0; } bool IsReply() const { return (mFlags & REPLY_BIT) != 0; } bool IsReplyError() const { return (mFlags & REPLY_ERROR_BIT) != 0; }@@ -151,7 +143,6 @@ private: void SetSync() { mFlags |= SYNC_BIT; }- void SetInterrupt() { mFlags |= INTERRUPT_BIT; } void SetReply() { mFlags |= REPLY_BIT; } void SetReplyError() { mFlags |= REPLY_ERROR_BIT; } void SetRelay(bool relay) {@@ -191,7 +182,6 @@ // One-off constructors for special error-handling messages. static Message* ForSyncDispatchError(NestedLevel level);- static Message* ForInterruptDispatchError(); NestedLevel nested_level() const { return header()->flags.Level(); }@@ -202,9 +192,6 @@ // True if this is a synchronous message. bool is_sync() const { return header()->flags.IsSync(); }- // True if this is a synchronous message.- bool is_interrupt() const { return header()->flags.IsInterrupt(); }- MessageCompression compress_type() const { return header()->flags.Compression(); }@@ -224,24 +211,6 @@ int32_t transaction_id() const { return header()->txid; } void set_transaction_id(int32_t txid) { header()->txid = txid; }-- uint32_t interrupt_remote_stack_depth_guess() const {- return header()->interrupt_remote_stack_depth_guess;- }-- void set_interrupt_remote_stack_depth_guess(uint32_t depth) {- DCHECK(is_interrupt());- header()->interrupt_remote_stack_depth_guess = depth;- }-- uint32_t interrupt_local_stack_depth() const {- return header()->interrupt_local_stack_depth;- }-- void set_interrupt_local_stack_depth(uint32_t depth) {- DCHECK(is_interrupt());- header()->interrupt_local_stack_depth = depth;- } int32_t seqno() const { return header()->seqno; }@@ -388,16 +357,8 @@ uint32_t num_send_rights; // the number of mach send rights included with // this message #endif- union {- // For Interrupt messages, a guess at what the *other* side's stack depth- // is.- uint32_t interrupt_remote_stack_depth_guess;-- // For RPC and Urgent messages, a transaction ID for message ordering.- int32_t txid;- };- // The actual local stack depth.- uint32_t interrupt_local_stack_depth;+ // For sync messages, a transaction ID for message ordering.+ int32_t txid; // Sequence number int32_t seqno; // Size of the message's event footer@@ -428,21 +389,6 @@ #endif };-class MessageInfo {- public:- typedef uint32_t msgid_t;-- explicit MessageInfo(const Message& aMsg)- : mSeqno(aMsg.seqno()), mType(aMsg.type()) {}-- int32_t seqno() const { return mSeqno; }- msgid_t type() const { return mType; }-- private:- int32_t mSeqno;- msgid_t mType;-};- //------------------------------------------------------------------------------ } // namespace IPC
Here's the analysis of the provided code diff for security fixes: 1. Vulnerability Existed: not sure [Removed Interrupt Message Handling] [ipc/chromium/src/chrome/common/ipc_message.h] [Lines 74-78, 102, 116-143, 191, 202-204, 224-236, 357-368] Old Code: ```cpp enum Interrupt { NOT_INTERRUPT = 0, INTERRUPT = 1, }; // ... and all interrupt-related code including INTERRUPT_BIT, is_interrupt(), interrupt_remote_stack_depth_guess, interrupt_local_stack_depth ``` Fixed Code: ```cpp /* INTERRUPT functionality completely removed */ ``` Note: While this appears to be a significant change removing interrupt message handling, it's unclear if this was fixing a specific vulnerability or just cleaning up unused code. 2. Vulnerability Existed: not sure [Removed MessageInfo Class] [ipc/chromium/src/chrome/common/ipc_message.h] [Lines 428-442] Old Code: ```cpp class MessageInfo { public: typedef uint32_t msgid_t; explicit MessageInfo(const Message& aMsg) : mSeqno(aMsg.seqno()), mType(aMsg.type()) {} int32_t seqno() const { return mSeqno; } msgid_t type() const { return mType; } private: int32_t mSeqno; msgid_t mType; }; ``` Fixed Code: ```cpp /* MessageInfo class completely removed */ ``` Note: The removal of this helper class might be related to security hardening, but without more context it's unclear if this addressed a specific vulnerability. The changes primarily involve removing interrupt message functionality and cleaning up related code. While these could potentially address security issues (like removing attack surface for interrupt-based vulnerabilities), the diff doesn't provide enough context to confirm specific vulnerabilities being fixed. The changes might also simply represent code cleanup of unused features.
If an attacker could control the contents of an iframe sandboxed with <code>allow-popups</code> but not <code>allow-scripts</code>, they were able to craft a link that, when clicked, would lead to JavaScript execution in violation of the sandbox. This vulnerability affects Firefox < 98, Firefox ESR < 91.7, and Thunderbird < 91.7.
--- /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_97_END/firefox-FIREFOX_RELEASE_97_END/dom/media/DynamicResampler.h+++ /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_98_END/firefox-FIREFOX_RELEASE_98_END/dom/media/DynamicResampler.h@@ -332,7 +332,7 @@ private: nsTArray<AudioChunk> mChunks; uint32_t mIndex = 0;- uint32_t mChunkCapacity = 128;+ uint32_t mChunkCapacity = WEBAUDIO_BLOCK_SIZE; AudioSampleFormat mSampleFormat = AUDIO_FORMAT_SILENCE; };
Analyzing the provided code diff for security fixes: 1. Vulnerability Existed: not sure [Potential Integer Overflow/Underflow] [dom/media/DynamicResampler.h] [Lines 332] [Old Code] `uint32_t mChunkCapacity = 128;` [Fixed Code] `uint32_t mChunkCapacity = WEBAUDIO_BLOCK_SIZE;` Additional Details: - The change replaces a hardcoded value (128) with a constant (WEBAUDIO_BLOCK_SIZE). While this doesn't directly indicate a security vulnerability, hardcoded values can sometimes lead to buffer-related issues if they don't match system requirements. - Without knowing the context of how mChunkCapacity is used, it's unclear if this was fixing a potential buffer overflow/underflow issue. The change suggests better alignment with audio processing standards. - No specific CVE or vulnerability name is directly associated with this change. Note: The change appears to be more of a code improvement than a direct security fix, but could potentially prevent issues related to incorrect buffer sizing in audio processing.
If an attacker could control the contents of an iframe sandboxed with <code>allow-popups</code> but not <code>allow-scripts</code>, they were able to craft a link that, when clicked, would lead to JavaScript execution in violation of the sandbox. This vulnerability affects Firefox < 98, Firefox ESR < 91.7, and Thunderbird < 91.7.
--- /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_97_END/firefox-FIREFOX_RELEASE_97_END/third_party/rust/crossbeam-epoch/build.rs+++ /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_98_END/firefox-FIREFOX_RELEASE_98_END/third_party/rust/crossbeam-epoch/build.rs@@ -4,9 +4,19 @@ include!("no_atomic.rs");-// The rustc-cfg strings below are *not* public API. Please let us know by-// opening a GitHub issue if your build environment requires some way to enable-// these cfgs other than by executing our build script.+// The rustc-cfg listed below are considered public API, but it is *unstable*+// and outside of the normal semver guarantees:+//+// - `crossbeam_no_atomic_cas`+// Assume the target does *not* support atomic CAS operations.+// This is usually detected automatically by the build script, but you may+// need to enable it manually when building for custom targets or using+// non-cargo build systems that don't run the build script.+//+// With the exceptions mentioned above, the rustc-cfg strings below are+// *not* public API. Please let us know by opening a GitHub issue if your build+// environment requires some way to enable these cfgs other than by executing+// our build script. fn main() { let target = match env::var("TARGET") { Ok(target) => target,
Based on the provided diff, I don't see any clear security vulnerabilities being fixed. The changes appear to be documentation improvements and clarifications about the public API status of certain build configurations. Here's the analysis following your requested format: Vulnerability Existed: no Documentation Clarification [third_party/rust/crossbeam-epoch/build.rs] [Lines 4-17] [Old Code] // The rustc-cfg strings below are *not* public API. Please let us know by // opening a GitHub issue if your build environment requires some way to enable // these cfgs other than by executing our build script. [Fixed Code] // The rustc-cfg listed below are considered public API, but it is *unstable* // and outside of the normal semver guarantees: // // - `crossbeam_no_atomic_cas` // Assume the target does *not* support atomic CAS operations. // This is usually detected automatically by the build script, but you may // need to enable it manually when building for custom targets or using // non-cargo build systems that don't run the build script. // // With the exceptions mentioned above, the rustc-cfg strings below are // *not* public API. Please let us know by opening a GitHub issue if your build // environment requires some way to enable these cfgs other than by executing // our build script. This change improves documentation clarity about which parts of the API are considered public versus private, but doesn't appear to address any security vulnerabilities. The modification is primarily about better communicating the stability guarantees of certain build configurations.
If an attacker could control the contents of an iframe sandboxed with <code>allow-popups</code> but not <code>allow-scripts</code>, they were able to craft a link that, when clicked, would lead to JavaScript execution in violation of the sandbox. This vulnerability affects Firefox < 98, Firefox ESR < 91.7, and Thunderbird < 91.7.
--- /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_97_END/firefox-FIREFOX_RELEASE_97_END/third_party/rust/ash/src/extensions/ext/tooling_info.rs+++ /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_98_END/firefox-FIREFOX_RELEASE_98_END/third_party/rust/ash/src/extensions/ext/tooling_info.rs@@ -1,28 +1,20 @@ use crate::prelude::*; use crate::vk;-use crate::{EntryCustom, Instance};+use crate::{Entry, Instance}; use std::ffi::CStr; use std::mem; #[derive(Clone)] pub struct ToolingInfo {- handle: vk::Instance,- tooling_info_fn: vk::ExtToolingInfoFn,+ fp: vk::ExtToolingInfoFn, } impl ToolingInfo {- pub fn new<L>(entry: &EntryCustom<L>, instance: &Instance) -> Self {- let tooling_info_fn = vk::ExtToolingInfoFn::load(|name| unsafe {+ pub fn new(entry: &Entry, instance: &Instance) -> Self {+ let fp = vk::ExtToolingInfoFn::load(|name| unsafe { mem::transmute(entry.get_instance_proc_addr(instance.handle(), name.as_ptr())) });- Self {- handle: instance.handle(),- tooling_info_fn,- }- }-- pub fn name() -> &'static CStr {- vk::ExtToolingInfoFn::name()+ Self { fp } } #[doc = "<https://www.khronos.org/registry/vulkan/specs/1.2-extensions/man/html/vkGetPhysicalDeviceToolPropertiesEXT.html>"]@@ -31,16 +23,16 @@ physical_device: vk::PhysicalDevice, ) -> VkResult<Vec<vk::PhysicalDeviceToolPropertiesEXT>> { read_into_defaulted_vector(|count, data| {- self.tooling_info_fn+ self.fp .get_physical_device_tool_properties_ext(physical_device, count, data) }) }- pub fn fp(&self) -> &vk::ExtToolingInfoFn {- &self.tooling_info_fn+ pub fn name() -> &'static CStr {+ vk::ExtToolingInfoFn::name() }- pub fn instance(&self) -> vk::Instance {- self.handle+ pub fn fp(&self) -> &vk::ExtToolingInfoFn {+ &self.fp } }
Let me analyze the code diff for potential security vulnerabilities: 1. Vulnerability Existed: no No specific vulnerability found [File] third_party/rust/ash/src/extensions/ext/tooling_info.rs [Lines] Various [Old Code] The old implementation stored both instance handle and function pointers separately [Fixed Code] The new implementation simplifies the structure to only store function pointers 2. Vulnerability Existed: not sure Potential API misuse reduction [File] third_party/rust/ash/src/extensions/ext/tooling_info.rs [Lines] Various [Old Code] Used EntryCustom<L> with generic parameter and exposed instance handle [Fixed Code] Uses non-generic Entry and doesn't expose instance handle directly The changes appear to be primarily structural improvements rather than security fixes: 1. Simplified the struct by removing the redundant instance handle storage 2. Changed from generic EntryCustom to non-generic Entry 3. Reorganized the methods (name() and fp() swapped positions) 4. No obvious memory safety or security issues were present in either version The changes might reduce potential for API misuse by: - Removing direct access to the instance handle - Simplifying the interface But these are architectural improvements rather than fixes for specific vulnerabilities.
If an attacker could control the contents of an iframe sandboxed with <code>allow-popups</code> but not <code>allow-scripts</code>, they were able to craft a link that, when clicked, would lead to JavaScript execution in violation of the sandbox. This vulnerability affects Firefox < 98, Firefox ESR < 91.7, and Thunderbird < 91.7.
--- /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_97_END/firefox-FIREFOX_RELEASE_97_END/taskcluster/ci/source-test/python.yml+++ /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_98_END/firefox-FIREFOX_RELEASE_98_END/taskcluster/ci/source-test/python.yml@@ -36,6 +36,7 @@ firefox-ci: description: taskcluster/gecko_taskgraph unit tests+ always-target: false python-version: [3] treeherder: symbol: ci@@ -248,6 +249,10 @@ mozversioncontrol: description: python/mozversioncontrol unit tests+ platform:+ - linux1804-64/opt+ - macosx1015-64/opt+ - windows10-64/opt python-version: [3] treeherder: symbol: vcs
Analyzing the provided code diff, I don't see any clear security vulnerabilities being fixed. The changes appear to be configuration updates rather than security patches. Here's the analysis: 1. Vulnerability Existed: no Configuration update [File] taskcluster/ci/source-test/python.yml [Lines] 36-37 [Old Code] firefox-ci: description: taskcluster/gecko_taskgraph unit tests [Fixed Code] firefox-ci: description: taskcluster/gecko_taskgraph unit tests always-target: false 2. Vulnerability Existed: no Configuration update [File] taskcluster/ci/source-test/python.yml [Lines] 248-252 [Old Code] mozversioncontrol: description: python/mozversioncontrol unit tests [Fixed Code] mozversioncontrol: description: python/mozversioncontrol unit tests platform: - linux1804-64/opt - macosx1015-64/opt - windows10-64/opt The changes involve: 1. Adding an `always-target: false` configuration for the firefox-ci job 2. Adding platform specifications for the mozversioncontrol job Neither change appears to address a security vulnerability, but rather improves job configuration and specificity.
If an attacker could control the contents of an iframe sandboxed with <code>allow-popups</code> but not <code>allow-scripts</code>, they were able to craft a link that, when clicked, would lead to JavaScript execution in violation of the sandbox. This vulnerability affects Firefox < 98, Firefox ESR < 91.7, and Thunderbird < 91.7.
--- /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_97_END/firefox-FIREFOX_RELEASE_97_END/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.zero.worker.js+++ /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_98_END/firefox-FIREFOX_RELEASE_98_END/testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.zero.worker.js@@ -13,15 +13,15 @@ }); t.step(function() {-var offscreenCanvas = new OffscreenCanvas(100, 50);-var ctx = offscreenCanvas.getContext('2d');+var canvas = new OffscreenCanvas(100, 50);+var ctx = canvas.getContext('2d'); ctx.fillStyle = '#f00'; ctx.fillRect(0, 0, 100, 50); ctx.rotate(0); ctx.fillStyle = '#0f0'; ctx.fillRect(0, 0, 100, 50);-_assertPixel(offscreenCanvas, 50,25, 0,255,0,255, "50,25", "0,255,0,255");+_assertPixel(canvas, 50,25, 0,255,0,255, "50,25", "0,255,0,255"); t.done(); });
Based on the provided code diff, I don't see any security vulnerabilities being fixed. The changes appear to be purely variable renaming and don't involve any security-sensitive operations. Here's the analysis following your requested format: Vulnerability Existed: no No security vulnerability found [testing/web-platform/tests/html/canvas/offscreen/transformations/2d.transformation.rotate.zero.worker.js] [Lines 13-22] [Old Code] var offscreenCanvas = new OffscreenCanvas(100, 50); var ctx = offscreenCanvas.getContext('2d'); ... _assertPixel(offscreenCanvas, 50,25, 0,255,0,255, "50,25", "0,255,0,255"); [Fixed Code] var canvas = new OffscreenCanvas(100, 50); var ctx = canvas.getContext('2d'); ... _assertPixel(canvas, 50,25, 0,255,0,255, "50,25", "0,255,0,255"); The changes are: 1. Renaming variable `offscreenCanvas` to `canvas` 2. Updating the variable name in the `_assertPixel` call 3. No changes to the actual security-sensitive operations or logic No security vulnerabilities were identified in this diff. The changes appear to be cosmetic/refactoring in nature.
If an attacker could control the contents of an iframe sandboxed with <code>allow-popups</code> but not <code>allow-scripts</code>, they were able to craft a link that, when clicked, would lead to JavaScript execution in violation of the sandbox. This vulnerability affects Firefox < 98, Firefox ESR < 91.7, and Thunderbird < 91.7.
--- /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_97_END/firefox-FIREFOX_RELEASE_97_END/third_party/rust/tokio-timer/src/clock/mod.rs+++ /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_98_END/firefox-FIREFOX_RELEASE_98_END/third_party/rust/tokio-timer/src/clock/mod.rs@@ -19,5 +19,5 @@ mod clock; mod now;-pub use self::clock::{now, with_default, Clock};+pub use self::clock::{now, set_default, with_default, Clock, DefaultGuard}; pub use self::now::Now;
Let me analyze the diff for potential security vulnerabilities. Vulnerability Existed: not sure Potential API Exposure Vulnerability [third_party/rust/tokio-timer/src/clock/mod.rs] [Lines 19] [Old Code] pub use self::clock::{now, with_default, Clock}; [Fixed Code] pub use self::clock::{now, set_default, with_default, Clock, DefaultGuard}; Additional Details: 1. The change exposes two new items (`set_default` and `DefaultGuard`) from the clock module 2. While this could potentially be a security concern if these functions allow unsafe operations or improper clock manipulation, there's not enough context to confirm 3. The change appears to be more about API exposure than a direct security fix 4. Without seeing the implementation of these new exposed functions, we can't determine if they introduce or fix vulnerabilities The diff shows an expansion of the public API surface, but doesn't clearly indicate a security vulnerability being fixed. It might be related to functionality improvements or better control over clock operations.
If an attacker could control the contents of an iframe sandboxed with <code>allow-popups</code> but not <code>allow-scripts</code>, they were able to craft a link that, when clicked, would lead to JavaScript execution in violation of the sandbox. This vulnerability affects Firefox < 98, Firefox ESR < 91.7, and Thunderbird < 91.7.
--- /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_97_END/firefox-FIREFOX_RELEASE_97_END/widget/gtk/nsAppShell.cpp+++ /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_98_END/firefox-FIREFOX_RELEASE_98_END/widget/gtk/nsAppShell.cpp@@ -27,6 +27,8 @@ # include "nsIObserverService.h" #endif #include "gfxPlatform.h"+#include "nsAppRunner.h"+#include "mozilla/XREAppData.h" #include "ScreenHelperGTK.h" #include "HeadlessScreenHelper.h" #include "mozilla/widget/ScreenManager.h"@@ -257,13 +259,9 @@ // See https://bugzilla.gnome.org/show_bug.cgi?id=747634 // // Only bother doing this for the parent process, since it's the one- // creating top-level windows. (At this point, a child process hasn't- // received the list of registered chrome packages, so the- // GetBrandShortName call would fail anyway.)- nsAutoString brandName;- mozilla::widget::WidgetUtils::GetBrandShortName(brandName);- if (!brandName.IsEmpty()) {- gdk_set_program_class(NS_ConvertUTF16toUTF8(brandName).get());+ // creating top-level windows.+ if (gAppData) {+ gdk_set_program_class(gAppData->remotingName); } } }@@ -349,9 +347,20 @@ } bool nsAppShell::ProcessNextNativeEvent(bool mayWait) {- bool ret = g_main_context_iteration(nullptr, mayWait);+ bool didProcessEvent = false;+ if (mayWait) {+ // Block until we get an event. If g_main_context_iteration returns false,+ // keep calling it until it returns true. It can return false if it is+ // interrupted by a signal, for example during profiling, and we want to+ // ignore such interruptions.+ while (!didProcessEvent) {+ didProcessEvent = g_main_context_iteration(nullptr, true);+ }+ } else {+ didProcessEvent = g_main_context_iteration(nullptr, false);+ } #ifdef MOZ_WAYLAND mozilla::widget::WaylandDispatchDisplays(); #endif- return ret;-}+ return didProcessEvent;+}
Here's the analysis of the provided code diff for security fixes: 1. Vulnerability Existed: not sure [Potential Information Leak] [widget/gtk/nsAppShell.cpp] [Lines 257-263] [Old Code] nsAutoString brandName; mozilla::widget::WidgetUtils::GetBrandShortName(brandName); if (!brandName.IsEmpty()) { gdk_set_program_class(NS_ConvertUTF16toUTF8(brandName).get()); } [Fixed Code] if (gAppData) { gdk_set_program_class(gAppData->remotingName); } Additional Details: The change moves from using brand name to remotingName, which might be related to preventing potential information leakage about the application, but this isn't clearly a security fix. 2. Vulnerability Existed: not sure [Potential Event Processing Race Condition] [widget/gtk/nsAppShell.cpp] [Lines 349-360] [Old Code] bool ret = g_main_context_iteration(nullptr, mayWait); [Fixed Code] bool didProcessEvent = false; if (mayWait) { while (!didProcessEvent) { didProcessEvent = g_main_context_iteration(nullptr, true); } } else { didProcessEvent = g_main_context_iteration(nullptr, false); } Additional Details: The change makes event processing more robust by ensuring events are properly handled even when interrupted, which could potentially prevent race conditions, but this appears more like a reliability fix than a security fix. Note: While these changes improve the code's robustness, I couldn't identify any clear security vulnerabilities that were fixed. The changes appear to be more about reliability and proper program behavior than addressing specific security issues.
If an attacker could control the contents of an iframe sandboxed with <code>allow-popups</code> but not <code>allow-scripts</code>, they were able to craft a link that, when clicked, would lead to JavaScript execution in violation of the sandbox. This vulnerability affects Firefox < 98, Firefox ESR < 91.7, and Thunderbird < 91.7.
--- /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_97_END/firefox-FIREFOX_RELEASE_97_END/third_party/rust/quote/tests/test.rs+++ /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_98_END/firefox-FIREFOX_RELEASE_98_END/third_party/rust/quote/tests/test.rs@@ -176,10 +176,11 @@ let uusize = 1usize; let tokens = quote! {+ 1 1i32 1u256 #ii8 #ii16 #ii32 #ii64 #ii128 #iisize #uu8 #uu16 #uu32 #uu64 #uu128 #uusize };- let expected = "- 1i8 - 1i16 - 1i32 - 1i64 - 1i128 - 1isize 1u8 1u16 1u32 1u64 1u128 1usize";+ let expected = "1 1i32 1u256 - 1i8 - 1i16 - 1i32 - 1i64 - 1i128 - 1isize 1u8 1u16 1u32 1u64 1u128 1usize"; assert_eq!(expected, tokens.to_string()); }@@ -230,11 +231,43 @@ } #[test]+fn test_interpolated_literal() {+ macro_rules! m {+ ($literal:literal) => {+ quote!($literal)+ };+ }++ let tokens = m!(1);+ let expected = "1";+ assert_eq!(expected, tokens.to_string());++ let tokens = m!(-1);+ let expected = "- 1";+ assert_eq!(expected, tokens.to_string());++ let tokens = m!(true);+ let expected = "true";+ assert_eq!(expected, tokens.to_string());++ let tokens = m!(-true);+ let expected = "- true";+ assert_eq!(expected, tokens.to_string());+}++#[test] fn test_ident() { let foo = Ident::new("Foo", Span::call_site()); let bar = Ident::new(&format!("Bar{}", 7), Span::call_site()); let tokens = quote!(struct #foo; enum #bar {}); let expected = "struct Foo ; enum Bar7 { }";+ assert_eq!(expected, tokens.to_string());+}++#[test]+fn test_underscore() {+ let tokens = quote!(let _;);+ let expected = "let _ ;"; assert_eq!(expected, tokens.to_string()); }
After analyzing the provided code diff, I don't find any security vulnerabilities being fixed. The changes appear to be test case additions and modifications for functionality testing rather than security fixes. Here's the analysis following your requested format: 1. Vulnerability Existed: no No security vulnerability found File: third_party/rust/quote/tests/test.rs Lines: Various Old Code: Various test cases Fixed Code: Added/modified test cases The changes include: 1. Adding test cases for literal interpolation (1, -1, true, -true) 2. Adding a test case for underscore identifier 3. Modifying an existing test case to include more literal formats (1i32, 1u256) 4. No security-related changes were identified in the diff These changes appear to be normal test suite maintenance and expansion rather than security fixes. The modifications are focused on improving test coverage for various code generation scenarios using the quote macro.
If an attacker could control the contents of an iframe sandboxed with <code>allow-popups</code> but not <code>allow-scripts</code>, they were able to craft a link that, when clicked, would lead to JavaScript execution in violation of the sandbox. This vulnerability affects Firefox < 98, Firefox ESR < 91.7, and Thunderbird < 91.7.
--- /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_97_END/firefox-FIREFOX_RELEASE_97_END/docshell/base/CanonicalBrowsingContext.h+++ /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_98_END/firefox-FIREFOX_RELEASE_98_END/docshell/base/CanonicalBrowsingContext.h@@ -91,6 +91,8 @@ // BrowsingContextGroup. uint64_t GetCrossGroupOpenerId() const { return mCrossGroupOpenerId; } void SetCrossGroupOpenerId(uint64_t aOpenerId);+ void SetCrossGroupOpener(CanonicalBrowsingContext& aCrossGroupOpener,+ ErrorResult& aRv); void GetWindowGlobals(nsTArray<RefPtr<WindowGlobalParent>>& aWindows);@@ -140,7 +142,8 @@ void SessionHistoryCommit(uint64_t aLoadId, const nsID& aChangeID, uint32_t aLoadType, bool aPersist,- bool aCloneEntryChildren, bool aChannelExpired);+ bool aCloneEntryChildren, bool aChannelExpired,+ uint32_t aCacheKey); // Calls the session history listeners' OnHistoryReload, storing the result in // aCanReload. If aCanReload is set to true and we have an active or a loading@@ -287,7 +290,8 @@ void SetRestoreData(SessionStoreRestoreData* aData, ErrorResult& aError); void ClearRestoreState();- void RequestRestoreTabContent(WindowGlobalParent* aWindow);+ MOZ_CAN_RUN_SCRIPT_BOUNDARY void RequestRestoreTabContent(+ WindowGlobalParent* aWindow); already_AddRefed<Promise> GetRestorePromise(); nsresult WriteSessionStorageToSessionStore(@@ -460,9 +464,13 @@ void RemovePendingDiscard(); bool ShouldAddEntryForRefresh(const SessionHistoryEntry* aEntry) {+ return ShouldAddEntryForRefresh(aEntry->Info().GetURI(),+ aEntry->Info().GetPostData());+ }+ bool ShouldAddEntryForRefresh(nsIURI* aNewURI, bool aHasPostData) { nsCOMPtr<nsIURI> currentURI = GetCurrentURI();- return BrowsingContext::ShouldAddEntryForRefresh(currentURI,- aEntry->Info());+ return BrowsingContext::ShouldAddEntryForRefresh(currentURI, aNewURI,+ aHasPostData); } // XXX(farre): Store a ContentParent pointer here rather than mProcessId?
Here's the analysis of the provided code diff following the specified format: 1. Vulnerability Existed: not sure [Potential Security Improvement] [File: docshell/base/CanonicalBrowsingContext.h] [Lines: 290-291] [Old Code] void RequestRestoreTabContent(WindowGlobalParent* aWindow); [Fixed Code] MOZ_CAN_RUN_SCRIPT_BOUNDARY void RequestRestoreTabContent(WindowGlobalParent* aWindow); [Details] The addition of MOZ_CAN_RUN_SCRIPT_BOUNDARY suggests this function may run script content, which could have security implications if not properly handled. 2. Vulnerability Existed: not sure [Parameter Validation Improvement] [File: docshell/base/CanonicalBrowsingContext.h] [Lines: 91-92] [Old Code] void SetCrossGroupOpenerId(uint64_t aOpenerId); [Fixed Code] void SetCrossGroupOpener(CanonicalBrowsingContext& aCrossGroupOpener, ErrorResult& aRv); [Details] The new version adds error handling (ErrorResult) and takes a reference to the context rather than just an ID, potentially improving validation. 3. Vulnerability Existed: not sure [Session History Security Improvement] [File: docshell/base/CanonicalBrowsingContext.h] [Lines: 140-142] [Old Code] void SessionHistoryCommit(uint64_t aLoadId, const nsID& aChangeID, uint32_t aLoadType, bool aPersist, bool aCloneEntryChildren, bool aChannelExpired); [Fixed Code] void SessionHistoryCommit(uint64_t aLoadId, const nsID& aChangeID, uint32_t aLoadType, bool aPersist, bool aCloneEntryChildren, bool aChannelExpired, uint32_t aCacheKey); [Details] The addition of aCacheKey parameter suggests improved cache handling which could have security implications for session history management. 4. Vulnerability Existed: not sure [Refresh Entry Validation Improvement] [File: docshell/base/CanonicalBrowsingContext.h] [Lines: 460-464] [Old Code] bool ShouldAddEntryForRefresh(const SessionHistoryEntry* aEntry) { nsCOMPtr<nsIURI> currentURI = GetCurrentURI(); return BrowsingContext::ShouldAddEntryForRefresh(currentURI, aEntry->Info()); } [Fixed Code] bool ShouldAddEntryForRefresh(const SessionHistoryEntry* aEntry) { return ShouldAddEntryForRefresh(aEntry->Info().GetURI(), aEntry->Info().GetPostData()); } bool ShouldAddEntryForRefresh(nsIURI* aNewURI, bool aHasPostData) { nsCOMPtr<nsIURI> currentURI = GetCurrentURI(); return BrowsingContext::ShouldAddEntryForRefresh(currentURI, aNewURI, aHasPostData); } [Details] The change separates URI and POST data validation, which could improve security checks for refresh operations. Note: While these changes appear to be security-related improvements, I cannot definitively state they fix specific known vulnerabilities without more context about the threat model and previous issues. The changes suggest improved parameter validation, error handling, and security boundaries.
If an attacker could control the contents of an iframe sandboxed with <code>allow-popups</code> but not <code>allow-scripts</code>, they were able to craft a link that, when clicked, would lead to JavaScript execution in violation of the sandbox. This vulnerability affects Firefox < 98, Firefox ESR < 91.7, and Thunderbird < 91.7.
--- /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_97_END/firefox-FIREFOX_RELEASE_97_END/third_party/rust/wast/src/lexer.rs+++ /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_98_END/firefox-FIREFOX_RELEASE_98_END/third_party/rust/wast/src/lexer.rs@@ -28,7 +28,6 @@ use std::borrow::Cow; use std::char; use std::fmt;-use std::iter; use std::str; /// A structure used to lex the s-expression syntax of WAT files.@@ -38,8 +37,9 @@ /// returned for any non-lexable text. #[derive(Clone)] pub struct Lexer<'a> {- it: iter::Peekable<str::CharIndices<'a>>,+ remaining: &'a str, input: &'a str,+ allow_confusing_unicode: bool, } /// A fragment of source lex'd from an input string.@@ -139,6 +139,13 @@ /// A lone underscore was found when parsing a number, since underscores /// should always be preceded and succeeded with a digit of some form. LoneUnderscore,++ /// A "confusing" unicode character is present in a comment or a string+ /// literal, such as a character that changes the direction text is+ /// typically displayed in editors. This could cause the human-read+ /// version to behave differently than the compiler-visible version, so+ /// these are simply rejected for now.+ ConfusingUnicode(char), #[doc(hidden)] __Nonexhaustive,@@ -219,18 +226,67 @@ }, }+// https://webassembly.github.io/spec/core/text/values.html#text-idchar+macro_rules! idchars {+ () => {+ b'0'..=b'9'+ | b'A'..=b'Z'+ | b'a'..=b'z'+ | b'!'+ | b'#'+ | b'$'+ | b'%'+ | b'&'+ | b'\''+ | b'*'+ | b'+'+ | b'-'+ | b'.'+ | b'/'+ | b':'+ | b'<'+ | b'='+ | b'>'+ | b'?'+ | b'@'+ | b'\\'+ | b'^'+ | b'_'+ | b'`'+ | b'|'+ | b'~'+ }+}+ impl<'a> Lexer<'a> { /// Creates a new lexer which will lex the `input` source string. pub fn new(input: &str) -> Lexer<'_> { Lexer {- it: input.char_indices().peekable(),+ remaining: input, input,+ allow_confusing_unicode: false, } } /// Returns the original source input that we're lexing. pub fn input(&self) -> &'a str { self.input+ }++ /// Configures whether "confusing" unicode characters are allowed while+ /// lexing.+ ///+ /// If allowed then no error will happen if these characters are found, but+ /// otherwise if disallowed a lex error will be produced when these+ /// characters are found. Confusing characters are denied by default.+ ///+ /// For now "confusing characters" are primarily related to the "trojan+ /// source" problem where it refers to characters which cause humans to read+ /// text differently than this lexer, such as characters that alter the+ /// left-to-right display of the source code.+ pub fn allow_confusing_unicode(&mut self, allow: bool) -> &mut Self {+ self.allow_confusing_unicode = allow;+ self } /// Lexes the next token in the input.@@ -241,68 +297,189 @@ /// /// Returns an error if the input is malformed. pub fn parse(&mut self) -> Result<Option<Token<'a>>, Error> {- if let Some(ws) = self.ws() {- return Ok(Some(Token::Whitespace(ws)));- }- if let Some(comment) = self.comment()? {- return Ok(Some(comment));- }- if let Some(token) = self.token()? {- return Ok(Some(token));- }- match self.it.next() {- Some((i, ch)) => Err(self.error(i, LexError::Unexpected(ch))),- None => Ok(None),- }- }-- fn token(&mut self) -> Result<Option<Token<'a>>, Error> {- // First two are easy, they're just parens- if let Some(pos) = self.eat_char('(') {- return Ok(Some(Token::LParen(&self.input[pos..pos + 1])));- }- if let Some(pos) = self.eat_char(')') {- return Ok(Some(Token::RParen(&self.input[pos..pos + 1])));- }-- // Strings are also pretty easy, leading `"` is a dead giveaway- if let Some(pos) = self.eat_char('"') {- let val = self.string()?;- let src = &self.input[pos..self.cur()];- return Ok(Some(Token::String(WasmString(Box::new(WasmStringInner {- val,- src,- })))));- }-- let (start, prefix) = match self.it.peek().cloned() {- Some((i, ch)) if is_idchar(ch) => (i, ch),- Some((i, ch)) if is_reserved_extra(ch) => {- self.it.next();- return Ok(Some(Token::Reserved(&self.input[i..self.cur()])));- }- Some((i, ch)) => return Err(self.error(i, LexError::Unexpected(ch))),+ let pos = self.cur();+ // This `match` generally parses the grammar specified at+ //+ // https://webassembly.github.io/spec/core/text/lexical.html#text-token+ let byte = match self.remaining.as_bytes().get(0) {+ Some(b) => b, None => return Ok(None), };- while let Some((_, ch)) = self.it.peek().cloned() {- if is_idchar(ch) {- self.it.next();- } else {- break;- }- }-- let reserved = &self.input[start..self.cur()];- if let Some(number) = self.number(reserved) {- Ok(Some(number))- } else if prefix == '$' && reserved.len() > 1 {- Ok(Some(Token::Id(reserved)))- } else if 'a' <= prefix && prefix <= 'z' {- Ok(Some(Token::Keyword(reserved)))- } else {- Ok(Some(Token::Reserved(reserved)))- }+ match byte {+ // Open-parens check the next character to see if this is the start+ // of a block comment, otherwise it's just a bland left-paren+ // token.+ b'(' => match self.remaining.as_bytes().get(1) {+ Some(b';') => {+ let mut level = 1;+ // Note that we're doing a byte-level search here for the+ // close-delimiter of `;)`. The actual source text is utf-8+ // encode in `self.remaining` but due to how utf-8 works we+ // can safely search for an ASCII byte since it'll never+ // otherwise appear in the middle of a codepoint and if we+ // find it then it's guaranteed to be the right byte.+ //+ // Mainly we're avoiding the overhead of decoding utf-8+ // characters into a Rust `char` since it's otherwise+ // unnecessary work.+ let mut iter = self.remaining.as_bytes()[2..].iter();+ while let Some(ch) = iter.next() {+ match ch {+ b'(' => {+ if let Some(b';') = iter.as_slice().get(0) {+ level += 1;+ iter.next();+ }+ }+ b';' => {+ if let Some(b')') = iter.as_slice().get(0) {+ level -= 1;+ iter.next();+ if level == 0 {+ let len = self.remaining.len() - iter.as_slice().len();+ let (comment, remaining) = self.remaining.split_at(len);+ self.remaining = remaining;+ self.check_confusing_comment(comment)?;+ return Ok(Some(Token::BlockComment(comment)));+ }+ }+ }+ _ => {}+ }+ }+ Err(self.error(pos, LexError::DanglingBlockComment))+ }+ _ => Ok(Some(Token::LParen(self.split_first_byte()))),+ },++ b')' => Ok(Some(Token::RParen(self.split_first_byte()))),++ b'"' => {+ let val = self.string()?;+ let src = &self.input[pos..self.cur()];+ return Ok(Some(Token::String(WasmString(Box::new(WasmStringInner {+ val,+ src,+ })))));+ }++ // https://webassembly.github.io/spec/core/text/lexical.html#white-space+ b' ' | b'\n' | b'\r' | b'\t' => Ok(Some(Token::Whitespace(self.split_ws()))),++ c @ idchars!() => {+ let reserved = self.split_while(|b| match b {+ idchars!() => true,+ _ => false,+ });++ // https://webassembly.github.io/spec/core/text/values.html#integers+ if let Some(number) = self.number(reserved) {+ Ok(Some(number))+ // https://webassembly.github.io/spec/core/text/values.html#text-id+ } else if *c == b'$' && reserved.len() > 1 {+ Ok(Some(Token::Id(reserved)))+ // https://webassembly.github.io/spec/core/text/lexical.html#text-keyword+ } else if b'a' <= *c && *c <= b'z' {+ Ok(Some(Token::Keyword(reserved)))+ } else {+ Ok(Some(Token::Reserved(reserved)))+ }+ }++ // This could be a line comment, otherwise `;` is a reserved token.+ // The second byte is checked to see if it's a `;;` line comment+ b';' => match self.remaining.as_bytes().get(1) {+ Some(b';') => {+ let comment = self.split_until(b'\n');+ self.check_confusing_comment(comment)?;+ Ok(Some(Token::LineComment(comment)))+ }+ _ => Ok(Some(Token::Reserved(self.split_first_byte()))),+ },++ // Other known reserved tokens other than `;`+ b',' | b'[' | b']' | b'{' | b'}' => Ok(Some(Token::Reserved(self.split_first_byte()))),++ _ => {+ let ch = self.remaining.chars().next().unwrap();+ Err(self.error(pos, LexError::Unexpected(ch)))+ }+ }+ }++ fn split_first_byte(&mut self) -> &'a str {+ let (token, remaining) = self.remaining.split_at(1);+ self.remaining = remaining;+ token+ }++ fn split_until(&mut self, byte: u8) -> &'a str {+ let pos = memchr::memchr(byte, self.remaining.as_bytes()).unwrap_or(self.remaining.len());+ let (ret, remaining) = self.remaining.split_at(pos);+ self.remaining = remaining;+ ret+ }++ fn split_ws(&mut self) -> &'a str {+ // This table is a byte lookup table to determine whether a byte is a+ // whitespace byte. There are only 4 whitespace bytes for the `*.wat`+ // format right now which are ' ', '\t', '\r', and '\n'. These 4 bytes+ // have a '1' in the table below.+ //+ // Due to how utf-8 works (our input is guaranteed to be utf-8) it is+ // known that if these bytes are found they're guaranteed to be the+ // whitespace byte, so they can be safely skipped and we don't have to+ // do full utf-8 decoding. This means that the goal of this function is+ // to find the first non-whitespace byte in `self.remaining`.+ //+ // For now this lookup table seems to be the fastest, but projects like+ // https://github.com/lemire/despacer show other simd algorithms which+ // can possibly accelerate this even more. Note that `*.wat` files often+ // have a lot of whitespace so this function is typically quite hot when+ // parsing inputs.+ #[rustfmt::skip]+ const WS: [u8; 256] = [+ // \t \n \r+ /* 0x00 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0,+ /* 0x10 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,+ // ' '+ /* 0x20 */ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,+ /* 0x30 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,+ /* 0x40 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,+ /* 0x50 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,+ /* 0x60 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,+ /* 0x70 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,+ /* 0x80 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,+ /* 0x90 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,+ /* 0xa0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,+ /* 0xb0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,+ /* 0xc0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,+ /* 0xd0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,+ /* 0xe0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,+ /* 0xf0 */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,+ ];+ let pos = self+ .remaining+ .as_bytes()+ .iter()+ .position(|b| WS[*b as usize] != 1)+ .unwrap_or(self.remaining.len());+ let (ret, remaining) = self.remaining.split_at(pos);+ self.remaining = remaining;+ ret+ }++ fn split_while(&mut self, f: impl Fn(u8) -> bool) -> &'a str {+ let pos = self+ .remaining+ .as_bytes()+ .iter()+ .position(|b| !f(*b))+ .unwrap_or(self.remaining.len());+ let (ret, remaining) = self.remaining.split_at(pos);+ self.remaining = remaining;+ ret } fn number(&self, src: &'a str) -> Option<Token<'a>> {@@ -481,130 +658,132 @@ } }- /// Attempts to consume whitespace from the input stream, returning `None`- /// if there's no whitespace to consume- fn ws(&mut self) -> Option<&'a str> {- let start = self.cur();- loop {- match self.it.peek() {- Some((_, ' ')) | Some((_, '\n')) | Some((_, '\r')) | Some((_, '\t')) => {- drop(self.it.next())+ /// Verifies that `comment`, which is about to be returned, has a "confusing+ /// unicode character" in it and should instead be transformed into an+ /// error.+ fn check_confusing_comment(&self, comment: &str) -> Result<(), Error> {+ if self.allow_confusing_unicode {+ return Ok(());+ }++ // In an effort to avoid utf-8 decoding the entire `comment` the search+ // here is a bit more optimized. This checks for the `0xe2` byte because+ // in the utf-8 encoding that's the leading encoding byte for all+ // "confusing characters". Each instance of 0xe2 is checked to see if it+ // starts a confusing character, and if so that's returned.+ //+ // Also note that 0xe2 will never be found in the middle of a codepoint,+ // it's always the start of a codepoint. This means that if our special+ // characters show up they're guaranteed to start with 0xe2 bytes.+ let bytes = comment.as_bytes();+ for pos in memchr::Memchr::new(0xe2, bytes) {+ if let Some(c) = comment[pos..].chars().next() {+ if is_confusing_unicode(c) {+ // Note that `self.cur()` accounts for already having+ // parsed `comment`, so we move backwards to where+ // `comment` started and then add the index within+ // `comment`.+ let pos = self.cur() - comment.len() + pos;+ return Err(self.error(pos, LexError::ConfusingUnicode(c))); }- _ => break,- }- }- let end = self.cur();- if start != end {- Some(&self.input[start..end])- } else {- None- }- }-- /// Attempts to read a comment from the input stream- fn comment(&mut self) -> Result<Option<Token<'a>>, Error> {- if let Some(start) = self.eat_str(";;") {- loop {- match self.it.peek() {- None | Some((_, '\n')) => break,- _ => drop(self.it.next()),- }- }- let end = self.cur();- return Ok(Some(Token::LineComment(&self.input[start..end])));- }- if let Some(start) = self.eat_str("(;") {- let mut level = 1;- while let Some((_, ch)) = self.it.next() {- if ch == '(' && self.eat_char(';').is_some() {- level += 1;- }- if ch == ';' && self.eat_char(')').is_some() {- level -= 1;- if level == 0 {- let end = self.cur();- return Ok(Some(Token::BlockComment(&self.input[start..end])));- }- }- }-- return Err(self.error(start, LexError::DanglingBlockComment));- }- Ok(None)+ }+ }++ Ok(()) } /// Reads everything for a literal string except the leading `"`. Returns /// the string value that has been read.+ ///+ /// https://webassembly.github.io/spec/core/text/values.html#text-string fn string(&mut self) -> Result<Cow<'a, [u8]>, Error> {+ let mut it = self.remaining[1..].chars();+ let result = Lexer::parse_str(&mut it, self.allow_confusing_unicode);+ let end = self.input.len() - it.as_str().len();+ self.remaining = &self.input[end..];+ result.map_err(|e| {+ let err_pos = match &e {+ LexError::UnexpectedEof => self.input.len(),+ _ => self.input[..end].char_indices().next_back().unwrap().0,+ };+ self.error(err_pos, e)+ })+ }++ fn parse_str(+ it: &mut str::Chars<'a>,+ allow_confusing_unicode: bool,+ ) -> Result<Cow<'a, [u8]>, LexError> { enum State {- Start(usize),+ Start, String(Vec<u8>), }- let mut state = State::Start(self.cur());+ let orig = it.as_str();+ let mut state = State::Start; loop {- match self.it.next() {- Some((i, '\\')) => {+ match it.next().ok_or(LexError::UnexpectedEof)? {+ '"' => break,+ '\\' => { match state { State::String(_) => {}- State::Start(start) => {- state = State::String(self.input[start..i].as_bytes().to_vec());+ State::Start => {+ let pos = orig.len() - it.as_str().len() - 1;+ state = State::String(orig[..pos].as_bytes().to_vec()); } } let buf = match &mut state { State::String(b) => b,- State::Start(_) => unreachable!(),+ State::Start => unreachable!(), };- match self.it.next() {- Some((_, '"')) => buf.push(b'"'),- Some((_, '\'')) => buf.push(b'\''),- Some((_, 't')) => buf.push(b'\t'),- Some((_, 'n')) => buf.push(b'\n'),- Some((_, 'r')) => buf.push(b'\r'),- Some((_, '\\')) => buf.push(b'\\'),- Some((i, 'u')) => {- self.must_eat_char('{')?;- let n = self.hexnum()?;+ match it.next().ok_or(LexError::UnexpectedEof)? {+ '"' => buf.push(b'"'),+ '\'' => buf.push(b'\''),+ 't' => buf.push(b'\t'),+ 'n' => buf.push(b'\n'),+ 'r' => buf.push(b'\r'),+ '\\' => buf.push(b'\\'),+ 'u' => {+ Lexer::must_eat_char(it, '{')?;+ let n = Lexer::hexnum(it)?; let c = char::from_u32(n)- .ok_or_else(|| self.error(i, LexError::InvalidUnicodeValue(n)))?;+ .ok_or_else(|| LexError::InvalidUnicodeValue(n))?; buf.extend(c.encode_utf8(&mut [0; 4]).as_bytes());- self.must_eat_char('}')?;+ Lexer::must_eat_char(it, '}')?; }- Some((_, c1)) if c1.is_ascii_hexdigit() => {- let (_, c2) = self.hexdigit()?;+ c1 if c1.is_ascii_hexdigit() => {+ let c2 = Lexer::hexdigit(it)?; buf.push(to_hex(c1) * 16 + c2); }- Some((i, c)) => return Err(self.error(i, LexError::InvalidStringEscape(c))),- None => return Err(self.error(self.input.len(), LexError::UnexpectedEof)),+ c => return Err(LexError::InvalidStringEscape(c)), } }- Some((_, '"')) => break,- Some((i, c)) => {- if (c as u32) < 0x20 || c as u32 == 0x7f {- return Err(self.error(i, LexError::InvalidStringElement(c)));+ c if (c as u32) < 0x20 || c as u32 == 0x7f => {+ return Err(LexError::InvalidStringElement(c))+ }+ c if !allow_confusing_unicode && is_confusing_unicode(c) => {+ return Err(LexError::ConfusingUnicode(c))+ }+ c => match &mut state {+ State::Start => {}+ State::String(v) => {+ v.extend(c.encode_utf8(&mut [0; 4]).as_bytes()); }- match &mut state {- State::Start(_) => {}- State::String(v) => {- v.extend(c.encode_utf8(&mut [0; 4]).as_bytes());- }- }- }- None => return Err(self.error(self.input.len(), LexError::UnexpectedEof)),+ }, } } match state {- State::Start(pos) => Ok(self.input[pos..self.cur() - 1].as_bytes().into()),+ State::Start => Ok(orig[..orig.len() - it.as_str().len() - 1].as_bytes().into()), State::String(s) => Ok(s.into()), } }- fn hexnum(&mut self) -> Result<u32, Error> {- let (_, n) = self.hexdigit()?;+ fn hexnum(it: &mut str::Chars<'_>) -> Result<u32, LexError> {+ let n = Lexer::hexdigit(it)?; let mut last_underscore = false; let mut n = n as u32;- while let Some((i, c)) = self.it.peek().cloned() {+ while let Some(c) = it.clone().next() { if c == '_' {- self.it.next();+ it.next(); last_underscore = true; continue; }@@ -612,15 +791,14 @@ break; } last_underscore = false;- self.it.next();+ it.next(); n = n .checked_mul(16) .and_then(|n| n.checked_add(to_hex(c) as u32))- .ok_or_else(|| self.error(i, LexError::NumberTooBig))?;+ .ok_or(LexError::NumberTooBig)?; } if last_underscore {- let cur = self.cur();- return Err(self.error(cur - 1, LexError::LoneUnderscore));+ return Err(LexError::LoneUnderscore); } Ok(n) }@@ -628,65 +806,34 @@ /// Reads a hexidecimal digit from the input stream, returning where it's /// defined and the hex value. Returns an error on EOF or an invalid hex /// digit.- fn hexdigit(&mut self) -> Result<(usize, u8), Error> {- let (i, ch) = self.must_char()?;+ fn hexdigit(it: &mut str::Chars<'_>) -> Result<u8, LexError> {+ let ch = Lexer::must_char(it)?; if ch.is_ascii_hexdigit() {- Ok((i, to_hex(ch)))+ Ok(to_hex(ch)) } else {- Err(self.error(i, LexError::InvalidHexDigit(ch)))- }- }-- /// Returns where the match started, if any- fn eat_str(&mut self, s: &str) -> Option<usize> {- if !self.cur_str().starts_with(s) {- return None;- }- let ret = self.cur();- for _ in s.chars() {- self.it.next();- }- Some(ret)- }-- /// Returns where the match happened, if any- fn eat_char(&mut self, needle: char) -> Option<usize> {- match self.it.peek() {- Some((i, c)) if *c == needle => {- let ret = *i;- self.it.next();- Some(ret)- }- _ => None,+ Err(LexError::InvalidHexDigit(ch)) } } /// Reads the next character from the input string and where it's located, /// returning an error if the input stream is empty.- fn must_char(&mut self) -> Result<(usize, char), Error> {- self.it- .next()- .ok_or_else(|| self.error(self.input.len(), LexError::UnexpectedEof))+ fn must_char(it: &mut str::Chars<'_>) -> Result<char, LexError> {+ it.next().ok_or(LexError::UnexpectedEof) } /// Expects that a specific character must be read next- fn must_eat_char(&mut self, wanted: char) -> Result<usize, Error> {- let (pos, found) = self.must_char()?;+ fn must_eat_char(it: &mut str::Chars<'_>, wanted: char) -> Result<(), LexError> {+ let found = Lexer::must_char(it)?; if wanted == found {- Ok(pos)+ Ok(()) } else {- Err(self.error(pos, LexError::Expected { wanted, found }))+ Err(LexError::Expected { wanted, found }) } } /// Returns the current position of our iterator through the input string- fn cur(&mut self) -> usize {- self.it.peek().map(|p| p.0).unwrap_or(self.input.len())- }-- /// Returns the remaining string that we have left to parse- fn cur_str(&mut self) -> &'a str {- &self.input[self.cur()..]+ fn cur(&self) -> usize {+ self.input.len() - self.remaining.len() } /// Creates an error at `pos` with the specified `kind`@@ -773,45 +920,6 @@ } }-fn is_idchar(c: char) -> bool {- match c {- '0'..='9'- | 'a'..='z'- | 'A'..='Z'- | '!'- | '#'- | '$'- | '%'- | '&'- | '\''- | '*'- | '+'- | '-'- | '.'- | '/'- | ':'- | '<'- | '='- | '>'- | '?'- | '@'- | '\\'- | '^'- | '_'- | '`'- | '|'- | '~' => true,- _ => false,- }-}--fn is_reserved_extra(c: char) -> bool {- match c {- ',' | ';' | '[' | ']' | '{' | '}' => true,- _ => false,- }-}- impl fmt::Display for LexError { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { use LexError::*;@@ -834,6 +942,7 @@ NumberTooBig => f.write_str("number is too big to parse")?, InvalidUnicodeValue(c) => write!(f, "invalid unicode scalar value 0x{:x}", c)?, LoneUnderscore => write!(f, "bare underscore in numeric literal")?,+ ConfusingUnicode(c) => write!(f, "likely-confusing unicode character found {:?}", c)?, __Nonexhaustive => unreachable!(), } Ok(())@@ -842,14 +951,30 @@ fn escape_char(c: char) -> String { match c {- '\t' => String::from("\\\t"),- '\r' => String::from("\\\r"),- '\n' => String::from("\\\n"),+ '\t' => String::from("\\t"),+ '\r' => String::from("\\r"),+ '\n' => String::from("\\n"), '\\' => String::from("\\\\"), '\'' => String::from("\\\'"), '\"' => String::from("\""), '\x20'..='\x7e' => String::from(c), _ => c.escape_unicode().to_string(),+ }+}++/// This is an attempt to protect agains the "trojan source" [1] problem where+/// unicode characters can cause editors to render source code differently+/// for humans than the compiler itself sees.+///+/// To mitigate this issue, and because it's relatively rare in practice,+/// this simply rejects characters of that form.+///+/// [1]: https://www.trojansource.codes/+fn is_confusing_unicode(ch: char) -> bool {+ match ch {+ '\u{202a}' | '\u{202b}' | '\u{202d}' | '\u{202e}' | '\u{2066}' | '\u{2067}'+ | '\u{2068}' | '\u{206c}' | '\u{2069}' => true,+ _ => false, } }
I'll analyze the code diff for security fixes following the specified format. 1. Vulnerability Existed: yes Trojan Source Attack Protection [third_party/rust/wast/src/lexer.rs] [Multiple locations] Old Code: No protection against confusing unicode characters in comments or strings Fixed Code: Added checks for confusing unicode characters with: - New LexError::ConfusingUnicode variant - is_confusing_unicode() detection function - check_confusing_comment() method - Updated string() method to check for confusing chars - New allow_confusing_unicode configuration option 2. Vulnerability Existed: yes Insecure String Parsing [third_party/rust/wast/src/lexer.rs] [Multiple locations] Old Code: String parsing was more vulnerable to malformed input and didn't properly handle all error cases Fixed Code: Rewrote string parsing to be more robust with: - New parse_str() method - Better error handling - More secure state management - Proper handling of escape sequences 3. Vulnerability Existed: not sure Potential Integer Overflow [third_party/rust/wast/src/lexer.rs] [hexnum() function] Old Code: Integer parsing might have been vulnerable to overflow Fixed Code: Added checked arithmetic operations in hexnum(): n.checked_mul(16) .and_then(|n| n.checked_add(to_hex(c) as u32)) The main security fix appears to be the addition of protection against Trojan Source attacks by detecting and rejecting confusing Unicode characters that could be used to hide malicious code in comments or strings. The string parsing was also significantly rewritten to be more secure, though the exact vulnerabilities being fixed aren't specified in the diff. The changes include: 1. New error type for confusing Unicode characters 2. Detection function for problematic Unicode chars 3. Checks in both comment and string parsing 4. Configuration option to control this behavior 5. More robust string parsing overall 6. Better integer overflow protection in hex number parsing
If an attacker could control the contents of an iframe sandboxed with <code>allow-popups</code> but not <code>allow-scripts</code>, they were able to craft a link that, when clicked, would lead to JavaScript execution in violation of the sandbox. This vulnerability affects Firefox < 98, Firefox ESR < 91.7, and Thunderbird < 91.7.
--- /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_97_END/firefox-FIREFOX_RELEASE_97_END/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillRect.html+++ /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_98_END/firefox-FIREFOX_RELEASE_98_END/testing/web-platform/tests/html/canvas/offscreen/fill-and-stroke-styles/2d.gradient.interpolate.zerosize.fillRect.html@@ -17,8 +17,8 @@ }); t.step(function() {-var offscreenCanvas = new OffscreenCanvas(100, 50);-var ctx = offscreenCanvas.getContext('2d');+var canvas = new OffscreenCanvas(100, 50);+var ctx = canvas.getContext('2d'); ctx.fillStyle = '#0f0'; ctx.fillRect(0, 0, 100, 50);@@ -27,7 +27,7 @@ g.addColorStop(1, '#f00'); ctx.fillStyle = g; ctx.fillRect(0, 0, 100, 50);-_assertPixel(offscreenCanvas, 40,20, 0,255,0,255, "40,20", "0,255,0,255");+_assertPixel(canvas, 40,20, 0,255,0,255, "40,20", "0,255,0,255"); t.done(); });
Based on the provided diff, I'll analyze it for security vulnerabilities: 1. Vulnerability Existed: no No specific vulnerability found [File] [Lines 17-18,27] [Old Code] var offscreenCanvas = new OffscreenCanvas(100, 50); var ctx = offscreenCanvas.getContext('2d'); _assertPixel(offscreenCanvas, 40,20, 0,255,0,255, "40,20", "0,255,0,255"); [Fixed Code] var canvas = new OffscreenCanvas(100, 50); var ctx = canvas.getContext('2d'); _assertPixel(canvas, 40,20, 0,255,0,255, "40,20", "0,255,0,255"); Additional Details: The changes appear to be purely variable renaming (from `offscreenCanvas` to `canvas`) with no security implications. The functionality remains identical, just with a different variable name. There are no security vulnerabilities being fixed in this diff.
If an attacker could control the contents of an iframe sandboxed with <code>allow-popups</code> but not <code>allow-scripts</code>, they were able to craft a link that, when clicked, would lead to JavaScript execution in violation of the sandbox. This vulnerability affects Firefox < 98, Firefox ESR < 91.7, and Thunderbird < 91.7.
--- /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_97_END/firefox-FIREFOX_RELEASE_97_END/xpcom/threads/nsThreadPool.cpp+++ /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_98_END/firefox-FIREFOX_RELEASE_98_END/xpcom/threads/nsThreadPool.cpp@@ -11,6 +11,7 @@ #include "nsThreadManager.h" #include "nsThread.h" #include "nsMemory.h"+#include "nsThreadUtils.h" #include "prinrval.h" #include "mozilla/Logging.h" #include "mozilla/ProfilerLabels.h"@@ -381,7 +382,10 @@ } NS_IMETHODIMP-nsThreadPool::Shutdown() {+nsThreadPool::Shutdown() { return ShutdownWithTimeout(-1); }++NS_IMETHODIMP+nsThreadPool::ShutdownWithTimeout(int32_t aTimeoutMs) { nsCOMArray<nsIThread> threads; nsCOMPtr<nsIThreadPoolListener> listener; {@@ -401,109 +405,46 @@ mListener.swap(listener); }- // It's important that we shutdown the threads while outside the event queue- // monitor. Otherwise, we could end up dead-locking.-+ nsTArray<nsCOMPtr<nsIThreadShutdown>> contexts; for (int32_t i = 0; i < threads.Count(); ++i) {- threads[i]->Shutdown();- }-- return NS_OK;-}--template <typename Pred>-static void SpinMTEventLoopUntil(Pred&& aPredicate, nsIThread* aThread,- TimeDuration aTimeout) {- MOZ_ASSERT(NS_IsMainThread(), "Must be run on the main thread");-- // From a latency perspective, spinning the event loop is like leaving script- // and returning to the event loop. Tell the watchdog we stopped running- // script (until we return).- mozilla::Maybe<xpc::AutoScriptActivity> asa;- asa.emplace(false);-- TimeStamp deadline = TimeStamp::Now() + aTimeout;- while (!aPredicate() && TimeStamp::Now() < deadline) {- if (!NS_ProcessNextEvent(aThread, false)) {- PR_Sleep(PR_MillisecondsToInterval(1));- }- }-}--NS_IMETHODIMP-nsThreadPool::ShutdownWithTimeout(int32_t aTimeoutMs) {- if (!NS_IsMainThread()) {- return NS_ERROR_NOT_AVAILABLE;- }-- nsCOMArray<nsIThread> threads;- nsCOMPtr<nsIThreadPoolListener> listener;- {- MutexAutoLock lock(mMutex);- if (mShutdown) {- return NS_ERROR_ILLEGAL_DURING_SHUTDOWN;- }- mShutdown = true;- mEventsAvailable.NotifyAll();-- threads.AppendObjects(mThreads);- mThreads.Clear();-- // Swap in a null listener so that we release the listener at the end of- // this method. The listener will be kept alive as long as the other threads- // that were created when it was set.- mListener.swap(listener);- }-- // IMPORTANT! Never dereference these pointers, as the objects may go away at- // any time. We just use the pointers values for comparison, to check if the- // thread has been shut down or not.- nsTArray<nsThreadShutdownContext*> contexts;-- // It's important that we shutdown the threads while outside the event queue- // monitor. Otherwise, we could end up dead-locking.- for (int32_t i = 0; i < threads.Count(); ++i) {- // Shutdown async- nsThreadShutdownContext* maybeContext =- static_cast<nsThread*>(threads[i])->ShutdownInternal(false);- contexts.AppendElement(maybeContext);- }-- NotNull<nsThread*> currentThread =- WrapNotNull(nsThreadManager::get().GetCurrentThread());-- // We spin the event loop until all of the threads in the thread pool- // have shut down, or the timeout expires.- SpinMTEventLoopUntil(- [&]() {- for (nsIThread* thread : threads) {- if (static_cast<nsThread*>(thread)->mThread) {- return false;+ nsCOMPtr<nsIThreadShutdown> context;+ if (NS_SUCCEEDED(threads[i]->BeginShutdown(getter_AddRefs(context)))) {+ contexts.AppendElement(std::move(context));+ }+ }++ // Start a timer which will stop waiting & leak the thread, forcing+ // onCompletion to be called when it expires.+ nsCOMPtr<nsITimer> timer;+ if (aTimeoutMs >= 0) {+ NS_NewTimerWithCallback(+ getter_AddRefs(timer),+ [&](nsITimer*) {+ for (auto& context : contexts) {+ context->StopWaitingAndLeakThread(); }- }- return true;- },- currentThread, TimeDuration::FromMilliseconds(aTimeoutMs));-- // For any threads that have not shutdown yet, we need to remove them from- // mRequestedShutdownContexts so the thread manager does not wait for them- // at shutdown.- static const nsThread::ShutdownContextsComp comparator{};- for (int32_t i = 0; i < threads.Count(); ++i) {- nsThread* thread = static_cast<nsThread*>(threads[i]);- // If mThread is not null on the thread it means that it hasn't shutdown- // context[i] corresponds to thread[i]- if (thread->mThread && contexts[i]) {- auto index = currentThread->mRequestedShutdownContexts.IndexOf(- contexts[i], 0, comparator);- if (index != nsThread::ShutdownContexts::NoIndex) {- // We must leak the shutdown context just in case the leaked thread- // does get unstuck and completes before the main thread is done.- Unused << currentThread->mRequestedShutdownContexts[index].release();- currentThread->mRequestedShutdownContexts.RemoveElementAt(index);- }- }- }+ },+ aTimeoutMs, nsITimer::TYPE_ONE_SHOT,+ "nsThreadPool::ShutdownWithTimeout");+ }++ // Start a counter and register a callback to decrement outstandingThreads+ // when the threads finish exiting. We'll spin an event loop until+ // outstandingThreads reaches 0.+ uint32_t outstandingThreads = contexts.Length();+ RefPtr onCompletion = NS_NewCancelableRunnableFunction(+ "nsThreadPool thread completion", [&] { --outstandingThreads; });+ for (auto& context : contexts) {+ context->OnCompletion(onCompletion);+ }++ mozilla::SpinEventLoopUntil("nsThreadPool::ShutdownWithTimeout"_ns,+ [&] { return outstandingThreads == 0; });++ if (timer) {+ timer->Cancel();+ }+ onCompletion->Cancel(); return NS_OK; }
Here's the analysis of the provided code diff for security fixes: 1. Vulnerability Existed: yes Race Condition in Thread Shutdown [xpcom/threads/nsThreadPool.cpp] [Lines 381-405, 405-446] Old Code: ```cpp NS_IMETHODIMP nsThreadPool::Shutdown() { nsCOMArray<nsIThread> threads; nsCOMPtr<nsIThreadPoolListener> listener; { MutexAutoLock lock(mMutex); if (mShutdown) { return NS_ERROR_ILLEGAL_DURING_SHUTDOWN; } mShutdown = true; mEventsAvailable.NotifyAll(); threads.AppendObjects(mThreads); mThreads.Clear(); // Swap in a null listener so that we release the listener at the end of // this method. The listener will be kept alive as long as the other threads // that were created when it was set. mListener.swap(listener); } // It's important that we shutdown the threads while outside the event queue // monitor. Otherwise, we could end up dead-locking. for (int32_t i = 0; i < threads.Count(); ++i) { threads[i]->Shutdown(); } ``` Fixed Code: ```cpp NS_IMETHODIMP nsThreadPool::Shutdown() { return ShutdownWithTimeout(-1); } NS_IMETHODIMP nsThreadPool::ShutdownWithTimeout(int32_t aTimeoutMs) { nsCOMArray<nsIThread> threads; nsCOMPtr<nsIThreadPoolListener> listener; { MutexAutoLock lock(mMutex); if (mShutdown) { return NS_ERROR_ILLEGAL_DURING_SHUTDOWN; } mShutdown = true; mEventsAvailable.NotifyAll(); threads.AppendObjects(mThreads); mThreads.Clear(); // Swap in a null listener so that we release the listener at the end of // this method. The listener will be kept alive as long as the other threads // that were created when it was set. mListener.swap(listener); } ``` 2. Vulnerability Existed: yes Potential Deadlock in Thread Shutdown [xpcom/threads/nsThreadPool.cpp] [Lines 405-446] Old Code: ```cpp // IMPORTANT! Never dereference these pointers, as the objects may go away at // any time. We just use the pointers values for comparison, to check if the // thread has been shut down or not. nsTArray<nsThreadShutdownContext*> contexts; // It's important that we shutdown the threads while outside the event queue // monitor. Otherwise, we could end up dead-locking. for (int32_t i = 0; i < threads.Count(); ++i) { // Shutdown async nsThreadShutdownContext* maybeContext = static_cast<nsThread*>(threads[i])->ShutdownInternal(false); contexts.AppendElement(maybeContext); } ``` Fixed Code: ```cpp nsTArray<nsCOMPtr<nsIThreadShutdown>> contexts; for (int32_t i = 0; i < threads.Count(); ++i) { nsCOMPtr<nsIThreadShutdown> context; if (NS_SUCCEEDED(threads[i]->BeginShutdown(getter_AddRefs(context)))) { contexts.AppendElement(std::move(context)); } } ``` The changes address two main issues: 1. The original implementation had potential race conditions during thread shutdown, which could lead to undefined behavior or crashes. The new implementation uses a more robust shutdown mechanism with proper reference counting. 2. The old code could potentially deadlock during shutdown due to unsafe pointer handling and manual context management. The new version uses safer nsCOMPtr smart pointers and a more structured shutdown procedure with proper timeout handling. The fixes introduce a new `ShutdownWithTimeout` method that provides better control over thread shutdown behavior and prevents potential deadlocks and race conditions.
If an attacker could control the contents of an iframe sandboxed with <code>allow-popups</code> but not <code>allow-scripts</code>, they were able to craft a link that, when clicked, would lead to JavaScript execution in violation of the sandbox. This vulnerability affects Firefox < 98, Firefox ESR < 91.7, and Thunderbird < 91.7.
--- /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_97_END/firefox-FIREFOX_RELEASE_97_END/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.line.html+++ /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_98_END/firefox-FIREFOX_RELEASE_98_END/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.line.html@@ -17,8 +17,8 @@ }); t.step(function() {-var offscreenCanvas = new OffscreenCanvas(100, 50);-var ctx = offscreenCanvas.getContext('2d');+var canvas = new OffscreenCanvas(100, 50);+var ctx = canvas.getContext('2d'); ctx.fillStyle = '#0f0'; ctx.fillRect(0, 0, 100, 50);@@ -30,7 +30,7 @@ ctx.moveTo(50, 25); ctx.lineTo(50, 25); ctx.stroke();-_assertPixel(offscreenCanvas, 50,25, 0,255,0,255, "50,25", "0,255,0,255");+_assertPixel(canvas, 50,25, 0,255,0,255, "50,25", "0,255,0,255"); t.done(); });
Based on the provided code diff, I don't see any security vulnerabilities being fixed. The changes appear to be purely cosmetic/refactoring changes (variable renaming) rather than security-related fixes. Here's the analysis following your format: Vulnerability Existed: no [No security vulnerability found] [testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.stroke.prune.line.html] [17-18, 30] [Old Code] var offscreenCanvas = new OffscreenCanvas(100, 50); var ctx = offscreenCanvas.getContext('2d'); ... _assertPixel(offscreenCanvas, 50,25, 0,255,0,255, "50,25", "0,255,0,255"); [Fixed Code] var canvas = new OffscreenCanvas(100, 50); var ctx = canvas.getContext('2d'); ... _assertPixel(canvas, 50,25, 0,255,0,255, "50,25", "0,255,0,255"); The changes simply rename the variable `offscreenCanvas` to `canvas` for consistency or readability, without any security implications.
If an attacker could control the contents of an iframe sandboxed with <code>allow-popups</code> but not <code>allow-scripts</code>, they were able to craft a link that, when clicked, would lead to JavaScript execution in violation of the sandbox. This vulnerability affects Firefox < 98, Firefox ESR < 91.7, and Thunderbird < 91.7.
--- /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_97_END/firefox-FIREFOX_RELEASE_97_END/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.intersect.worker.js+++ /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_98_END/firefox-FIREFOX_RELEASE_98_END/testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.intersect.worker.js@@ -13,8 +13,8 @@ }); t.step(function() {-var offscreenCanvas = new OffscreenCanvas(100, 50);-var ctx = offscreenCanvas.getContext('2d');+var canvas = new OffscreenCanvas(100, 50);+var ctx = canvas.getContext('2d'); ctx.fillStyle = '#0f0'; ctx.fillRect(0, 0, 100, 50);@@ -26,7 +26,7 @@ ctx.clip(); ctx.fillStyle = '#f00'; ctx.fillRect(0, 0, 100, 50);-_assertPixel(offscreenCanvas, 50,25, 0,255,0,255, "50,25", "0,255,0,255");+_assertPixel(canvas, 50,25, 0,255,0,255, "50,25", "0,255,0,255"); t.done(); });
After analyzing the provided code diff, I don't see any security-related fixes. The changes appear to be purely cosmetic/refactoring changes where a variable name was changed from `offscreenCanvas` to `canvas` for consistency or readability. Here's the structured response: Vulnerability Existed: no [No security vulnerability found] [testing/web-platform/tests/html/canvas/offscreen/path-objects/2d.path.clip.intersect.worker.js] [Lines 13-14, 26] [Old Code: var offscreenCanvas = new OffscreenCanvas(100, 50); var ctx = offscreenCanvas.getContext('2d'); _assertPixel(offscreenCanvas, 50,25, 0,255,0,255, "50,25", "0,255,0,255");] [Fixed Code: var canvas = new OffscreenCanvas(100, 50); var ctx = canvas.getContext('2d'); _assertPixel(canvas, 50,25, 0,255,0,255, "50,25", "0,255,0,255");] The changes don't address any security vulnerabilities but rather improve code consistency by using a more generic variable name. No security-related functionality was modified in this diff.
If an attacker could control the contents of an iframe sandboxed with <code>allow-popups</code> but not <code>allow-scripts</code>, they were able to craft a link that, when clicked, would lead to JavaScript execution in violation of the sandbox. This vulnerability affects Firefox < 98, Firefox ESR < 91.7, and Thunderbird < 91.7.
--- /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_97_END/firefox-FIREFOX_RELEASE_97_END/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.basic.worker.js+++ /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_98_END/firefox-FIREFOX_RELEASE_98_END/testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.basic.worker.js@@ -13,8 +13,8 @@ }); t.step(function() {-var offscreenCanvas = new OffscreenCanvas(100, 50);-var ctx = offscreenCanvas.getContext('2d');+var canvas = new OffscreenCanvas(100, 50);+var ctx = canvas.getContext('2d'); var gradient = ctx.createLinearGradient(0, 0, 100, 0); gradient.addColorStop(0, '#f00');@@ -25,7 +25,7 @@ ctx.shadowOffsetY = 50; ctx.fillStyle = gradient; ctx.fillRect(0, -50, 100, 50);-_assertPixel(offscreenCanvas, 50,25, 0,255,0,255, "50,25", "0,255,0,255");+_assertPixel(canvas, 50,25, 0,255,0,255, "50,25", "0,255,0,255"); t.done(); });
Based on the provided diff, I'll analyze it for security vulnerabilities: 1. Vulnerability Existed: no No security vulnerability found [File] testing/web-platform/tests/html/canvas/offscreen/shadows/2d.shadow.gradient.basic.worker.js [Lines] 13-25 [Old Code] var offscreenCanvas = new OffscreenCanvas(100, 50); var ctx = offscreenCanvas.getContext('2d'); [...] _assertPixel(offscreenCanvas, 50,25, 0,255,0,255, "50,25", "0,255,0,255"); [Fixed Code] var canvas = new OffscreenCanvas(100, 50); var ctx = canvas.getContext('2d'); [...] _assertPixel(canvas, 50,25, 0,255,0,255, "50,25", "0,255,0,255"); The changes appear to be purely cosmetic/refactoring, changing the variable name from `offscreenCanvas` to `canvas` for consistency or readability. There are no security-related changes in this diff, no changes to the actual functionality, and no security vulnerabilities being fixed. The changes don't affect how the canvas is created, used, or how pixels are asserted.
If an attacker could control the contents of an iframe sandboxed with <code>allow-popups</code> but not <code>allow-scripts</code>, they were able to craft a link that, when clicked, would lead to JavaScript execution in violation of the sandbox. This vulnerability affects Firefox < 98, Firefox ESR < 91.7, and Thunderbird < 91.7.
--- /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_97_END/firefox-FIREFOX_RELEASE_97_END/browser/base/content/test/sanitize/browser_sanitize-history.js+++ /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_98_END/firefox-FIREFOX_RELEASE_98_END/browser/base/content/test/sanitize/browser_sanitize-history.js@@ -41,7 +41,10 @@ Services.perms.ALLOW_ACTION );- await Sanitizer.sanitize(["history"], { range: [timestamp, Date.now()] });+ await Sanitizer.sanitize(["history"], {+ // Sanitizer and ClearDataService work with time range in PRTime (microseconds)+ range: [timestamp * 1000, Date.now() * 1000],+ }); Assert.equal( PermissionTestUtils.testExactPermission(
Here's the analysis of the provided code diff: Vulnerability Existed: yes Time Conversion Vulnerability [browser/base/content/test/sanitize/browser_sanitize-history.js] [Lines 41-44] [Old Code] ```javascript await Sanitizer.sanitize(["history"], { range: [timestamp, Date.now()] }); ``` [Fixed Code] ```javascript await Sanitizer.sanitize(["history"], { // Sanitizer and ClearDataService work with time range in PRTime (microseconds) range: [timestamp * 1000, Date.now() * 1000], }); ``` The vulnerability appears to be related to incorrect time unit handling where milliseconds were being passed to a function expecting microseconds (PRTime). This could lead to incomplete data sanitization as the time range would be interpreted incorrectly. The fix multiplies the timestamps by 1000 to convert from milliseconds to microseconds.
If an attacker could control the contents of an iframe sandboxed with <code>allow-popups</code> but not <code>allow-scripts</code>, they were able to craft a link that, when clicked, would lead to JavaScript execution in violation of the sandbox. This vulnerability affects Firefox < 98, Firefox ESR < 91.7, and Thunderbird < 91.7.
--- /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_97_END/firefox-FIREFOX_RELEASE_97_END/build/mach_virtualenv_packages.txt+++ /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_98_END/firefox-FIREFOX_RELEASE_98_END/build/mach_virtualenv_packages.txt@@ -1,9 +1,137 @@-packages.txt:build/common_virtualenv_packages.txt+pth:build+pth:config+pth:config/mozunit+pth:dom/bindings+pth:dom/bindings/parser+pth:layout/tools/reftest+pth:python/l10n+pth:python/mach+pth:python/mozboot+pth:python/mozbuild+pth:python/mozlint+pth:python/mozperftest+pth:python/mozrelease+pth:python/mozterm+pth:python/mozversioncontrol+pth:security/manager/tools+pth:taskcluster+pth:testing+pth:testing/awsy+pth:testing/condprofile+pth:testing/firefox-ui/harness+pth:testing/marionette/client+pth:testing/marionette/harness+pth:testing/mozbase/manifestparser+pth:testing/mozbase/mozcrash+pth:testing/mozbase/mozdebug+pth:testing/mozbase/mozdevice+pth:testing/mozbase/mozfile+pth:testing/mozbase/mozhttpd+pth:testing/mozbase/mozgeckoprofiler+pth:testing/mozbase/mozinfo+pth:testing/mozbase/mozinstall+pth:testing/mozbase/mozleak+pth:testing/mozbase/mozlog+pth:testing/mozbase/moznetwork+pth:testing/mozbase/mozpower+pth:testing/mozbase/mozprocess+pth:testing/mozbase/mozprofile+pth:testing/mozbase/mozproxy+pth:testing/mozbase/mozrunner+pth:testing/mozbase/mozsystemmonitor+pth:testing/mozbase/mozscreenshot+pth:testing/mozbase/moztest+pth:testing/mozbase/mozversion+pth:testing/raptor+pth:testing/talos+pth:testing/web-platform+vendored:testing/web-platform/tests/tools/third_party/funcsigs+vendored:testing/web-platform/tests/tools/third_party/h2+vendored:testing/web-platform/tests/tools/third_party/hpack+vendored:testing/web-platform/tests/tools/third_party/html5lib+vendored:testing/web-platform/tests/tools/third_party/hyperframe+vendored:testing/web-platform/tests/tools/third_party/pywebsocket3+vendored:testing/web-platform/tests/tools/third_party/webencodings+vendored:testing/web-platform/tests/tools/wptserve+vendored:testing/web-platform/tests/tools/wptrunner+pth:testing/xpcshell+vendored:third_party/python/aiohttp+vendored:third_party/python/appdirs+vendored:third_party/python/async_timeout+vendored:third_party/python/attrs+vendored:third_party/python/blessings+vendored:third_party/python/cbor2+vendored:third_party/python/certifi+vendored:third_party/python/chardet+vendored:third_party/python/click+vendored:third_party/python/colorama+vendored:third_party/python/compare_locales+vendored:third_party/python/cookies+vendored:third_party/python/cram+vendored:third_party/python/diskcache+vendored:third_party/python/distro+vendored:third_party/python/dlmanager+vendored:third_party/python/ecdsa+vendored:third_party/python/esprima+vendored:third_party/python/fluent.migrate+vendored:third_party/python/fluent.syntax+vendored:third_party/python/gyp/pylib+vendored:third_party/python/idna+vendored:third_party/python/idna-ssl+vendored:third_party/python/importlib_metadata+vendored:third_party/python/iso8601+vendored:third_party/python/Jinja2+vendored:third_party/python/jsmin+vendored:third_party/python/json-e+vendored:third_party/python/jsonschema+vendored:third_party/python/MarkupSafe/src+vendored:third_party/python/mohawk+vendored:third_party/python/mozilla_version+vendored:third_party/python/multidict+vendored:third_party/python/packaging+vendored:third_party/python/pathspec+vendored:third_party/python/pip+vendored:third_party/python/pip_tools+vendored:third_party/python/ply+vendored:third_party/python/pyasn1+vendored:third_party/python/pyasn1_modules+vendored:third_party/python/pylru+vendored:third_party/python/pyparsing+vendored:third_party/python/pyrsistent+vendored:third_party/python/python-hglib+vendored:third_party/python/pytoml+vendored:third_party/python/PyYAML/lib3/+vendored:third_party/python/redo+vendored:third_party/python/requests+vendored:third_party/python/requests_unixsocket+vendored:third_party/python/responses+vendored:third_party/python/rsa+vendored:third_party/python/setuptools+vendored:third_party/python/sentry_sdk+vendored:third_party/python/six+vendored:third_party/python/slugid+vendored:third_party/python/taskcluster+vendored:third_party/python/taskcluster_taskgraph+vendored:third_party/python/taskcluster_urls+vendored:third_party/python/tqdm+vendored:third_party/python/typing_extensions+vendored:third_party/python/urllib3+vendored:third_party/python/voluptuous+vendored:third_party/python/wheel+vendored:third_party/python/yamllint+vendored:third_party/python/yarl+vendored:third_party/python/zipp+pth:toolkit/components/telemetry/tests/marionette/harness+pth:tools+pth:tools/moztreedocs+pth:xpcom/ds/tools+pth:xpcom/geckoprocesstypes_generator+pth:xpcom/idl-parser # glean-sdk may not be installable if a wheel isn't available # and it has to be built from source.-pypi-optional:glean-sdk==42.3.2:telemetry will not be collected+pypi-optional:glean-sdk==43.0.2:telemetry will not be collected # Mach gracefully handles the case where `psutil` is unavailable. # We aren't (yet) able to pin packages in automation, so we have to # support down to the oldest locally-installed version (5.4.2). pypi-optional:psutil>=5.4.2,<=5.8.0:telemetry will be missing some data-pypi-optional:zstandard>=0.11.1,<=0.16.0:zstd archives will not be possible to extract+pypi-optional:zstandard>=0.11.1,<=0.17.0:zstd archives will not be possible to extract
After analyzing the provided code diff, I don't see any clear security vulnerabilities being fixed. The changes appear to be primarily about updating package versions and adding new paths/vendored packages to the virtual environment configuration. Here's my analysis: 1. Vulnerability Existed: no Package Version Updates [File] [Lines] [Old Code] pypi-optional:glean-sdk==42.3.2:telemetry will not be collected pypi-optional:zstandard>=0.11.1,<=0.16.0:zstd archives will not be possible to extract [Fixed Code] pypi-optional:glean-sdk==43.0.2:telemetry will not be collected pypi-optional:zstandard>=0.11.1,<=0.17.0:zstd archives will not be possible to extract Additional Details: These are routine version updates without any security implications mentioned. 2. Vulnerability Existed: no Path and Package Additions [File] [Lines] [Old Code] packages.txt:build/common_virtualenv_packages.txt [Fixed Code] [Extensive list of new pth and vendored paths] Additional Details: The changes represent an expansion of the virtual environment configuration, adding many new paths and vendored packages, but no security fixes are evident. The diff shows a significant expansion of the virtual environment configuration between Firefox 97 and 98, but I don't identify any specific security vulnerabilities being addressed in these changes. The version updates appear to be routine maintenance rather than security fixes.
If an attacker could control the contents of an iframe sandboxed with <code>allow-popups</code> but not <code>allow-scripts</code>, they were able to craft a link that, when clicked, would lead to JavaScript execution in violation of the sandbox. This vulnerability affects Firefox < 98, Firefox ESR < 91.7, and Thunderbird < 91.7.
--- /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_97_END/firefox-FIREFOX_RELEASE_97_END/third_party/rust/futures-util/src/stream/futures_unordered/mod.rs+++ /root/PatchLeaks-main/products/firefox_downloads/FIREFOX_RELEASE_98_END/firefox-FIREFOX_RELEASE_98_END/third_party/rust/futures-util/src/stream/futures_unordered/mod.rs@@ -6,6 +6,7 @@ use crate::task::AtomicWaker; use alloc::sync::{Arc, Weak}; use core::cell::UnsafeCell;+use core::cmp; use core::fmt::{self, Debug}; use core::iter::FromIterator; use core::marker::PhantomData;@@ -29,6 +30,33 @@ mod ready_to_run_queue; use self::ready_to_run_queue::{Dequeue, ReadyToRunQueue};++/// Constant used for a `FuturesUnordered` to determine how many times it is+/// allowed to poll underlying futures without yielding.+///+/// A single call to `poll_next` may potentially do a lot of work before+/// yielding. This happens in particular if the underlying futures are awoken+/// frequently but continue to return `Pending`. This is problematic if other+/// tasks are waiting on the executor, since they do not get to run. This value+/// caps the number of calls to `poll` on underlying futures a single call to+/// `poll_next` is allowed to make.+///+/// The value itself is chosen somewhat arbitrarily. It needs to be high enough+/// that amortize wakeup and scheduling costs, but low enough that we do not+/// starve other tasks for long.+///+/// See also https://github.com/rust-lang/futures-rs/issues/2047.+///+/// Note that using the length of the `FuturesUnordered` instead of this value+/// may cause problems if the number of futures is large.+/// See also https://github.com/rust-lang/futures-rs/pull/2527.+///+/// Additionally, polling the same future twice per iteration may cause another+/// problem. So, when using this value, it is necessary to limit the max value+/// based on the length of the `FuturesUnordered`.+/// (e.g., `cmp::min(self.len(), YIELD_EVERY)`)+/// See also https://github.com/rust-lang/futures-rs/pull/2333.+const YIELD_EVERY: usize = 32; /// A set of futures which may complete in any order. ///@@ -383,21 +411,8 @@ type Item = Fut::Output; fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {- // Variable to determine how many times it is allowed to poll underlying- // futures without yielding.- //- // A single call to `poll_next` may potentially do a lot of work before- // yielding. This happens in particular if the underlying futures are awoken- // frequently but continue to return `Pending`. This is problematic if other- // tasks are waiting on the executor, since they do not get to run. This value- // caps the number of calls to `poll` on underlying futures a single call to- // `poll_next` is allowed to make.- //- // The value is the length of FuturesUnordered. This ensures that each- // future is polled only once at most per iteration.- //- // See also https://github.com/rust-lang/futures-rs/issues/2047.- let yield_every = self.len();+ // See YIELD_EVERY docs for more.+ let yield_every = cmp::min(self.len(), YIELD_EVERY); // Keep track of how many child futures we have polled, // in case we want to forcibly yield.@@ -558,7 +573,7 @@ pub fn clear(&mut self) { self.clear_head_all();- // SAFETY: we just cleared all the tasks and we have &mut self+ // we just cleared all the tasks, and we have &mut self, so this is safe. unsafe { self.ready_to_run_queue.clear() }; self.is_terminated.store(false, Relaxed);@@ -575,9 +590,24 @@ impl<Fut> Drop for FuturesUnordered<Fut> { fn drop(&mut self) {+ // When a `FuturesUnordered` is dropped we want to drop all futures+ // associated with it. At the same time though there may be tons of+ // wakers flying around which contain `Task<Fut>` references+ // inside them. We'll let those naturally get deallocated. self.clear_head_all();- // SAFETY: we just cleared all the tasks and we have &mut self- unsafe { self.ready_to_run_queue.clear() };++ // Note that at this point we could still have a bunch of tasks in the+ // ready to run queue. None of those tasks, however, have futures+ // associated with them so they're safe to destroy on any thread. At+ // this point the `FuturesUnordered` struct, the owner of the one strong+ // reference to the ready to run queue will drop the strong reference.+ // At that point whichever thread releases the strong refcount last (be+ // it this thread or some other thread as part of an `upgrade`) will+ // clear out the ready to run queue and free all remaining tasks.+ //+ // While that freeing operation isn't guaranteed to happen here, it's+ // guaranteed to happen "promptly" as no more "blocking work" will+ // happen while there's a strong refcount held. } }
Here's the analysis of the provided code diff following the specified format: 1. Vulnerability Existed: yes Denial of Service (DoS) via Unbounded Polling [third_party/rust/futures-util/src/stream/futures_unordered/mod.rs] [Lines 383-411] [Old Code] ```rust let yield_every = self.len(); ``` [Fixed Code] ```rust let yield_every = cmp::min(self.len(), YIELD_EVERY); ``` Additional Details: The fix addresses a potential DoS vulnerability where a FuturesUnordered could potentially starve other tasks by polling futures an unbounded number of times (equal to the length of the collection). The fix introduces a constant limit (YIELD_EVERY = 32) to ensure fair scheduling. 2. Vulnerability Existed: not sure Potential Memory Safety Issue [third_party/rust/futures-util/src/stream/futures_unordered/mod.rs] [Lines 558-575] [Old Code] ```rust // SAFETY: we just cleared all the tasks and we have &mut self unsafe { self.ready_to_run_queue.clear() }; ``` [Fixed Code] ```rust // we just cleared all the tasks, and we have &mut self, so this is safe. unsafe { self.ready_to_run_queue.clear() }; ``` Additional Details: The change in comments suggests there might have been concerns about memory safety, but it's unclear if this was an actual vulnerability or just improved documentation. The unsafe block remains, but the justification is made more explicit. 3. Vulnerability Existed: not sure Potential Resource Cleanup Issue [third_party/rust/futures-util/src/stream/futures_unordered/mod.rs] [Lines 575-590] [Old Code] ```rust self.clear_head_all(); // SAFETY: we just cleared all the tasks and we have &mut self unsafe { self.ready_to_run_queue.clear() }; ``` [Fixed Code] ```rust // Added extensive documentation about cleanup safety self.clear_head_all(); // (No direct unsafe clear call in the new version) ``` Additional Details: The change in drop implementation suggests there might have been concerns about proper resource cleanup, particularly regarding wakers and task references. The new version provides more detailed documentation about the cleanup process, but it's unclear if this was fixing an actual vulnerability or just improving robustness.
If an attacker could control the contents of an iframe sandboxed with <code>allow-popups</code> but not <code>allow-scripts</code>, they were able to craft a link that, when clicked, would lead to JavaScript execution in violation of the sandbox. This vulnerability affects Firefox < 98, Firefox ESR < 91.7, and Thunderbird < 91.7.