← All issues

[9] FairPlay CDM MTE hardening

Severity: Medium | Component: FairPlay CDM implementation in WebCore | 62e4c75

Rated Medium because this is a hardening measure that removes a stepping stone in a multi-stage exploit chain — the commit explicitly states that heap-allocated StringImpl objects are exploitable via arbitrary decrement primitives in the GPU process, but exploitation requires the attacker to already possess such a primitive.

Use MAKE_STATIC_STRING_IMPL for the FairPlay keySystem string to place the StaticStringImpl in the __DATA section instead of on the heap. Heap-allocated StringImpl objects are not MTE-tagged, making them potentially exploitable via arbitrary decrement primitives in the GPU process.

Source/WebCore/platform/graphics/avfoundation/objc/CDMInstanceFairPlayStreamingAVFObjC.mm

const String& CDMInstanceFairPlayStreamingAVFObjC::keySystem() const
{
- static NeverDestroyed<String> keySystem { "com.apple.fps"_s };
- return keySystem;
+ static const NeverDestroyed<String> s_keySystem { MAKE_STATIC_STRING_IMPL("com.apple.fps") };
+ return s_keySystem;
}

The fix changes the static String construction from "com.apple.fps"_s (which produces a heap-allocated StringImpl wrapper) to MAKE_STATIC_STRING_IMPL("com.apple.fps") (which places the StaticStringImpl in the binary's __DATA section). The variable is also made const and renamed to s_keySystem.

Heap-allocated string metadata lacking MTE protection in a security-sensitive process, exploitable via arbitrary decrement primitives to corrupt reference counts.

MAKE_STATIC_STRING_IMPL is a WebKit macro that creates a StaticStringImpl in the binary's __DATA section at compile time. Unlike heap-allocated StringImpl, a StaticStringImpl has a special flag (s_refCountFlagIsStaticString) that causes the reference counting system to skip increment/decrement operations entirely — the object is never freed. ARM Memory Tagging Extension (MTE) is a hardware feature that tags heap pointers and their corresponding memory regions with 4-bit tags; accesses with mismatched tags fault. MTE protects heap allocations but does not apply to static data segments. The _s string literal suffix in WebKit creates a StringImpl via StringImplFromLiteral, which still results in a heap-allocated StringImpl wrapper. NeverDestroyed<T> prevents static destruction of its contained object.

Before the fix, CDMInstanceFairPlayStreamingAVFObjC::keySystem() constructed its static String using "com.apple.fps"_s, producing a heap-allocated StringImpl. As the commit message states, heap-allocated StringImpl objects are not protected by MTE tags. An attacker who already possesses an arbitrary decrement primitive in the GPU process could target the StringImpl's reference count field — decrementing it to zero would trigger a free while other references still exist, creating a use-after-free. By moving the string to static storage, the StaticStringImpl's refcount is effectively ignored, eliminating this exploitation target entirely.

🔒

Explores the exploitation model for heap-allocated string metadata in processes with limited memory tagging coverage

Subscribe to read more

🔒

Multiple hardening audit patterns identified across security-sensitive WebKit processes, with concrete search targets for similar gaps

Subscribe to read more