Feb 16, 2026·7 min read·6 visits
Samsung's HDCP DRM component, running in the secure TrustZone, failed to validate who was talking to it. Local attackers could use this to send privileged commands, corrupt secure memory, and escalate from a basic user to Root.
A critical privilege escalation vulnerability within Samsung's HDCP trustlet allows a local attacker to bypass Trusted Execution Environment (TEE) boundaries. By exploiting improper access controls in the communication interface between the Android kernel and the Secure World, a standard shell user can execute privileged commands, leading to total device compromise and root access.
In the world of Android security, the TrustZone (or TEE - Trusted Execution Environment) is the Holy of Holies. It is a hardware-isolated area of the processor where the most sensitive operations happen: biometric authentication, payment processing, and cryptographic key storage. The code running here, known as 'trustlets', operates with privileges that eclipse even the Android kernel (Ring 0). If you can compromise a trustlet, the entire security model of the device collapses like a house of cards in a hurricane.
Enter HDCP (High-bandwidth Digital Content Protection). It's that annoying DRM protocol that stops you from recording Netflix streams. To keep the content encryption keys safe, the HDCP logic runs as a trustlet inside the Samsung TEE. While DRM is generally boring, for a hacker, this component is a gold mine. Why? Because it exposes a communication interface to the 'Normal World' (the Android OS). And as history has taught us repeatedly, wherever two worlds meet, there is friction—and usually, a vulnerability.
CVE-2025-20936 isn't just a bug; it's a structural failure in how that communication was policed. Samsung's implementation created a bridge for video data, but they forgot to put a guard at the tollbooth. This vulnerability allows a lowly shell user to walk right into the most secure room in the building and start issuing orders.
The vulnerability is a classic case of CWE-285: Improper Access Control. When a user-space application needs to talk to a trustlet, it can't just call it directly. It has to go through a kernel driver (often /dev/qseecom or a specific /dev/tz_hdcp node). This driver takes the request, packages it, and utilizes the Secure Monitor Call (SMC) instruction to context-switch into the Secure World.
The flaw here is embarrassingly simple: the interface failed to check who was knocking. In a proper implementation, the kernel driver or the trustlet itself should verify the User ID (UID) of the calling process. Only trusted system services, like mediaserver or drmserver, should be allowed to speak to the HDCP trustlet. However, the affected code treated a request from a random shell user (UID 2000) with the same respect as a request from the system itself.
This lack of 'Access Control Lists' (ACLs) meant that the attack surface was wide open. A local attacker didn't need to find a complex memory corruption bug in the kernel first; they just needed to ask the trustlet nicely. By sending specific IOCTL commands that were intended for privileged initialization or key management, the attacker could trick the trustlet into performing operations that it assumed were authorized. It's the digital equivalent of walking into a bank vault because the security guard assumed anyone wearing a shirt and shoes was an employee.
Since the actual source code for Samsung's proprietary trustlets is closed (and usually only seen via Ghidra/IDA Pro reverse engineering), we can visualize the logic failure through a reconstruction of the vulnerable driver handler. The issue lies in the ioctl handler responsible for dispatching commands to the TEE.
Vulnerable Logic (Pseudo-code):
// The Vulnerable IOCTL Handler
long hdcp_driver_ioctl(struct file *file, unsigned int cmd, unsigned long arg) {
struct hdcp_req_data data;
// 1. Copy data from user space
if (copy_from_user(&data, (void __user *)arg, sizeof(data)))
return -EFAULT;
// 2. THE MISSING CHECK
// The code proceeds to send the command to the Secure World
// regardless of current_uid().
// 3. Dispatch to TrustZone
return send_cmd_to_trustlet(data.cmd_id, data.payload);
}In the patched version, Samsung had to explicitly enforce caller identity. The fix likely introduces a check against a whitelist of allowed UIDs (like AID_MEDIA or AID_SYSTEM) or verifies the process context capabilities before allowing the SMC call to proceed.
Patched Logic (Pseudo-code):
// The Fixed IOCTL Handler
long hdcp_driver_ioctl(struct file *file, unsigned int cmd, unsigned long arg) {
// 1. SECURITY CHECK: Is the caller authorized?
// Only allow specific system UIDs to touch this interface
uid_t uid = current_uid().val;
if (uid != AID_MEDIA && uid != AID_SYSTEM && uid != AID_ROOT) {
pr_err("HDCP: Unauthorized access attempt by UID %d\n", uid);
return -EPERM; // Access Denied
}
// ... proceed with copy_from_user and TrustZone dispatch ...
}By omitting that simple if statement, the driver effectively exposed the raw Secure World API to every app installed on the device.
Exploiting this requires a bit of finesse, but the path is clear. The goal is Local Privilege Escalation (LPE). The attacker starts with shell access—perhaps achieved via adb shell or by sideloading a malicious app. The target is the exposed /dev/ node associated with the HDCP trustlet.
Phase 1: The Setup
The exploit opens a file descriptor to the vulnerable driver. Since there are no permission checks, open("/dev/tz_hdcp", O_RDWR) succeeds even from an unprivileged context.
Phase 2: The Payload The attacker crafts a specific IOCTL structure. This structure contains a command ID that the trustlet interprets as a "write" or "config" operation. Because the trustlet runs in the Secure World, it has a view of all physical memory, including the Normal World kernel memory. The exploit leverages a specific command (Command Misuse) that triggers the trustlet to write data to a memory location specified by the attacker (or implied by the command context).
Phase 3: The Execution
By manipulating the arguments passed to the trustlet, the attacker coerces the Trusted Application to overwrite the cred structure (credentials) of the attacking process in the Linux kernel memory. This is the 'god mode' toggle.
Once the cred structure is overwritten to effectively uid=0, gid=0, the attacker has full root access to the Android system, bypassing the sandbox entirely.
A vulnerability like CVE-2025-20936 is a nightmare scenario for device security. It breaks the fundamental promise of the Trusted Execution Environment. TEEs are designed to protect secrets even if the main OS is compromised, but in this case, the TEE itself is the weapon used to compromise the OS.
With root access gained via this exploit, an attacker can:
The fact that this was reachable from an unprivileged shell makes it a prime candidate for spyware chains or "one-click" root solutions. It demonstrates that complexity (adding HDCP DRM) is the enemy of security.
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
Samsung Android 13 Samsung | < SMR Apr-2025 Release 1 | SMR Apr-2025 Release 1 |
Samsung Android 14 Samsung | < SMR Apr-2025 Release 1 | SMR Apr-2025 Release 1 |
Samsung Android 15 Samsung | < SMR Apr-2025 Release 1 | SMR Apr-2025 Release 1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-285 |
| Attack Vector | Local (AV:L) |
| CVSS | 8.8 (Critical) |
| Privileges Required | Low (PR:L) |
| Impact | Confidentiality, Integrity, Availability (High) |
| Exploit Status | Poc / Internal Research |
The application does not perform or incorrectly performs an authorization check when an actor attempts to access a resource or perform an action.