🤬
  • Added CVE-2021-30858 RCA

    Change-Id: Ia8626be5e5d2ace7e9297f336b4b1f3e1a531e6d
  • Loading...
  • Maddie Stone committed 3 years ago
    67fde24b
    1 parent f88a1455
  • ■ ■ ■ ■ ■ ■
    0day-RCAs/2021/CVE-2021-30858.md
     1 +# CVE-2021-30858: Use-after-free in WebKit
     2 +*Maddie Stone, Google Project Zero*
     3 + 
     4 +## The Basics
     5 + 
     6 +**Disclosure or Patch Date:** 13 September 2021
     7 + 
     8 +**Product:** Apple WebKit
     9 + 
     10 +**Advisory:** https://support.apple.com/en-us/HT212808
     11 + 
     12 +**Affected Versions:** pre-Safari 14.1.2, pre-iOS 14.8
     13 + 
     14 +**First Patched Version:** Safari 14.1.2, iOS 14.8
     15 + 
     16 +**Issue/Bug Report:** https://bugs.webkit.org/show_bug.cgi?id=229535
     17 + 
     18 +**Patch CL:** https://github.com/WebKit/WebKit/commit/fbf37d27e313d8d0a150a74cc8fab956eb7f3c59
     19 + 
     20 +**Bug-Introducing CL:** https://github.com/WebKit/WebKit/commit/d5dbfd02054e9f904b27224a598ca1bb8ded5f87
     21 + 
     22 +**Reporter(s):** Anonymous
     23 + 
     24 +## The Code
     25 + 
     26 +**Proof-of-concept:**
     27 + 
     28 +```javascript
     29 +var fontFace1 = new FontFace("font1", "", {});
     30 +var fontFaceSet = new FontFaceSet([fontFace1]);
     31 +fontFace1.family = "font2";
     32 +```
     33 + 
     34 +**Exploit sample:** N/A
     35 + 
     36 +**Did you have access to the exploit sample when doing the analysis?** No
     37 + 
     38 +## The Vulnerability
     39 + 
     40 +**Bug class:** Use-after-free
     41 + 
     42 +**Vulnerability details:**
     43 +The vulnerability is a use-after-free due to an unchecked `end()` iterator. There was an assert statement: `ASSERT(iterator != m_facesLookupTable.end());`, but `ASSERT`s don't do anything in release builds. Therefore, even if `iterator == m_facesLookupTable.end()` in the release build, nothing would happen and `iterator` would still be used.
     44 + 
     45 +https://github.com/WebKit/WebKit/blob/74bd0da94fa1d31a115bc4ee0e3927d8b2ea571e/Source/WebCore/css/CSSFontFaceSet.cpp#L223
     46 +```c++
     47 +void CSSFontFaceSet::removeFromFacesLookupTable(const CSSFontFace& face, const CSSValueList& familiesToSearchFor)
     48 +{
     49 + for (auto& item : familiesToSearchFor) {
     50 + String familyName = CSSFontFaceSet::familyNameFromPrimitive(downcast<CSSPrimitiveValue>(item.get()));
     51 + if (familyName.isEmpty())
     52 + continue;
     53 + 
     54 + auto iterator = m_facesLookupTable.find(familyName);
     55 + ASSERT(iterator != m_facesLookupTable.end());
     56 + bool found = false;
     57 + for (size_t i = 0; i < iterator->value.size(); ++i) {
     58 + if (iterator->value[i].ptr() == &face) {
     59 + found = true;
     60 + iterator->value.remove(i);
     61 + break;
     62 + }
     63 + }
     64 + ASSERT_UNUSED(found, found);
     65 + if (!iterator->value.size())
     66 + m_facesLookupTable.remove(iterator);
     67 + }
     68 +}
     69 + 
     70 +```
     71 + 
     72 +In `FontFaceSet` a `FontFace` is not added to the faces lookup table in `addToFacesLookupTable` if the font has already been deemed to be invalid. However, `removeFromFacesLookupTable` would still attempt to remove the font, leading to the use-after-free.
     73 + 
     74 +**Patch analysis:**
     75 + 
     76 +The patch changes the `ASSERT` to an if clause. The function will return if `iterator == m_facesLookupTable.end()`, since the item it wishes to remove is not found in the table.
     77 + 
     78 +**Thoughts on how this vuln might have been found _(fuzzing, code auditing, variant analysis, etc.)_:**
     79 + 
     80 +It seems equally likely that this vulnerability could have been found via fuzzing or code auditing. The trigger is only 3 lines long so it seems like that a fuzzer could have triggered the vulnerability.
     81 + 
     82 +**(Historical/present/future) context of bug:**
     83 + 
     84 +## The Exploit
     85 + 
     86 +(The terms *exploit primitive*, *exploit strategy*, *exploit technique*, and *exploit flow* are [defined here](https://googleprojectzero.blogspot.com/2020/06/a-survey-of-recent-ios-kernel-exploits.html).)
     87 + 
     88 +**Exploit strategy (or strategies):**
     89 + 
     90 +N/A no access to exploit sample
     91 + 
     92 +**Exploit flow:**
     93 + 
     94 +**Known cases of the same exploit flow:**
     95 + 
     96 +**Part of an exploit chain?**
     97 + 
     98 +## The Next Steps
     99 + 
     100 +### Variant analysis
     101 + 
     102 +**Areas/approach for variant analysis (and why):**
     103 + 
     104 +* Look for other places where there is an `ASSERT` checking that the result of `find() != end()`, but the result can still be used even if that `ASSERT` fails.
     105 +* Fuzz the `FontFace` components.
     106 + 
     107 +**Found variants:** N/A
     108 + 
     109 +### Structural improvements
     110 + 
     111 +What are structural improvements such as ways to kill the bug class, prevent the introduction of this vulnerability, mitigate the exploit flow, make this type of vulnerability harder to exploit, etc.?
     112 + 
     113 +**Ideas to kill the bug class:**
     114 + 
     115 +* Change any `ASSERT` statements that verifies that a value doesn't equal `end()` to `RELEASE_ASSERT` statements. These situations should be caught prior to the `RELEASE_ASSERT`, but at least if it happens to not be, the `RELEASE_ASSERT` would prevent exploitation.
     116 +* Memory-safe languages. This is a memory corruption bug so switching to a memory safe language would also prevent this type of vulnerability.
     117 + 
     118 +**Ideas to mitigate the exploit flow:**
     119 + 
     120 +N/A
     121 + 
     122 +**Other potential improvements:**
     123 + 
     124 +### 0-day detection methods
     125 + 
     126 +There doesn't seem to be any really great options for detection due to the trigger for the vulnerability not doing anything that out of the ordinary other than running the samples in a debug WebKit build.
     127 + 
     128 +## Other References
     129 + 
Please wait...
Page is in error, reload to recover