Samsung OEM-unlock gate anatomy (One UI 8.x era)
Everything between "flip the toggle" and "the bootloader unlocks" — from decompiling
services.jar on a 2026 Samsung flagship. Device-agnostic; applies to any recent
Samsung Android build.
The three layers
1. The service backend
OemLockService picks its backend at boot:
- a vendor IOemLock HAL exists → HAL backend (older devices / some vendors),
- otherwise → PersistentDataBlockLock — the flag lives in the persistent
partition (ro.frp.pst), managed by PersistentDataBlockService.
Modern Samsungs (Snapdragon flagships) use the PDB backend: the "OEM unlock" toggle state is software storage on a raw partition, not a hardware switch.
2. The gates (all software)
java
// PersistentDataBlockLock
isOemUnlockAllowedByCarrier() =
!UserManager.hasUserRestriction("no_oem_unlock", USER_SYSTEM);
setOemUnlockAllowedByCarrier(z, sig) { // "Signature provided but is not being used" <-- carrier sig is IGNORED setUserRestriction("no_oem_unlock", !z, USER_SYSTEM); if (!z && flashIsLocked) pdb.setOemUnlockEnabled(false); // side effect! }
// OemLockService.setOemUnlockAllowedByUser(z)
// gate 1: hasUserRestriction("no_factory_reset") -> "Admin does not allow OEM unlock"
// gate 2: !isOemUnlockAllowedByCarrier() -> "Carrier does not allow OEM unlock"
// then: setOemUnlockAllowedByDevice(z) -> writes the PDB flag
`````
Key insights:
- **"Carrier does not allow OEM unlock" is a user restriction** (no_oem_unlock), not a
SIM/carrier/signature check. The carrier signature parameter is ignored entirely.
- **The PDB setter's own gate isno_factory_reset** ("OEM unlock is disallowed by
user restriction: no_factory_reset") plus FRP-inactive.
- **The flag is the LAST BYTE of the persistent partition**, with a SHA-256 digest at
offset 0 (doSetOemUnlockEnabledLocked+computeAndWriteDigestLocked`).
3. The consumer (where it usually dies)
On older devices the abl reads the flag and performs the unlock. On newer bit-rev
firmware (Samsung's 2025-2026 "no more bootloader unlock" policy) the abl does not
read it at all — the toggle disappears from Settings and even a root-written flag is
ignored. Verified empirically on bit-4 SM-F956B: flag written as uid 0 with valid
digest, all service getters TRUE → reboot → ro.boot.other.locked=1,
vbmeta.device_state=locked. The bootloader was stripped, not the UI.
Transaction map (service call oem_lock N)
| tx | method | notes |
|---|---|---|
| 1 | getLockName | |
| 2 | setOemUnlockAllowedByCarrier(bool, byte[]) | signature ignored |
| 3 | isOemUnlockAllowedByCarrier | = !no_oem_unlock |
| 4 | setOemUnlockAllowedByUser(bool) | both gates + writes flag |
| 5 | isOemUnlockAllowedByUser | = PDB flag |
| 6 | isOemUnlockAllowed | carrier && device |
| 7 | isDeviceOemUnlocked | = ro.boot.flash.locked == "0" |
The classic pitfall
A no-arg probe like service call oem_lock 2 (meant as a "getter") actually calls
setCarrier(false, null) → sets no_oem_unlock=true and clears the PDB flag
(the flash-locked side effect). This self-inflicts the exact "Carrier does not allow
OEM unlock" refusal everyone then tries to debug. Always pass the boolean:
service call oem_lock 2 i32 1 to clear the restriction.
Practical facts
cmd user set-user-restrictiondidn't exist as expected on the tested build — the oem_lock transactions are the reliable way to flip these restrictions with uid 0.- Kernel-context root shells can't reach servicemanager: use
runcon u:r:shell:s0 sh -c 'service call …'(uid stays 0, lookups work). - The PDB flag can be TRUE from the factory on some firmwares — software "allowed" while the bootloader refuses. Don't assume a TRUE getter means anything about the bootloader.