AddressSanitizer: heap-buffer-overflow [@ __asan_memcpy] with READ of size 16 via ClearKeyUtils::DecryptAES
Categories
(Core :: Audio/Video: GMP, defect, P1)
Tracking
()
People
(Reporter: jkratzer, Assigned: pehrsons)
References
(Regression)
Details
(6 keywords, Whiteboard: [bugmon:bisected,confirmed][adv-main148+] [adv-esr115.33+] [adv-esr140.8+])
Attachments
(3 files, 8 external files, 2 obsolete files)
Reproduced on mozilla-central rev 57fbf639ea5b (built with: --enable-address-sanitizer --enable-fuzzing).
Testcase can be reproduced using the following commands:
$ pip install fuzzfetch grizzly-framework pipx --upgrade
$ python -m pipx ensurepath
$ fuzzfetch --build 57fbf639ea5b --asan --fuzzing -n firefox
$ grizzly-replay-bugzilla ./firefox/firefox <bugid>
AddressSanitizer: heap-buffer-overflow [@ __asan_memcpy] with READ of size 16
=================================================================
==2542561==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x734392fed311 at pc 0x5989a24f328b bp 0x7ffc8c8db0a0 sp 0x7ffc8c8da860
READ of size 16 at 0x734392fed311 thread T0
#0 0x5989a24f328a in __asan_memcpy _asan_rtl_:3
#1 0x7723937cd87b in SECITEM_CopyItem_Util /security/nss/lib/util/secitem.c:271:9
#2 0x732392f90bd6 in pk11_ImportSymKeyWithTempl /security/nss/lib/pk11wrap/pk11skey.c:456:9
#3 0x732392f909cd in PK11_ImportSymKey /security/nss/lib/pk11wrap/pk11skey.c:508:14
#4 0x732366d2132c in ClearKeyUtils::DecryptAES(std::vector<unsigned char, std::allocator<unsigned char>> const&, std::vector<unsigned char, std::allocator<unsigned char>>&, std::vector<unsigned char, std::allocator<unsigned char>>&) /dom/media/eme/clearkey/ClearKeyUtils.cpp:201:21
#5 0x732366d1ffc6 in ClearKeyDecryptor::Decrypt(unsigned char*, unsigned int, CryptoMetaData const&) /dom/media/eme/clearkey/ClearKeyDecryptionManager.cpp:271:8
#6 0x732366d2d8ce in Decrypt /dom/media/eme/clearkey/ClearKeyDecryptionManager.cpp:151:41
#7 0x732366d2d8ce in ClearKeySessionManager::Decrypt(cdm::InputBuffer_2 const&, cdm::DecryptedBlock*) /dom/media/eme/clearkey/ClearKeySessionManager.cpp:559:34
#8 0x732375df2486 in mozilla::gmp::ChromiumCDMChild::RecvDecrypt(unsigned int const&, mozilla::gmp::CDMInputBuffer const&) /dom/media/gmp/ChromiumCDMChild.cpp:644:30
#9 0x732375ed68c2 in mozilla::gmp::PChromiumCDMChild::OnMessageReceived(IPC::Message const&) /builds/worker/workspace/obj-build/ipc/ipdl/PChromiumCDMChild.cpp:1337:52
#10 0x732375eefbe4 in mozilla::gmp::PGMPContentChild::OnMessageReceived(IPC::Message const&) /builds/worker/workspace/obj-build/ipc/ipdl/PGMPContentChild.cpp:262:32
#11 0x73236f766515 in mozilla::ipc::MessageChannel::DispatchAsyncMessage(mozilla::ipc::ActorLifecycleProxy*, IPC::Message const&) /ipc/glue/MessageChannel.cpp:1793:25
#12 0x73236f762a09 in mozilla::ipc::MessageChannel::DispatchMessage(mozilla::ipc::ActorLifecycleProxy*, std::unique_ptr<IPC::Message, std::default_delete<IPC::Message>>) /ipc/glue/MessageChannel.cpp:1719:9
#13 0x73236f763827 in mozilla::ipc::MessageChannel::RunMessage(mozilla::ipc::ActorLifecycleProxy*, mozilla::ipc::MessageChannel::MessageTask&) /ipc/glue/MessageChannel.cpp:1508:3
#14 0x73236f764d43 in mozilla::ipc::MessageChannel::MessageTask::Run() /ipc/glue/MessageChannel.cpp:1610:14
#15 0x73236dffe95a in mozilla::RunnableTask::Run() /xpcom/threads/TaskController.cpp:705:16
#16 0x73236dfedd9b in mozilla::TaskController::RunTask(mozilla::Task*) /xpcom/threads/TaskController.cpp:196:19
#17 0x73236dff509d in mozilla::TaskController::DoExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) /xpcom/threads/TaskController.cpp:1325:20
#18 0x73236dff2b78 in mozilla::TaskController::ExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) /xpcom/threads/TaskController.cpp:1148:15
#19 0x73236dff3196 in mozilla::TaskController::ProcessPendingMTTask(bool) /xpcom/threads/TaskController.cpp:641:36
#20 0x73236e013f11 in operator() /xpcom/threads/TaskController.cpp:333:37
#21 0x73236e013f11 in mozilla::detail::RunnableFunction<mozilla::TaskController::TaskController()::$_0>::Run() /xpcom/threads/nsThreadUtils.h:549:5
#22 0x73236e034ffa in nsThread::ProcessNextEvent(bool, bool*) /xpcom/threads/nsThread.cpp:1168:16
#23 0x73236e03e1f9 in NS_ProcessNextEvent(nsIThread*, bool) /xpcom/threads/nsThreadUtils.cpp:461:10
#24 0x73236f76f14e in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /ipc/glue/MessagePump.cpp:85:21
#25 0x73236f64df04 in RunInternal /ipc/chromium/src/base/message_loop.cc:373:10
#26 0x73236f64df04 in RunHandler /ipc/chromium/src/base/message_loop.cc:366:3
#27 0x73236f64df04 in MessageLoop::Run() /ipc/chromium/src/base/message_loop.cc:348:3
#28 0x732379094f46 in nsBaseAppShell::Run() /widget/nsBaseAppShell.cpp:152:27
#29 0x73237927899b in nsAppShell::Run() /widget/gtk/nsAppShell.cpp:555:33
#30 0x73237b2e8cfd in XRE_RunAppShell() /toolkit/xre/nsEmbedFunctions.cpp:652:20
#31 0x73236f64df04 in RunInternal /ipc/chromium/src/base/message_loop.cc:373:10
#32 0x73236f64df04 in RunHandler /ipc/chromium/src/base/message_loop.cc:366:3
#33 0x73236f64df04 in MessageLoop::Run() /ipc/chromium/src/base/message_loop.cc:348:3
#34 0x73237b2e7c4c in XRE_InitChildProcess(int, char**, XREChildData const*) /toolkit/xre/nsEmbedFunctions.cpp:590:34
#35 0x5989a253a1ea in main /browser/app/nsBrowserApp.cpp:465:22
#36 0x772393e2a1c9 in __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#37 0x772393e2a28a in __libc_start_main ./csu/../csu/libc-start.c:360:3
#38 0x5989a24541a8 in _start ??:0:0
0x734392fed311 is located 0 bytes after 1-byte region [0x734392fed310,0x734392fed311)
allocated by thread T0 here:
#0 0x5989a24f5544 in __interceptor_malloc _asan_rtl_:3
#1 0x5989a254a615 in moz_xmalloc /memory/mozalloc/mozalloc.cpp:51:15
#2 0x732366d206a0 in operator new /builds/worker/workspace/obj-build/dist/include/mozilla/cxxalloc.h:33:10
#3 0x732366d206a0 in allocate /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/ext/new_allocator.h:121:27
#4 0x732366d206a0 in allocate /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/allocator.h:181:32
#5 0x732366d206a0 in allocate /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/alloc_traits.h:460:20
#6 0x732366d206a0 in _M_allocate /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/stl_vector.h:346:20
#7 0x732366d206a0 in _M_allocate_and_copy<__gnu_cxx::__normal_iterator<const unsigned char *, std::vector<unsigned char, std::allocator<unsigned char> > > > /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/stl_vector.h:1511:29
#8 0x732366d206a0 in std::vector<unsigned char, std::allocator<unsigned char>>::operator=(std::vector<unsigned char, std::allocator<unsigned char>> const&) /builds/worker/fetches/sysroot-x86_64-linux-gnu/usr/lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/vector.tcc:226:24
#9 0x732366d299d5 in InitKey /dom/media/eme/clearkey/ClearKeyDecryptionManager.cpp:165:57
#10 0x732366d299d5 in InitKey /dom/media/eme/clearkey/ClearKeyDecryptionManager.cpp:109:26
#11 0x732366d299d5 in ClearKeySessionManager::UpdateSession(unsigned int, char const*, unsigned int, unsigned char const*, unsigned int) /dom/media/eme/clearkey/ClearKeySessionManager.cpp:350:25
#12 0x732375df1583 in mozilla::gmp::ChromiumCDMChild::RecvUpdateSession(unsigned int const&, nsTSubstring<char> const&, nsTArray<unsigned char>&&) /dom/media/gmp/ChromiumCDMChild.cpp:495:11
#13 0x732375ed5e32 in mozilla::gmp::PChromiumCDMChild::OnMessageReceived(IPC::Message const&) /builds/worker/workspace/obj-build/ipc/ipdl/PChromiumCDMChild.cpp:1125:52
#14 0x732375eefbe4 in mozilla::gmp::PGMPContentChild::OnMessageReceived(IPC::Message const&) /builds/worker/workspace/obj-build/ipc/ipdl/PGMPContentChild.cpp:262:32
#15 0x73236f766515 in mozilla::ipc::MessageChannel::DispatchAsyncMessage(mozilla::ipc::ActorLifecycleProxy*, IPC::Message const&) /ipc/glue/MessageChannel.cpp:1793:25
#16 0x73236f762a09 in mozilla::ipc::MessageChannel::DispatchMessage(mozilla::ipc::ActorLifecycleProxy*, std::unique_ptr<IPC::Message, std::default_delete<IPC::Message>>) /ipc/glue/MessageChannel.cpp:1719:9
#17 0x73236f763827 in mozilla::ipc::MessageChannel::RunMessage(mozilla::ipc::ActorLifecycleProxy*, mozilla::ipc::MessageChannel::MessageTask&) /ipc/glue/MessageChannel.cpp:1508:3
#18 0x73236f764d43 in mozilla::ipc::MessageChannel::MessageTask::Run() /ipc/glue/MessageChannel.cpp:1610:14
#19 0x73236dffe95a in mozilla::RunnableTask::Run() /xpcom/threads/TaskController.cpp:705:16
#20 0x73236dfedd9b in mozilla::TaskController::RunTask(mozilla::Task*) /xpcom/threads/TaskController.cpp:196:19
#21 0x73236dff509d in mozilla::TaskController::DoExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) /xpcom/threads/TaskController.cpp:1325:20
#22 0x73236dff2b78 in mozilla::TaskController::ExecuteNextTaskOnlyMainThreadInternal(mozilla::detail::BaseAutoLock<mozilla::Mutex&> const&) /xpcom/threads/TaskController.cpp:1148:15
#23 0x73236dff3196 in mozilla::TaskController::ProcessPendingMTTask(bool) /xpcom/threads/TaskController.cpp:641:36
#24 0x73236e013f34 in operator() /xpcom/threads/TaskController.cpp:336:37
#25 0x73236e013f34 in mozilla::detail::RunnableFunction<mozilla::TaskController::TaskController()::$_1>::Run() /xpcom/threads/nsThreadUtils.h:549:5
#26 0x73236e034ffa in nsThread::ProcessNextEvent(bool, bool*) /xpcom/threads/nsThread.cpp:1168:16
#27 0x73236e03e1f9 in NS_ProcessNextEvent(nsIThread*, bool) /xpcom/threads/nsThreadUtils.cpp:461:10
#28 0x73236f76f143 in mozilla::ipc::MessagePump::Run(base::MessagePump::Delegate*) /ipc/glue/MessagePump.cpp:107:5
#29 0x73236f64df04 in RunInternal /ipc/chromium/src/base/message_loop.cc:373:10
#30 0x73236f64df04 in RunHandler /ipc/chromium/src/base/message_loop.cc:366:3
#31 0x73236f64df04 in MessageLoop::Run() /ipc/chromium/src/base/message_loop.cc:348:3
#32 0x732379094f46 in nsBaseAppShell::Run() /widget/nsBaseAppShell.cpp:152:27
#33 0x73237927899b in nsAppShell::Run() /widget/gtk/nsAppShell.cpp:555:33
#34 0x73237b2e8cfd in XRE_RunAppShell() /toolkit/xre/nsEmbedFunctions.cpp:652:20
#35 0x73236f64df04 in RunInternal /ipc/chromium/src/base/message_loop.cc:373:10
#36 0x73236f64df04 in RunHandler /ipc/chromium/src/base/message_loop.cc:366:3
#37 0x73236f64df04 in MessageLoop::Run() /ipc/chromium/src/base/message_loop.cc:348:3
#38 0x73237b2e7c4c in XRE_InitChildProcess(int, char**, XREChildData const*) /toolkit/xre/nsEmbedFunctions.cpp:590:34
#39 0x5989a253a1ea in main /browser/app/nsBrowserApp.cpp:465:22
#40 0x772393e2a1c9 in __libc_start_call_main ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
#41 0x772393e2a28a in __libc_start_main ./csu/../csu/libc-start.c:360:3
#42 0x5989a24541a8 in _start ??:0:0
SUMMARY: AddressSanitizer: heap-buffer-overflow (/home/jkratzer/builds/m-c-20260205090734-fuzzing-asan-opt/firefox+0x16d28a) (BuildId: 063d602c62d2807ca3aaf7e336687b79450a1eb3)
Shadow bytes around the buggy address:
0x734392fed080: fa fa fd fa fa fa fd fa fa fa fd fa fa fa fd fd
0x734392fed100: fa fa fd fd fa fa fd fd fa fa 00 00 fa fa fd fd
0x734392fed180: fa fa fd fd fa fa 00 00 fa fa fd fd fa fa fd fd
0x734392fed200: fa fa fd fd fa fa fd fd fa fa fd fd fa fa fd fa
0x734392fed280: fa fa fd fd fa fa fd fa fa fa fd fd fa fa fd fa
=>0x734392fed300: fa fa[01]fa fa fa 00 00 fa fa fd fd fa fa 00 04
0x734392fed380: fa fa 00 04 fa fa 00 00 fa fa 00 00 fa fa 00 00
0x734392fed400: fa fa 04 fa fa fa 04 fa fa fa 00 00 fa fa 00 00
0x734392fed480: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x734392fed500: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x734392fed580: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
==2542561==ABORTING
| Reporter | ||
Comment 1•9 months ago
|
||
| Reporter | ||
Comment 2•9 months ago
|
||
| Reporter | ||
Comment 3•9 months ago
|
||
Updated•9 months ago
|
Updated•9 months ago
|
Comment 4•9 months ago
|
||
It looks like this is doing a memcpy of this keyItem thing, so maybe CENC_KEY_LEN is larger than the length of aKey? I dunno why the length is hard coded like that.
SECItem keyItem = {siBuffer, (unsigned char*)aKey.data(), CENC_KEY_LEN};
PK11SymKey* key = PK11_ImportSymKey(slot, CKM_AES_CTR, PK11_OriginUnwrap,
CKA_ENCRYPT, &keyItem, nullptr);
Comment 5•9 months ago
|
||
Verified bug as reproducible on mozilla-central 20260205213633-279b57ef4bf0.
The bug appears to have been introduced in the following build range:
Start: 34544a375cd51e0499900e6e49c6b7148b35725d (20250221000500)
End: 6f6056944d37ddf15a3ef67de808de0ba7a38a43 (20250221015358)
Pushlog: https://hg.mozilla.org/integration/autoland/pushloghtml?fromchange=34544a375cd51e0499900e6e49c6b7148b35725d&tochange=6f6056944d37ddf15a3ef67de808de0ba7a38a43
| Assignee | ||
Comment 6•9 months ago
|
||
Trying to reproduce, I am hitting this assert(aKey.size() == CENC_KEY_LEN);. This is gated on NDEBUG so doesn't apply in non-debug builds.
In non-debug, aIV has size 16 as expected, aKey has size 1, which we use for SECItem keyItem = {siBuffer, (unsigned char*)aKey.data(), CENC_KEY_LEN}. keyItem is then the from here and we end up reading out of bounds.
I doubt this is linux-only.
Bug 1861016 fixed the same type of issue for DecryptCbcs but for some reason didn't cover DecryptAES. I'll employ the same fix here.
FWIW passing on the real key length 1 seems to work as well. ASAN reports no issues and the testcase passes. The log shows [Child 1212766, MediaDecoderStateMachine #1] WARNING: Decoder=7924a4042080 Decode error: NS_ERROR_DOM_MEDIA_FATAL_ERR (0x806e0005) - void mozilla::EMEDecryptor::Decrypted(const DecryptResult &): decrypted.mStatus=1: file /home/apehrson/dev/firefox/dom/media/MediaDecoderStateMachineBase.cpp:168 -- as it did with the GMP process crash too.
| Assignee | ||
Comment 7•9 months ago
|
||
I believe bug 1983381 describes the same failure mode, without ASAN.
| Assignee | ||
Comment 8•9 months ago
|
||
| Assignee | ||
Comment 9•9 months ago
|
||
Comment 10•9 months ago
|
||
Based on comment #5, this bug contains a bisection range found by bugmon. However, the Regressed by field is still not filled.
:pehrsons, if possible, could you fill the Regressed by field and investigate this regression?
For more information, please visit BugBot documentation.
| Assignee | ||
Comment 11•9 months ago
|
||
Maybe something in that range enabled the particular path used to trigger the bug? The root cause stems from the original Clearkey code, bug 1044742.
Comment 12•9 months ago
|
||
The code was using CENC_KEY_LEN (16) as a hardcoded length when creating
the SECItem for the key, but aKey could be smaller, causing a heap buffer
overflow when NSS attempted to copy the key data. This adds validation
matching the fix applied to DecryptCbcs in bug 1861016.
Updated•9 months ago
|
Updated•9 months ago
|
Updated•9 months ago
|
Comment 13•9 months ago
|
||
Updated•9 months ago
|
Comment 14•9 months ago
|
||
https://hg.mozilla.org/mozilla-central/rev/4d10e6d69414
https://hg.mozilla.org/mozilla-central/rev/ecc5082da209
Updated•8 months ago
|
Comment 15•8 months ago
|
||
:pehrsons, please add beta and ESR115/ESR140 uplift requests.
ESR115/ESR140 will need a rebased patch
https://wiki.mozilla.org/Release_Management/Requesting_an_Uplift#Manual_Cherry-Pick_(Recommended_if_Conflicts_Are_Likely)
| Assignee | ||
Comment 16•8 months ago
|
||
Original Revision: https://phabricator.services.mozilla.com/D282157
Updated•8 months ago
|
| Assignee | ||
Comment 17•8 months ago
|
||
Original Revision: https://phabricator.services.mozilla.com/D282158
Updated•8 months ago
|
| Assignee | ||
Comment 18•8 months ago
|
||
Original Revision: https://phabricator.services.mozilla.com/D282157
Updated•8 months ago
|
| Assignee | ||
Comment 19•8 months ago
|
||
Original Revision: https://phabricator.services.mozilla.com/D282158
Updated•8 months ago
|
| Assignee | ||
Comment 20•8 months ago
|
||
Original Revision: https://phabricator.services.mozilla.com/D282157
Updated•8 months ago
|
Comment 21•8 months ago
|
||
firefox-beta Uplift Approval Request
- User impact if declined: sec-moderate, GMP process heap-buffer-overflow READ at will
- Code covered by automated testing: yes
- Fix verified in Nightly: no
- Needs manual QE test: no
- Steps to reproduce for manual QE testing:
- Risk associated with taking this patch: low
- Explanation of risk level: Trivial change
- String changes made/needed: None
- Is Android affected?: no
| Assignee | ||
Comment 22•8 months ago
|
||
Original Revision: https://phabricator.services.mozilla.com/D282158
Comment 23•8 months ago
|
||
firefox-esr115 Uplift Approval Request
- User impact if declined: sec-moderate, GMP process heap-buffer-overflow READ at will
- Code covered by automated testing: yes
- Fix verified in Nightly: no
- Needs manual QE test: no
- Steps to reproduce for manual QE testing:
- Risk associated with taking this patch: low
- Explanation of risk level: Trivial change
- String changes made/needed: None
- Is Android affected?: no
Comment 24•8 months ago
|
||
firefox-esr140 Uplift Approval Request
- User impact if declined: sec-moderate, GMP process heap-buffer-overflow READ at will
- Code covered by automated testing: yes
- Fix verified in Nightly: no
- Needs manual QE test: no
- Steps to reproduce for manual QE testing:
- Risk associated with taking this patch: low
- Explanation of risk level: Trivial change
- String changes made/needed: None
- Is Android affected?: no
| Assignee | ||
Updated•8 months ago
|
Comment 25•8 months ago
|
||
Verified bug as fixed on rev mozilla-central 20260211162125-7df40d9149a3.
Removing bugmon keyword as no further action possible. Please review the bug and re-add the keyword for further analysis.
Updated•8 months ago
|
Updated•8 months ago
|
Updated•8 months ago
|
Comment 26•8 months ago
|
||
| uplift | ||
Updated•8 months ago
|
Updated•8 months ago
|
Updated•8 months ago
|
Comment 27•8 months ago
|
||
| uplift | ||
Updated•8 months ago
|
Updated•8 months ago
|
Updated•8 months ago
|
Comment 28•8 months ago
|
||
| uplift | ||
Updated•8 months ago
|
Comment 29•8 months ago
|
||
Updated•8 months ago
|
Updated•8 months ago
|
Updated•8 months ago
|
Updated•8 months ago
|
Updated•6 months ago
|
Updated•1 month ago
|
Description
•