First handset with MTE available on the market
By Mark Model, Google Mission Zero
Introduction
It is lastly time for me to satisfy a long-standing promise. Since I first heard about ARM’s Reminiscence Tagging Extensions, I’ve mentioned (to far too many individuals at this level to have the ability to again out…) that I would instantly swap to the primary accessible machine that supported this characteristic. It has been an extended wait (since late 2017) however with the discharge of the brand new Pixel 8 / Pixel 8 Pro handsets, there’s lastly a manufacturing handset that means that you can allow MTE!
The means of MTE to detect reminiscence corruption exploitation on the first harmful entry is a major enchancment in diagnostic and potential safety effectiveness. The provision of MTE on a manufacturing handset for the primary time is an enormous step ahead, and I believe there’s actual potential to make use of this expertise to make 0-day more durable.
I have been operating my Pixel 8 with MTE enabled since launch day, and thus far I have never discovered any points with any of the purposes I exploit every day1, or any noticeable efficiency points.
At the moment, MTE is just accessible on the Pixel as a developer possibility, supposed for app builders to check their apps utilizing MTE, however we are able to configure it to default to synchronous mode for all2 apps and native person mode binaries. This may be carried out on a inventory picture, with out bootloader unlocking or rooting required – simply a few debugger instructions. We’ll try this now, however first:
Disclaimer
That is completely not a supported machine configuration; and it is extremely possible that you’re going to encounter points with at the least some purposes crashing or failing to run appropriately with MTE should you set your machine up on this approach.
That is how I’ve configured my private Pixel 8, and thus far I’ve not skilled any points, however this was considerably of a shock to me, and I am nonetheless ready to see what the primary app that merely will not work in any respect shall be…
Enabling MTE on Pixel 8/Pixel 8 Professional
Enabling MTE on an Android machine requires the bootloader to order a portion of the machine reminiscence for storing tags. Which means there are two separate locations the place MTE must be enabled – first we have to configure the bootloader to allow it, after which we have to configure the system to make use of it in purposes.
First we’d like observe the Android instructions to allow developer mode and USB debugging on the machine:
Now we have to join our telephone to a trusted laptop that has the Android debugging tools put in on it – I am utilizing my linux workstation:
markbrand@markbrand$ adb units -l
Listing of units connected
XXXXXXXXXXXXXX machine usb:3-3 product:shiba mannequin:Pixel_8 machine:shiba transport_id:5
markbrand@markbrand$ adb shell
shiba:/ $ setprop arm64.memtag.bootctl memtag
shiba:/ $ setprop persist.arm64.memtag.default sync
shiba:/ $ setprop persist.arm64.memtag.app_default sync
shiba:/ $ reboot
These instructions are doing a few issues – first, we’re configuring the bootloader to allow MTE at boot. The second command units the default MTE mode for native executables operating on the machine, and the third command units the default MTE mode for apps. An app developer can allow MTE by utilizing the manifest, however this technique property units the default MTE mode for apps, successfully making it opt-out as a substitute of opt-in.
Whereas on the subject of apps opting-out, it is value noting that Chrome would not use the system allocator for many allocations, and as a substitute makes use of PartitionAlloc. There may be experimental MTE help beneath improvement, which might be enabled with some extra steps3. Unfortunately this at present requires setting a command-line flag which includes some safety tradeoffs. We anticipate that Chrome will add a better method to allow MTE help with out these issues within the close to future.
If we have a look at the entire system properties, we are able to see that there are just a few extra properties which can be associated to reminiscence tagging:
shiba:/ $ getprop | grep memtag
[arm64.memtag.bootctl]: [memtag]
[persist.arm64.memtag.app.com.android.nfc]: [off]
[persist.arm64.memtag.app.com.android.se]: [off]
[persist.arm64.memtag.app.com.google.android.bluetooth]: [off]
[persist.arm64.memtag.app_default]: [sync]
[persist.arm64.memtag.default]: [sync]
[persist.arm64.memtag.system_server]: [off]
[ro.arm64.memtag.bootctl_supported]: [1]
There are sadly some default exclusions which we will not overwrite – the protections on system properties imply that we will not at present allow MTE for just a few parts in a traditional manufacturing construct – these exceptions are system_server and purposes associated to nfc, the safe component and bluetooth.
We needed to ensure that these instructions work, so we’ll try this now. We’ll first test whether or not it is working for native executables:
shiba:/ $ cat /proc/self/smaps | grep mt
VmFlags: rd wr mr mw me ac mt
VmFlags: rd wr mr mw me ac mt
VmFlags: rd wr mr mw me ac mt
VmFlags: rd wr mr mw me ac mt
VmFlags: rd wr mr mw me ac mt
VmFlags: rd wr mr mw me ac mt
VmFlags: rd wr mr mw me ac mt
765bff1000-765c011000 r–s 00000000 00:12 97 /dev/__properties__/u:object_r:arm64_memtag_prop:s0
We will see that our cat course of has mappings with the mt bit set, so MTE has been enabled for the method.
Now in an effort to test that an app with none manifest setting has picked up this, we added a bit little bit of code to an empty JNI challenge to set off a use-after-free bug:
extern “C” JNIEXPORT jstring JNICALL
Java_com_example_mtetestapplication_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
char* ptr = strdup(“take a look at string”);
free(ptr);
// Use-after-free when ptr is accessed under.
return env->NewStringUTF(ptr);
}
With out MTE, it is unlikely that the applying would crash operating this code. I additionally made certain that the applying manifest doesn’t set MTE, so it can inherit the default. Once we launch the applying we are going to see whether or not it crashes, and whether or not the crash is attributable to an MTE test failure!
Trying on the logcat output we are able to see that the reason for the crash was a synchronous MTE tag test failure (SEGV_MTESERR).
DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
DEBUG : Construct fingerprint: ‘google/shiba/shiba:14/UD1A.230803.041/10808477:person/release-keys’
DEBUG : Revision: ‘MP1.0’
DEBUG : ABI: ‘arm64’
DEBUG : Timestamp: 2023-10-24 16:56:32.092532886+0200
DEBUG : Course of uptime: 2s
DEBUG : Cmdline: com.instance.mtetestapplication
DEBUG : pid: 24147, tid: 24147, title: testapplication >>> com.instance.mtetestapplication <<<
DEBUG : uid: 10292
DEBUG : tagged_addr_ctrl: 000000000007fff3 (PR_TAGGED_ADDR_ENABLE, PR_MTE_TCF_SYNC, masks 0xfffe)
DEBUG : pac_enabled_keys: 000000000000000f (PR_PAC_APIAKEY, PR_PAC_APIBKEY, PR_PAC_APDAKEY, PR_PAC_APDBKEY)
DEBUG : sign 11 (SIGSEGV), code 9 (SEGV_MTESERR), fault addr 0x0b000072afa9f790
DEBUG : x0 0000000000000001 x1 0000007fe384c2e0 x2 0000000000000075 x3 00000072aae969ac
DEBUG : x4 0000007fe384c308 x5 0000000000000004 x6 7274732074736574 x7 00676e6972747320
DEBUG : x8 0000000000000020 x9 00000072ab1867e0 x10 000000000000050c x11 00000072aaed0af4
DEBUG : x12 00000072aaed0ca8 x13 31106e3dee7fb177 x14 ffffffffffffffff x15 00000000ebad6a89
DEBUG : x16 0000000000000001 x17 000000722ff047b8 x18 00000075740fe000 x19 0000007fe384c2d0
DEBUG : x20 0000007fe384c308 x21 00000072aae969ac x22 0000007fe384c2e0 x23 070000741fa897b0
DEBUG : x24 0b000072afa9f790 x25 00000072aaed0c18 x26 0000000000000001 x27 000000754a5fae40
DEBUG : x28 0000007573c00000 x29 0000007fe384c260
DEBUG : lr 00000072ab35e7ac sp 0000007fe384be30 computer 00000072ab1867ec pst 0000000080001000
DEBUG : 98 whole frames
DEBUG : backtrace:
DEBUG : #00 computer 00000000003867ec /apex/com.android.artwork/lib64/libart.so (artwork::(nameless namespace)::ScopedCheck::Verify(artwork::ScopedObjectAccess&, bool, char const*, artwork::(nameless namespace)::JniValueType*) (.__uniq.99033978352804627313491551960229047428)+1636) (BuildId: a5fcf27f4a71b07dff05c648ad58e3cd)
DEBUG : #01 computer 000000000055e7a8 /apex/com.android.artwork/lib64/libart.so (artwork::(nameless namespace)::CheckJNI::NewStringUTF(_JNIEnv*, char const*) (.__uniq.99033978352804627313491551960229047428.llvm.6178811259984417487)+160) (BuildId: a5fcf27f4a71b07dff05c648ad58e3cd)
DEBUG : #02 computer 00000000000017dc /information/app/~~lgGoAt3gB6oojf3IWXi-KQ==/com.instance.mtetestapplication-k4Yl4oMx9PEbfuvTEkjqFg==/base.apk!libmtetestapplication.so (offset 0x1000) (_JNIEnv::NewStringUTF(char const*)+36) (BuildId: f60a9970a8a46ff7949a5c8e41d0ece51e47d82c)
…
DEBUG : Word: a number of potential causes for this crash have been detected, itemizing them in lowering order of probability.
DEBUG : Trigger: [MTE]: Use After Free, 0 bytes right into a 12-byte allocation at 0x72afa9f790
DEBUG : deallocated by thread 24147:
DEBUG : #00 computer 000000000005e800 /apex/com.android.runtime/lib64/bionic/libc.so (scudo::Allocator<scudo::AndroidConfig, &(scudo_malloc_postinit)>::quarantineOrDeallocateChunk(scudo::Choices, void*, scudo::Chunk::UnpackedHeader*, unsigned lengthy)+496) (BuildId: a017f07431ff6692304a0cae225962fb)
DEBUG : #01 computer 0000000000057ba4 /apex/com.android.runtime/lib64/bionic/libc.so (scudo::Allocator<scudo::AndroidConfig, &(scudo_malloc_postinit)>::deallocate(void*, scudo::Chunk::Origin, unsigned lengthy, unsigned lengthy)+212) (BuildId: a017f07431ff6692304a0cae225962fb)
DEBUG : #02 computer 000000000000179c /information/app/~~lgGoAt3gB6oojf3IWXi-KQ==/com.instance.mtetestapplication-k4Yl4oMx9PEbfuvTEkjqFg==/base.apk!libmtetestapplication.so (offset 0x1000) (Java_com_example_mtetestapplication_MainActivity_stringFromJNI+40) (BuildId: f60a9970a8a46ff7949a5c8e41d0ece51e47d82c)
If you happen to simply need to test that MTE has been enabled within the bootloader, there’s an application on the Play Store from Google’s Dynamic Instruments staff, which it’s also possible to use (this app allows MTE in async mode within the manifest, which is why you see under that it isn’t operating in sync mode on all cores):
At this level, we are able to return into the developer settings and disable USB debugging, since we do not need that enabled for regular day-to-day utilization. We do want to go away the developer mode toggle on, since disabling that may flip off MTE once more fully on the subsequent reboot.
Conclusion
The Pixel 8 with synchronous-MTE enabled is at the least subjectively a efficiency and battery-life improve over my earlier telephone.
I believe it is a large enchancment for the overall safety of the machine – many zero-click assault surfaces contain giant quantities of unsafe C/C++ code, whether or not that is WebRTC for calling, or one of many many media or picture file parsing libraries. MTE is not a silver bullet for reminiscence security – however the launch of the primary manufacturing machine with the flexibility to run nearly all user-mode purposes with synchronous-MTE is a large step ahead, and one thing that is value celebrating!
1 On a staff member’s machine, a single MTE detection of a use-after-free bug occurred final week. This resulted in a crash that wasn’t observed on the time, however which we later discovered when trying via the saved crash studies on their machine. As a result of the alloc and free stacktraces of the allocation have been recorded, we have been capable of rapidly determine the bug and report it to the applying builders – the bug on this case was attributable to person gesture enter, and would not actually have safety impression, however it already illustrates a few of the benefits of MTE.
2 Apart from se (safe component), bluetooth, nfc, and the system server, attributable to these system apps explicitly setting their particular person system properties to ‘off’ within the Pixel system picture.
3 Enabling MTE in Chrome requires setting a number of command line flags, which on a non-rooted Android machine requires configuring Chrome to load the command line flags from a file in /information/native/tmp. That is probably unsafe, so we would not counsel doing this, however if you would like to experiment on a take a look at machine or for fuzzing, the next instructions will permit you to run Chrome with MTE enabled:
markbrand@markbrand:~$ adb shell
shiba:/ $ umask 022
shiba:/ $ echo “_ –enable-features=PartitionAllocMemoryTagging:enabled-processes/all-processes/memtag-mode/sync –disable-features=PartitionAllocPermissiveMte,KillPartitionAllocMemoryTagging” > /information/native/tmp/chrome-command-line
shiba:/ $ ls -la /information/native/tmp/chrome-command-line
-rw-r–r– 1 shell shell 176 2023-10-25 19:14 /information/native/tmp/chrome-command-line