High firefox Memory Corruption 🔧 Commit mapped

Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
Impacthigh
DescriptionMemory safety bugs present in Firefox ESR 140.8, Thunderbird ESR 140.8, Firefox 148 and Thunderbird 148. Some of these bugs showed evidence of memory corruption and we presume that with enough effort some of these could have been exploited to run arbitrary code.
ComponentToolkit
Bug ClassMemory Corruption
Tracker2004652
Fix commite99a6260dbfe (firefox) +228/-81
CISA KEVNot listed
CreditedChristian Holler, Gabriele Svelto, Tom Schuster and the Mozilla Fuzzing Team
Disclosed2026-03-24

Files Changed

  • .cargo/config.toml.in
  • Cargo.lock
  • third_party/rust/coremidi/.cargo-checksum.json
  • third_party/rust/coremidi/.idea/.gitignore
  • third_party/rust/cubeb-coreaudio/.cargo-checksum.json
  • third_party/rust/cubeb-coreaudio/src/backend/aggregate_device.rs
  • third_party/rust/cubeb-coreaudio/src/backend/mod.rs
  • third_party/rust/cubeb-coreaudio/src/backend/tests/mod.rs
  • third_party/rust/cubeb-coreaudio/src/backend/tests/sync_callback.rs
  • third_party/rust/cubeb-sys/.cargo-checksum.json
  • third_party/rust/cubeb-sys/libcubeb/.gitignore
  • third_party/rust/cubeb-sys/libcubeb/cmake/sanitizers-cmake/.gitignore
  • third_party/rust/cubeb-sys/libcubeb/src/cubeb-coreaudio-rs/.gitignore
  • third_party/rust/cubeb-sys/libcubeb/src/cubeb-pulse-rs/.gitignore
  • third_party/rust/glslopt/.cargo-checksum.json
  • third_party/rust/glslopt/glsl-optimizer/.gitignore
  • third_party/rust/mp4parse/.cargo-checksum.json
  • third_party/rust/mp4parse/link-u-avif-sample-images/.gitignore
  • third_party/rust/nss/.cargo-checksum.json
  • third_party/rust/nss/fixtures/profile/.gitignore
  • third_party/rust/regex/.cargo-checksum.json
  • third_party/rust/regex/record/old-bench-log/.gitignore
  • third_party/rust/unicode-ident/.cargo-checksum.json
  • third_party/rust/unicode-ident/tests/fst/.gitignore
  • third_party/rust/wasmparser/.cargo-checksum.json
  • third_party/rust/wasmparser/benches/.gitignore
  • third_party/rust/wast/.cargo-checksum.json
  • third_party/rust/wast/tests/.gitattributes
  • third_party/rust/wast/tests/.gitignore
  • toolkit/library/rust/shared/Cargo.toml
diff --git a/.cargo/config.toml.in b/.cargo/config.toml.in
index 5dfd02e06a6..5fafc0415ad 100644
--- a/.cargo/config.toml.in
+++ b/.cargo/config.toml.in
@@ -85,9 +85,9 @@ git = "https://github.com/mozilla/audioipc"
 rev = "c8d3f03cb5f889e4cab18cc1360ad0daa074f17a"
 replace-with = "vendored-sources"
 
-[source."git+https://github.com/mozilla/cubeb-coreaudio-rs?rev=ee717924ccfefc3b0b58e52968a9036b73f56f9e"]
+[source."git+https://github.com/mozilla/cubeb-coreaudio-rs?rev=5b689a7f90086e07c271ad1cf79325ee06112ab6"]
 git = "https://github.com/mozilla/cubeb-coreaudio-rs"
-rev = "ee717924ccfefc3b0b58e52968a9036b73f56f9e"
+rev = "5b689a7f90086e07c271ad1cf79325ee06112ab6"
 replace-with = "vendored-sources"
 
 [source."git+https://github.com/mozilla/cubeb-pulse-rs?rev=9cebfcceb073e9dd10cfb275a7590bca58d4c251"]
diff --git a/Cargo.lock b/Cargo.lock
index c362540f8f0..56890117947 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1090,7 +1090,7 @@ dependencies = [
 [[package]]
 name = "coreaudio-sys-utils"
 version = "0.1.0"
-source = "git+https://github.com/mozilla/cubeb-coreaudio-rs?rev=ee717924ccfefc3b0b58e52968a9036b73f56f9e#ee717924ccfefc3b0b58e52968a9036b73f56f9e"
+source = "git+https://github.com/mozilla/cubeb-coreaudio-rs?rev=5b689a7f90086e07c271ad1cf79325ee06112ab6#5b689a7f90086e07c271ad1cf79325ee06112ab6"
 dependencies = [
  "core-foundation-sys",
  "coreaudio-sys",
@@ -1436,7 +1436,7 @@ dependencies = [
 [[package]]
 name = "cubeb-coreaudio"
 version = "0.1.0"
-source = "git+https://github.com/mozilla/cubeb-coreaudio-rs?rev=ee717924ccfefc3b0b58e52968a9036b73f56f9e#ee717924ccfefc3b0b58e52968a9036b73f56f9e"
+source = "git+https://github.com/mozilla/cubeb-coreaudio-rs?rev=5b689a7f90086e07c271ad1cf79325ee06112ab6#5b689a7f90086e07c271ad1cf79325ee06112ab6"
 dependencies = [
  "atomic",
  "audio-mixer",
diff --git a/third_party/rust/coremidi/.cargo-checksum.json b/third_party/rust/coremidi/.cargo-checksum.json
index a4ed7d3b066..b83a7900846 100644
--- a/third_party/rust/coremidi/.cargo-checksum.json
+++ b/third_party/rust/coremidi/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{".cargo_vcs_info.json":"027854b9a546ff3bcce94fe10ad83debd7570429aadd23e360dde32935aea52a",".github/workflows/deploy.yaml":"de84428eb35f3b6617704d80dbb916987d9a4fbaf1d2a5b1a52a1c4c60d89c94",".github/workflows/test.yaml":"7a8e59be2e1a4253dd277874257003a20a1149de891749f701910a270c69a3af",".idea/.gitignore":"4073be0dd9e3ae38beba97eed085d5f023a5f2cdc101ec35f2877b185b1f1193","Cargo.lock":"5e5dd0b8006fbcc96bff6908978ddce772095a95a8b8e8bd29601b862991bef2","Cargo.toml":"505c6ef2f5e1dda024ea65c0ea8f5d3bb05f3b017d2c9e4463a25c838ea208e2","Cargo.toml.orig":"70de399a10af67ae1d1d8660c6ddec5b10ceefc23b3d84767362d06f9416f7d2","LICENSE":"c1c457e1b2794c9044f0e2d66a7010c223d0fb65b06e1dfbab6e21888ab09c16","README.md":"e55bfa1cadbbf497d28f3c9fc470eb381ff3c9ef7bbc3bcb7828a097924e21ab","examples/endpoints.rs":"4431c57aaf70ee9bec3bc3eb97ccc0d92673cdb49f67c8d81e9caf1fb1a5a213","examples/notifications.rs":"8aed2404777a2d68efc4ddb89ad8f612b20045e1bc1a67df943b8f31ba32e322","examples/properties.rs":"37c0c205f7677ff18caa1258a3c88313ce06033facc025adf7364db5bddeb5df","examples/receive.rs":"4a754506f9f89e58d4abcc5148f39a501e79f4ca7768e31ff8ac808deb59d2f9","examples/send.rs":"35b4ea48c405e085e918c91831d9ac9a89312da66540cdb0e4e6e22647565503","examples/virtual-destination.rs":"2c44bd1a704d3c6ea3a379921f7a91bcd0c51f6e85787c5fa816c5983d07e76e","examples/virtual-source.rs":"e9444b89a940911e946e98ab23979407b724b4487501cd7f2bc74507eed8deec","rust-toolchain":"b104646411661bf06fc72347bbb9966cded636b50c02f722d7e8b8f2131a5aff","src/any_object.rs":"2f3586da54ad8252e452c51c0342b2721db3094e33bcfae5f590049808959234","src/client.rs":"0a41d7cf4286fef3dd22348079aac27beee2c32fdb9f72c31254645f781571f9","src/device.rs":"a9c470f28c14b45ecfca9d96a275388238b74bbea3594f28a8741ce6fa975690","src/endpoints/destinations.rs":"77f2df648df7c69afbca33206539c7131e0d7192f03c0fa9ef9947f63cda9a1c","src/endpoints/endpoint.rs":"84715d6f175cbc2fcdb4cbcd8ab9db9c745fc50b1b1853919078fa20c16fe1a3","src/endpoints/mod.rs":"5750836ea1bbc4914e41fa29ffe1ecb5c289933a94875777a00272acb9fd5b11","src/endpoints/sources.rs":"a71c79e32d2a0647df6f4d5da5ba7d71bd55948cf4436df1b6089a30cd7ea692","src/entity.rs":"5b02ffd6207842e84a8c5c73d7439c6d39881aac04a0099258d0e16a21668ecb","src/events.rs":"40b4c7d5b2e7afa6b5213aad6114cc92c2122acb08d77fbf15bd0ba48207e53e","src/lib.rs":"ed0e9016b9d9ffb9b638ed63738c3f0623e17900a19fe16f009d77fd5d20a81e","src/notifications.rs":"0ab5c2f169c7b4515b294aa960bf83327c109a62e343019602517cf726712b7c","src/object.rs":"c5b4162898b1a295bcdcd4ab2042752adfd1aef1a4dd8c048407ffe60cdf4630","src/packets.rs":"8d1dd5c274567077ed7dbed614b103f1519b2b58ca251d3627828d9eab8850ad","src/ports.rs":"cf0c3e168e42e5b8e32ac86044453ca36cb17adb54dbfc36470f751f4d36dccc","src/properties.rs":"4b3bd650be9ca163b34868fc98e282bf4e9ed216500ff0513b169c03a7a7ec97","src/protocol.rs":"811f87c29e67adad51980930b692a413bfdb4f41130de8a3f8e8fce99159a3a3"},"package":"964eb3e10ea8b0d29c797086aab3ca730f75e06dced0cb980642fd274a5cca30"}
\ No newline at end of file
+{"files":{".cargo_vcs_info.json":"027854b9a546ff3bcce94fe10ad83debd7570429aadd23e360dde32935aea52a",".github/workflows/deploy.yaml":"de84428eb35f3b6617704d80dbb916987d9a4fbaf1d2a5b1a52a1c4c60d89c94",".github/workflows/test.yaml":"7a8e59be2e1a4253dd277874257003a20a1149de891749f701910a270c69a3af","Cargo.lock":"5e5dd0b8006fbcc96bff6908978ddce772095a95a8b8e8bd29601b862991bef2","Cargo.toml":"505c6ef2f5e1dda024ea65c0ea8f5d3bb05f3b017d2c9e4463a25c838ea208e2","Cargo.toml.orig":"70de399a10af67ae1d1d8660c6ddec5b10ceefc23b3d84767362d06f9416f7d2","LICENSE":"c1c457e1b2794c9044f0e2d66a7010c223d0fb65b06e1dfbab6e21888ab09c16","README.md":"e55bfa1cadbbf497d28f3c9fc470eb381ff3c9ef7bbc3bcb7828a097924e21ab","examples/endpoints.rs":"4431c57aaf70ee9bec3bc3eb97ccc0d92673cdb49f67c8d81e9caf1fb1a5a213","examples/notifications.rs":"8aed2404777a2d68efc4ddb89ad8f612b20045e1bc1a67df943b8f31ba32e322","examples/properties.rs":"37c0c205f7677ff18caa1258a3c88313ce06033facc025adf7364db5bddeb5df","examples/receive.rs":"4a754506f9f89e58d4abcc5148f39a501e79f4ca7768e31ff8ac808deb59d2f9","examples/send.rs":"35b4ea48c405e085e918c91831d9ac9a89312da66540cdb0e4e6e22647565503","examples/virtual-destination.rs":"2c44bd1a704d3c6ea3a379921f7a91bcd0c51f6e85787c5fa816c5983d07e76e","examples/virtual-source.rs":"e9444b89a940911e946e98ab23979407b724b4487501cd7f2bc74507eed8deec","rust-toolchain":"b104646411661bf06fc72347bbb9966cded636b50c02f722d7e8b8f2131a5aff","src/any_object.rs":"2f3586da54ad8252e452c51c0342b2721db3094e33bcfae5f590049808959234","src/client.rs":"0a41d7cf4286fef3dd22348079aac27beee2c32fdb9f72c31254645f781571f9","src/device.rs":"a9c470f28c14b45ecfca9d96a275388238b74bbea3594f28a8741ce6fa975690","src/endpoints/destinations.rs":"77f2df648df7c69afbca33206539c7131e0d7192f03c0fa9ef9947f63cda9a1c","src/endpoints/endpoint.rs":"84715d6f175cbc2fcdb4cbcd8ab9db9c745fc50b1b1853919078fa20c16fe1a3","src/endpoints/mod.rs":"5750836ea1bbc4914e41fa29ffe1ecb5c289933a94875777a00272acb9fd5b11","src/endpoints/sources.rs":"a71c79e32d2a0647df6f4d5da5ba7d71bd55948cf4436df1b6089a30cd7ea692","src/entity.rs":"5b02ffd6207842e84a8c5c73d7439c6d39881aac04a0099258d0e16a21668ecb","src/events.rs":"40b4c7d5b2e7afa6b5213aad6114cc92c2122acb08d77fbf15bd0ba48207e53e","src/lib.rs":"ed0e9016b9d9ffb9b638ed63738c3f0623e17900a19fe16f009d77fd5d20a81e","src/notifications.rs":"0ab5c2f169c7b4515b294aa960bf83327c109a62e343019602517cf726712b7c","src/object.rs":"c5b4162898b1a295bcdcd4ab2042752adfd1aef1a4dd8c048407ffe60cdf4630","src/packets.rs":"8d1dd5c274567077ed7dbed614b103f1519b2b58ca251d3627828d9eab8850ad","src/ports.rs":"cf0c3e168e42e5b8e32ac86044453ca36cb17adb54dbfc36470f751f4d36dccc","src/properties.rs":"4b3bd650be9ca163b34868fc98e282bf4e9ed216500ff0513b169c03a7a7ec97","src/protocol.rs":"811f87c29e67adad51980930b692a413bfdb4f41130de8a3f8e8fce99159a3a3"},"package":"964eb3e10ea8b0d29c797086aab3ca730f75e06dced0cb980642fd274a5cca30"}
\ No newline at end of file
diff --git a/third_party/rust/coremidi/.idea/.gitignore b/third_party/rust/coremidi/.idea/.gitignore
deleted file mode 100644
index 62c893550ad..00000000000
--- a/third_party/rust/coremidi/.idea/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-.idea/
\ No newline at end of file
diff --git a/third_party/rust/cubeb-coreaudio/.cargo-checksum.json b/third_party/rust/cubeb-coreaudio/.cargo-checksum.json
index 6d6de08d46a..2c370b77df0 100644
--- a/third_party/rust/cubeb-coreaudio/.cargo-checksum.json
+++ b/third_party/rust/cubeb-coreaudio/.cargo-checksum.json
@@ -1 +1 @@
-{"files":{".circleci/config.yml":"7f3dc865105ca8f33965a7958b1fe2e627ae2d5a703f3b2a4ab6e2e796018597",".editorconfig":"4e53b182bcc78b83d7e1b5c03efa14d22d4955c4ed2514d1ba4e99c1eb1a50ba",".githooks/pre-push":"8b8b26544cd56f54c0c33812551f786bb25cb08c86dbfeb6bf3daad881c826a1",".github/workflows/test.yml":"c63a88abf1b6860c7b039c8fae6ad4a263a8ce415dd551d014e32aa5d2ca2b2e",".travis.yml":"dc07bac53f70f16c9bdf52264bdc58500ae6018c1b4c567bc7642f6b4ca3cc35","Cargo.lock":"5a80d932526192fe7d2ec016d82620f8caf18e1624d70908a96230e5c8965667","Cargo.toml":"e4d8055ee32a452254f59dfd0cd1ef2cfd490bcda81ea1387a004415b768de82","LICENSE":"6e6f56aff5bbf3cbc60747e152fb1a719bd0716aaf6d711c554f57d92e96297c","README.md":"0007782a05a5330f739ad789c19c82562c82e32386b0447000fc72c0d48405bc","build-audiounit-rust-in-cubeb.sh":"d228a05985dcd02ec1ecac66a2b64dae5a530804a25a7054ccc95905aedfb7ef","install_git_hook.sh":"d38c8e51e636f6b90b489621ac34ccd1d1b1f40dccce3d178ed1da1c5068f16d","install_rustfmt_clippy.sh":"4ae90d8dcb9757cb3ae4ae142ef80e5377c0dde61c63f4a3c32418646e80ca7b","run_device_tests.sh":"2f6b7385e173eb3558a793421ebb9d4df1c0edeb3aff8a054f01e00f43f4381a","run_sanitizers.sh":"bb9f7c1091d9397f52d190fc8708e1f939735fee450d1a914f7a17139e8b62f1","run_tests.sh":"c7b4087ad12482bac3468828a4648d4be07a75e5840f8f760992887639000054","src/backend/aggregate_device.rs":"37a8f19af165a4413c512669ea4538b20adb128de0a490a13d5f54c2558c8327","src/backend/auto_release.rs":"050fdcee74cf46b9a8a85a877e166d72a853d33220f59cf734cbb6ea09daa441","src/backend/buffer_manager.rs":"0d1f9af94271ed4042e8cf0bb9658604c9f2e1ff9d931f50c1904d5ee372cb72","src/backend/device_property.rs":"4afd8961b4f722791f5c35a0934352a0a452f9d610e49c53820492788c9a77c1","src/backend/intern.rs":"11ca424e4eb77f8eb9fd5a6717d1e791facf9743156a8534f0016fcf64d57b0f","src/backend/mixer.rs":"c4d09291598cbffb2217b551770ec590f34b6dd6b461dd99b019d5bb70f0eef3","src/backend/mod.rs":"40de35ae0d31e270dbd805a7595f61c41710a7c93d9adc4af9b2ae7b021ec56d","src/backend/resampler.rs":"48bf8f56ae8d60dbabca6417b768000619abee8731ac3902164b45651ac08a4d","src/backend/tests/aggregate_device.rs":"e962f805d9d9e6c9bd258eb718862086f16e9bb519ddd1cfede3b955ab0331ae","src/backend/tests/api.rs":"2ea37fae81cddee7790973cf1a323ee0deaf6a017e844e74b1b653ad8ae28f08","src/backend/tests/backlog.rs":"3b189a7e036543c467cc242af0ed3332721179ee2b1c8847a6db563546f1ac52","src/backend/tests/device_change.rs":"e09e75a5e654b1ac8359d086e6d28002fa4519debbedb8e1e7d091eba50e33f9","src/backend/tests/device_property.rs":"6a5d9c4d5d46cb582c78ff1dc55ecacfea675566df0ee9b50e1a89f00fe9ff99","src/backend/tests/interfaces.rs":"1bff45c21f7e3493d8159feba6c98484c548527984254434d6fce9af265a6e75","src/backend/tests/manual.rs":"7706b0bdaad7014eb2ef79f5298d1ac09306735e25b0718acf05c6a4652c35df","src/backend/tests/mod.rs":"8dba770023d7f9c4228f0e11915347f0e07da5fd818e3ee4478c4b197af9aa2a","src/backend/tests/parallel.rs":"a7ebd579339c40ca64c0757cc9da6baec641e670f226e1b2ec5049894700bd7a","src/backend/tests/tone.rs":"b028c67777b6453a26190b6a49785dfe28556adcbe179cb10862ce0d47ee8509","src/backend/tests/utils.rs":"33568e881e9e944949a2d58ebbb18b1e5e23dc097cbf7706fa2dd60d7730c500","src/backend/utils.rs":"98317f425f4436af74df1fb79faf4d4a6beab824aa51f32e29af81ca39334543","src/capi.rs":"21b66b70545bf04ec719928004d1d9adb45b24ced51288f5b2993d79aaf78f5f","src/lib.rs":"a2c8a665cae5e26e6eee4c93b480f7ed708eeb6ba9ccf6f82b41c262f4b60015","todo.md":"efc1f012eb9a331a040cad4ac03aa79307f25885f71b6fb38f3ad7af8d7d515c"},"package":null}
\ No newline at end of file
+{"files":{".circleci/config.yml":"7f3dc865105ca8f33965a7958b1fe2e627ae2d5a703f3b2a4ab6e2e796018597",".editorconfig":"4e53b182bcc78b83d7e1b5c03efa14d22d4955c4ed2514d1ba4e99c1eb1a50ba",".githooks/pre-push":"8b8b26544cd56f54c0c33812551f786bb25cb08c86dbfeb6bf3daad881c826a1",".github/workflows/test.yml":"c63a88abf1b6860c7b039c8fae6ad4a263a8ce415dd551d014e32aa5d2ca2b2e",".travis.yml":"dc07bac53f70f16c9bdf52264bdc58500ae6018c1b4c567bc7642f6b4ca3cc35","Cargo.lock":"5a80d932526192fe7d2ec016d82620f8caf18e1624d70908a96230e5c8965667","Cargo.toml":"e4d8055ee32a452254f59dfd0cd1ef2cfd490bcda81ea1387a004415b768de82","LICENSE":"6e6f56aff5bbf3cbc60747e152fb1a719bd0716aaf6d711c554f57d92e96297c","README.md":"0007782a05a5330f739ad789c19c82562c82e32386b0447000fc72c0d48405bc","build-audiounit-rust-in-cubeb.sh":"d228a05985dcd02ec1ecac66a2b64dae5a530804a25a7054ccc95905aedfb7ef","install_git_hook.sh":"d38c8e51e636f6b90b489621ac34ccd1d1b1f40dccce3d178ed1da1c5068f16d","install_rustfmt_clippy.sh":"4ae90d8dcb9757cb3ae4ae142ef80e5377c0dde61c63f4a3c32418646e80ca7b","run_device_tests.sh":"2f6b7385e173eb3558a793421ebb9d4df1c0edeb3aff8a054f01e00f43f4381a","run_sanitizers.sh":"bb9f7c1091d9397f52d190fc8708e1f939735fee450d1a914f7a17139e8b62f1","run_tests.sh":"c7b4087ad12482bac3468828a4648d4be07a75e5840f8f760992887639000054","src/backend/aggregate_device.rs":"b78db7878f0e6b79fc90720d38b47f0a66124092ad1518a606e1ddcde8b80b55","src/backend/auto_release.rs":"050fdcee74cf46b9a8a85a877e166d72a853d33220f59cf734cbb6ea09daa441","src/backend/buffer_manager.rs":"0d1f9af94271ed4042e8cf0bb9658604c9f2e1ff9d931f50c1904d5ee372cb72","src/backend/device_property.rs":"4afd8961b4f722791f5c35a0934352a0a452f9d610e49c53820492788c9a77c1","src/backend/intern.rs":"11ca424e4eb77f8eb9fd5a6717d1e791facf9743156a8534f0016fcf64d57b0f","src/backend/mixer.rs":"c4d09291598cbffb2217b551770ec590f34b6dd6b461dd99b019d5bb70f0eef3","src/backend/mod.rs":"152b4a8b22b86284c45abc6dc341a00fe01ffc78eb6ae950d60d42ea0957b728","src/backend/resampler.rs":"48bf8f56ae8d60dbabca6417b768000619abee8731ac3902164b45651ac08a4d","src/backend/tests/aggregate_device.rs":"e962f805d9d9e6c9bd258eb718862086f16e9bb519ddd1cfede3b955ab0331ae","src/backend/tests/api.rs":"2ea37fae81cddee7790973cf1a323ee0deaf6a017e844e74b1b653ad8ae28f08","src/backend/tests/backlog.rs":"3b189a7e036543c467cc242af0ed3332721179ee2b1c8847a6db563546f1ac52","src/backend/tests/device_change.rs":"e09e75a5e654b1ac8359d086e6d28002fa4519debbedb8e1e7d091eba50e33f9","src/backend/tests/device_property.rs":"6a5d9c4d5d46cb582c78ff1dc55ecacfea675566df0ee9b50e1a89f00fe9ff99","src/backend/tests/interfaces.rs":"1bff45c21f7e3493d8159feba6c98484c548527984254434d6fce9af265a6e75","src/backend/tests/manual.rs":"7706b0bdaad7014eb2ef79f5298d1ac09306735e25b0718acf05c6a4652c35df","src/backend/tests/mod.rs":"e388a37edd5f53cda04fe1ac8bf033e423c6604014792177c623c8456fe5d257","src/backend/tests/parallel.rs":"a7ebd579339c40ca64c0757cc9da6baec641e670f226e1b2ec5049894700bd7a","src/backend/tests/sync_callback.rs":"20e7ba57714c0d2bff3bc8d3a912f17fdab293737bc729eae1684070b90b72c4","src/backend/tests/tone.rs":"b028c67777b6453a26190b6a49785dfe28556adcbe179cb10862ce0d47ee8509","src/backend/tests/utils.rs":"33568e881e9e944949a2d58ebbb18b1e5e23dc097cbf7706fa2dd60d7730c500","src/backend/utils.rs":"98317f425f4436af74df1fb79faf4d4a6beab824aa51f32e29af81ca39334543","src/capi.rs":"21b66b70545bf04ec719928004d1d9adb45b24ced51288f5b2993d79aaf78f5f","src/lib.rs":"a2c8a665cae5e26e6eee4c93b480f7ed708eeb6ba9ccf6f82b41c262f4b60015","todo.md":"efc1f012eb9a331a040cad4ac03aa79307f25885f71b6fb38f3ad7af8d7d515c"},"package":null}
\ No newline at end of file
diff --git a/third_party/rust/cubeb-coreaudio/src/backend/aggregate_device.rs b/third_party/rust/cubeb-coreaudio/src/backend/aggregate_device.rs
index 27c07e33b7e..e4558ec380f 100644
--- a/third_party/rust/cubeb-coreaudio/src/backend/aggregate_device.rs
+++ b/third_party/rust/cubeb-coreaudio/src/backend/aggregate_device.rs
@@ -152,9 +152,9 @@ impl AggregateDevice {
         debug_assert_running_serially();
         let waiting_time = Duration::new(5, 0);
 
-        let condvar_pair = Arc::new((Mutex::new(()), Condvar::new()));
-        let mut cloned_condvar_pair = condvar_pair.clone();
-        let data_ptr = &mut cloned_condvar_pair as *mut Arc<(Mutex<()>, Condvar)>;
+        let condvar_pair = Box::new((Mutex::new(()), Condvar::new()));
+        let data_ptr = Box::into_raw(condvar_pair);
+        sync_callback_registry_register(data_ptr as usize);
 
         let address = get_property_address(
             Property::HardwareDevices,
@@ -177,12 +177,14 @@ impl AggregateDevice {
                 data_ptr as *mut c_void,
             );
             assert_eq!(status, NO_ERR);
+            sync_callback_registry_unregister(data_ptr as usize);
+            unsafe { drop(Box::from_raw(data_ptr)) };
         });
 
         let device = Self::create_blank_device(plugin_id)?;
 
         // Wait until the aggregate is created.
-        let (lock, cvar) = &*condvar_pair;
+        let (lock, cvar) = unsafe { &*data_ptr };
         let guard = lock.lock().unwrap();
         let (_guard, timeout_res) = cvar
             .wait_timeout_while(guard, waiting_time, |()| !get_devices().contains(&device))
@@ -202,10 +204,12 @@ impl AggregateDevice {
             data: *mut c_void,
         ) -> OSStatus {
             assert_eq!(id, kAudioObjectSystemObject);
-            let pair = unsafe { &mut *(data as *mut Arc<(Mutex<()>, Condvar)>) };
-            let (lock, cvar) = &**pair;
-            let _guard = lock.lock().unwrap();
-            cvar.notify_one();
+            with_sync_callback_ptr(data, || {
+                let pair = unsafe { &*(data as *const (Mutex<()>, Condvar)) };
+                let (lock, cvar) = pair;
+                let _guard = lock.lock().unwrap();
+                cvar.notify_one();
+            });
             NO_ERR
         }
 
@@ -314,9 +318,9 @@ impl AggregateDevice {
 
         let waiting_time = Duration::new(5, 0);
 
-        let condvar_pair = Arc::new((Mutex::new(AudioObjectID::default()), Condvar::new()));
-        let mut cloned_condvar_pair = condvar_pair.clone();
-        let data_ptr = &mut cloned_condvar_pair as *mut Arc<(Mutex<AudioObjectID>, Condvar)>;
+        let condvar_pair = Box::new((Mutex::new(AudioObjectID::default()), Condvar::new()));
+        let data_ptr = Box::into_raw(condvar_pair);
+        sync_callback_registry_register(data_ptr as usize);
 
         let status = audio_object_add_property_listener(
             device_id,
@@ -325,22 +329,27 @@ impl AggregateDevice {
             data_ptr as *mut c_void,
         );
         if status != NO_ERR {
+            sync_callback_registry_unregister(data_ptr as usize);
+            unsafe { drop(Box::from_raw(data_ptr)) };
             return Err(Error::from(status));
         }
 
-        let remove_listener = || -> OSStatus {
-            audio_object_remove_property_listener(
+        let cleanup = || {
+            let status = audio_object_remove_property_listener(
                 device_id,
                 &address,
                 devices_changed_callback,
                 data_ptr as *mut c_void,
-            )
+            );
+            sync_callback_registry_unregister(data_ptr as usize);
+            unsafe { drop(Box::from_raw(data_ptr)) };
+            status
         };
 
         Self::set_sub_devices(device_id, input_id, output_id)?;
 
         // Wait until the sub devices are added.
-        let (lock, cvar) = &*condvar_pair;
+        let (lock, cvar) = unsafe { &*data_ptr };
         let device = lock.lock().unwrap();
         if *device != device_id {
             let (dev, timeout_res) = cvar.wait_timeout(device, waiting_time).unwrap();
@@ -353,13 +362,10 @@ impl AggregateDevice {
                 );
             }
             if *dev != device_id {
-                let status = remove_listener();
+                let status = cleanup();
                 // If the error is kAudioHardwareBadObjectError, it implies `device_id` is somehow
                 // dead, so its listener should receive nothing. It's ok to leave here.
                 assert!(status == NO_ERR || status == (kAudioHardwareBadObjectError as OSStatus));
-                // TODO: Destroy the aggregate device immediately if error is not
-                // kAudioHardwareBadObjectError. Otherwise the `devices_changed_callback` is able
-                // to touch the `cloned_condvar_pair` after it's freed.
                 return Err(Error::from(waiting_time));
             }
         }
@@ -370,15 +376,17 @@ impl AggregateDevice {
             _addresses: *const AudioObjectPropertyAddress,
             data: *mut c_void,
         ) -> OSStatus {
-            let pair = unsafe { &mut *(data as *mut Arc<(Mutex<AudioObjectID>, Condvar)>) };
-            let (lock, cvar) = &**pair;
-            let mut device = lock.lock().unwrap();
-            *device = id;
-            cvar.notify_one();
+            with_sync_callback_ptr(data, || {
+                let pair = unsafe { &*(data as *const (Mutex<AudioObjectID>, Condvar)) };
+                let (lock, cvar) = pair;
+                let mut device = lock.lock().unwrap();
+                *device = id;
+                cvar.notify_one();
+            });
             NO_ERR
         }
 
-        let status = remove_listener();
+        let status = cleanup();
         assert_eq!(status, NO_ERR);
         Ok(())
     }
diff --git a/third_party/rust/cubeb-coreaudio/src/backend/mod.rs b/third_party/rust/cubeb-coreaudio/src/backend/mod.rs
index 210a9f33e12..023a7210b65 100644
Loading diff…

Regression Test / PoC

shipped with the fix
diff --git a/third_party/rust/cubeb-coreaudio/src/backend/tests/mod.rs b/third_party/rust/cubeb-coreaudio/src/backend/tests/mod.rs
index 0c193d0dc8f..9406c9ecfa7 100644
--- a/third_party/rust/cubeb-coreaudio/src/backend/tests/mod.rs
+++ b/third_party/rust/cubeb-coreaudio/src/backend/tests/mod.rs
@@ -8,5 +8,6 @@ mod device_property;
 mod interfaces;
 mod manual;
 mod parallel;
+mod sync_callback;
 mod tone;
 mod utils;
diff --git a/third_party/rust/cubeb-coreaudio/src/backend/tests/sync_callback.rs b/third_party/rust/cubeb-coreaudio/src/backend/tests/sync_callback.rs
new file mode 100644
index 00000000000..6930dc7ecce
--- /dev/null
+++ b/third_party/rust/cubeb-coreaudio/src/backend/tests/sync_callback.rs
@@ -0,0 +1,136 @@
+// Copyright © 2026 Mozilla Foundation
+//
+// This program is made available under an ISC-style license.  See the
+// accompanying file LICENSE for details.
+
+use super::*;
+use std::sync::atomic::{AtomicBool, Ordering};
+use std::sync::Arc;
+
+// Test basic registration and unregistration
+#[test]
+fn test_sync_callback_register_unregister() {
+    let dummy_data = Box::new(42u32);
+    let ptr = Box::into_raw(dummy_data);
+    let ptr_usize = ptr as usize;
+
+    // Register the pointer
+    sync_callback_registry_register(ptr_usize);
+
+    // Verify the callback is called when registered
+    let called = Arc::new(AtomicBool::new(false));
+    let called_clone = called.clone();
+    with_sync_callback_ptr(ptr as *mut c_void, || {
+        called_clone.store(true, Ordering::SeqCst);
+    });
+    assert!(
+        called.load(Ordering::SeqCst),
+        "Callback should be called when pointer is registered"
+    );
+
+    // Unregister the pointer
+    sync_callback_registry_unregister(ptr_usize);
+
+    // Verify the callback is NOT called after unregistration
+    let called2 = Arc::new(AtomicBool::new(false));
+    let called2_clone = called2.clone();
+    with_sync_callback_ptr(ptr as *mut c_void, || {
+        called2_clone.store(true, Ordering::SeqCst);
+    });
+    assert!(
+        !called2.load(Ordering::SeqCst),
+        "Callback should NOT be called after unregistration"
+    );
+
+    // Clean up
+    unsafe { drop(Box::from_raw(ptr)) };
+}
+
+// Test that unregistered pointers don't trigger callbacks
+#[test]
+fn test_sync_callback_unregistered_pointer() {
+    let dummy_data = Box::new(100u32);
+    let ptr = Box::into_raw(dummy_data);
+
+    // Try to use callback without registration
+    let called = Arc::new(AtomicBool::new(false));
+    let called_clone = called.clone();
+    with_sync_callback_ptr(ptr as *mut c_void, || {
+        called_clone.store(true, Ordering::SeqCst);
+    });
+    assert!(
+        !called.load(Ordering::SeqCst),
+        "Callback should NOT be called for unregistered pointer"
+    );
+
+    // Clean up
+    unsafe { drop(Box::from_raw(ptr)) };
+}
+
+// Test multiple registrations don't cause issues
+#[test]
+fn test_sync_callback_multiple_pointers() {
+    let data1 = Box::new(1u32);
+    let ptr1 = Box::into_raw(data1);
+    let ptr1_usize = ptr1 as usize;
+
+    let data2 = Box::new(2u32);
+    let ptr2 = Box::into_raw(data2);
+    let ptr2_usize = ptr2 as usize;
+
+    // Register both pointers
+    sync_callback_registry_register(ptr1_usize);
+    sync_callback_registry_register(ptr2_usize);
+
+    // Both should work
+    let called1 = Arc::new(AtomicBool::new(false));
+    let called1_clone = called1.clone();
+    with_sync_callback_ptr(ptr1 as *mut c_void, || {
+        called1_clone.store(true, Ordering::SeqCst);
+    });
+    assert!(
+        called1.load(Ordering::SeqCst),
+        "First pointer callback should be called"
+    );
+
+    let called2 = Arc::new(AtomicBool::new(false));
+    let called2_clone = called2.clone();
+    with_sync_callback_ptr(ptr2 as *mut c_void, || {
+        called2_clone.store(true, Ordering::SeqCst);
+    });
+    assert!(
+        called2.load(Ordering::SeqCst),
+        "Second pointer callback should be called"
+    );
+
+    // Unregister first pointer
+    sync_callback_registry_unregister(ptr1_usize);
+
+    // First should not work, second should still work
+    let called1_after = Arc::new(AtomicBool::new(false));
+    let called1_after_clone = called1_after.clone();
+    with_sync_callback_ptr(ptr1 as *mut c_void, || {
+        called1_after_clone.store(true, Ordering::SeqCst);
+    });
+    assert!(
+        !called1_after.load(Ordering::SeqCst),
+        "First pointer callback should NOT be called after unregister"
+    );
+
+    let called2_after = Arc::new(AtomicBool::new(false));
+    let called2_after_clone = called2_after.clone();
+    with_sync_callback_ptr(ptr2 as *mut c_void, || {
+        called2_after_clone.store(true, Ordering::SeqCst);
+    });
+    assert!(
+        called2_after.load(Ordering::SeqCst),
+        "Second pointer callback should still be called"
+    );
+
+    // Clean up
+    sync_callback_registry_unregister(ptr2_usize);
+    unsafe {
+        drop(Box::from_raw(ptr1));
+        drop(Box::from_raw(ptr2));
+    };
+}
diff --git a/third_party/rust/unicode-ident/tests/fst/.gitignore b/third_party/rust/unicode-ident/tests/fst/.gitignore
deleted file mode 100644
index 0d101a4a953..00000000000
--- a/third_party/rust/unicode-ident/tests/fst/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-prop_list.rs
diff --git a/third_party/rust/wast/tests/.gitattributes b/third_party/rust/wast/tests/.gitattributes
deleted file mode 100644
index 75de48a520a..00000000000
--- a/third_party/rust/wast/tests/.gitattributes
+++ /dev/null
@@ -1 +0,0 @@
-parse-fail/newline-in-string.wat text eol=lf
diff --git a/third_party/rust/wast/tests/.gitignore b/third_party/rust/wast/tests/.gitignore
deleted file mode 100644
index 265315a8623..00000000000
--- a/third_party/rust/wast/tests/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-!*.wat
Loading diff…