Port exploit to Realme GT2 Pro
rapperskull opened this issue · 24 comments
Hi, I tried to run the exploit on a Realme GT2 Pro without success.
I modified the run file, adding -f /vendor/lib/libdrmfs.so
(one of the libraries with 0x5F at offset 0x1000), but the phone reboots.
This is the script output:
dirtypipe-android: 1 file pushed, 0 skipped. 87.7 MB/s (46184 bytes in 0.001s)
env-patcher: 1 file pushed, 0 skipped. 48.5 MB/s (13224 bytes in 0.000s)
startup-root: 1 file pushed, 0 skipped. 28.9 MB/s (6946 bytes in 0.000s)
magisk/: 7 files pushed, 0 skipped. 45.0 MB/s (14522684 bytes in 0.308s)
10 files pushed, 0 skipped. 44.2 MB/s (14589038 bytes in 0.315s)
Failed to set property 'a' to 'a'.
See dmesg for error reason.
Ignore device info.
Device version: Product=RMX3301 Fingerprint=realme/RMX3301EEA/RED8ACL1:12/SKQ1.211019.001/S.GDPR.202204141322:user/release-keys
stage1_lib: /system/lib64/libc++.so
stage2_lib: /system/lib/libldacBT_enc.so
stage2_param_libname: /vendor/lib/libdrmfs.so
d503233f PACIASP was found. Offset hook address by +4.
Offset found: shellcode_offset: a57d0 hook_offset: 5b264 first instruction: a9be7bfd
Empty space size: 2096 bytes
Run index: 0
Stage1 debug filename: /dev/.dirtypipe-0000
Shell code size: 344 0x158 bytes
startup script: /data/local/tmp/startup-root
It worked!
I think this is a problem with the included mymod.ko
. Unfortunately Realme hasn't released yet the kernel sources. Do you think there's another way around?
Thank you.
BTW I also tried to use /vendor/lib/libcamxifestriping.so
and beta4 from the S22 thread, with the same result.
This is the onyl thing in the logcat:
05-31 11:54:16.557 31291 31291 W libc : Unable to set property "a" to "a": error code: 0x18
05-31 11:54:16.554 31293 31293 W modprobe: type=1400 audit(0.0:8650): avc: denied { read } for path="pipe:[1216045]" dev="pipefs" ino=1216045 scontext=u:r:vendor_modprobe:s0 tcontext=u:r:init:s0 tclass=fifo_file permissive=0
05-31 11:54:16.554 31293 31293 W modprobe: type=1400 audit(0.0:8651): avc: denied { write } for path="pipe:[1216045]" dev="pipefs" ino=1216045 scontext=u:r:vendor_modprobe:s0 tcontext=u:r:init:s0 tclass=fifo_file permissive=0
uname -a
output:
Linux localhost 5.10.66-android12-9-gc634142fd3d8-ab8094802 #1 SMP PREEMPT Wed Jan 19 19:31:18 UTC 2022 aarch64
The ROM build date is Thu Apr 14 12:53:07 CST 2022
, so I'm not sure if Dirty Pipe is patched in this kernel version, but judging from the kernel date it should not.
Check if mymod.ko is properly loaded. e.g. Removing code from mymod_init and put log output like following:
static int __init mymod_init(void) {
pr_info("mymod_init: called!\n");
return -ENOMSG;
}
Perhaps you can use kernel code from Pixel6.
Just tried and unfortunately I can't see mymod_init: called!
anywhere.
You still see rebooting after exploit?
pr_info write to dmesg instead of logcat.
But dmesg can't be read when selinux is enabled.
It is necessary to find another method to log.
Yes, it still reboots. Didn't know that pr_info wrote to dmesg.
It shouldn't reboot if module is properly loaded. Perhaps there is a issue before loading mod.
Comment out this line and check logcat.
DirtyPipe-Android/modprobe-payload.c
Line 68 in ca23ffb
In addition, can you obtain kernel module for the device from firmware?
Maybe the kernel crashed because of the difference of module binary format.
Sorry, I made a mistake. After replacing mymod_init
it doesn't reboot. This is the logcat:
06-01 08:03:47.834 11120 11120 W libc : Unable to set property "a" to "a": error code: 0x18
06-01 08:03:47.833 11123 11123 W modprobe: type=1400 audit(0.0:219): avc: denied { read } for path="pipe:[175682]" dev="pipefs" ino=175682 scontext=u:r:vendor_modprobe:s0 tcontext=u:r:init:s0 tclass=fifo_file permissive=0
06-01 08:03:47.833 11123 11123 W modprobe: type=1400 audit(0.0:220): avc: denied { write } for path="pipe:[175682]" dev="pipefs" ino=175682 scontext=u:r:vendor_modprobe:s0 tcontext=u:r:init:s0 tclass=fifo_file permissive=0
06-01 08:03:47.849 11123 11123 I modprobe-payload: Parsed '/vendor/lib/libcamxifestriping.so' '/data/local/tmp/startup-root' fd=3
06-01 08:03:47.856 11123 11123 I modprobe-payload: Succeed: /vendor/lib/libcamxifestriping.so -1 42
06-01 08:03:47.857 11124 11124 I modprobe-payload: execve: 13 /data/local/tmp/startup-root 0
06-01 08:03:48.857 11124 11124 I modprobe-payload: execve: 13 /data/local/tmp/startup-root 1
06-01 08:03:49.858 11124 11124 I modprobe-payload: execve: 13 /data/local/tmp/startup-root 2
06-01 08:03:50.859 11124 11124 I modprobe-payload: execve: 13 /data/local/tmp/startup-root 3
06-01 08:03:51.862 11124 11124 I modprobe-payload: execve: 13 /data/local/tmp/startup-root 4
06-01 08:03:52.866 11124 11124 I modprobe-payload: execve: 13 /data/local/tmp/startup-root 5
06-01 08:03:53.868 11124 11124 I modprobe-payload: execve: 13 /data/local/tmp/startup-root 6
And it goes on until I reboot.
Do you still need me to make the other try, commenting that line?
As for the kernel module, what do you need exactly? I have the boot.img, do I need to extract something from that?
That's good. It means the rebooting was caused by the code to setup permissive domain.
Recover original mymod.c then comment out this line. (Or use mymod-permissive.ko from repository.)
DirtyPipe-Android/mymod/mymod.c
Line 156 in ca23ffb
06-01 08:54:15.950 9873 9873 I modprobe-payload: Failed: /vendor/lib/libcamxifestriping.so -1 8
As I understand, finit_module is setting errno to ENOEXEC
. I read here that it could be due to a vermagic mismatch.
I checked /proc/config.gz
and in fact the kernel was compiled without CONFIG_MODULE_FORCE_LOAD
, so setting the MODULE_INIT_IGNORE_VERMAGIC
flag doesn't work.
I don't know exactly what it means, maybe I need to use the sources for my kernel specifically (which I don't have) or checkout the Pixel 6 kernel sources to a specific commit?
EDIT: I tried to change the version in build-script-patch.patch
to match the one of my kernel, but I had no luck. Same error.
EDIT2: The symbol version hashes take precedence over vermagic, and they seem to match, so this is not the problem.
After a lot of tries, I boiled the issue down to this line:
DirtyPipe-Android/mymod/mymod.c
Line 203 in ca23ffb
Finally found out the problem, by a lot of trial and error.
The fact is that we can not overwrite the first byte of every page, and something important could be at offset 0x2000.
I ran llvm-objcopy --set-section-alignment .comment=4096 mymod-permissive.ko
on your original mymod-permissive.ko
file to align the .comment section at offset 0x2000 and everything worked. Something still crosses the boundary at offset 0x3000, but maybe it's not a problem.
Well, almost everything worked: now I can't get root access. Magisk simply logs su: request rejected (2000)
after a while, without prompting. Maybe if I factory reset, something changes and it works, but maybe we can try to figure out what's wrong.
I created #13 with the changes I made to make it work on my device. It simply generates a smaller file and avoids putting important stuff at offset 0x2000. On my device it even works with USE_PERMISSIVE_DOMAIN
defined.
As for Magisk not granting root, still no success. I also made a factory reset but nothing changed.
Finally found out the problem, by a lot of trial and error.
Congrat! 👍
Sorry that I couldn't give you any good help.
For magisk issue, try following checks.
- See if magisk app is installed. It should be installed automatically.
- Open magisk settings to see adb shell is permitted to access su.
- Check if
magiskd
is running.ps -A | grep magiskd
- Edit startup-root to launch telnetd or reverse shell for better debugging environment.
- See magisk logs placed in
/data/adb
.
Magisk is installed, both apps and adb can access root, and magiskd is running. I cannot see the logs since /data/adb
is not accessible without being root, but the log in the Magisk app says nothing wrong.
I replaced startup-root
with the one from beta4, and this is the output:
06-03 20:17:07.355 9946 9946 W libc : Unable to set property "a" to "a": error code: 0x18
06-03 20:17:07.359 9949 9949 W modprobe: type=1400 audit(0.0:219): avc: denied { read } for path="pipe:[125985]" dev="pipefs" ino=125985 scontext=u:r:vendor_modprobe:s0 tcontext=u:r:init:s0 tclass=fifo_file permissive=0
06-03 20:17:07.359 9949 9949 W modprobe: type=1400 audit(0.0:220): avc: denied { write } for path="pipe:[125985]" dev="pipefs" ino=125985 scontext=u:r:vendor_modprobe:s0 tcontext=u:r:init:s0 tclass=fifo_file permissive=0
06-03 20:17:07.373 9949 9949 I modprobe-payload: Parsed '/vendor/lib/libcamxifestriping.so' '/data/local/tmp/startup-root' fd=3
06-03 20:17:07.411 9949 9949 I modprobe-payload: Succeed: /vendor/lib/libcamxifestriping.so -1 42
06-03 20:17:07.415 9953 9953 I setenforce: type=1400 audit(0.0:221): avc: denied { setenforce } for scontext=u:r:vendor_modprobe:s0 tcontext=u:object_r:kernel:s0 tclass=security permissive=1
06-03 20:17:07.415 812 812 W auditd : type=1404 audit(0.0:222): enforcing=0 old_enforcing=1 auid=4294967295 ses=4294967295 enabled=1 old-enabled=1 lsm=selinux res=1
06-03 20:17:07.423 9955 9955 I logwrapper: type=1400 audit(0.0:223): avc: denied { read write } for name="0" dev="devpts" ino=3 scontext=u:r:vendor_modprobe:s0 tcontext=u:object_r:devpts:s0 tclass=chr_file permissive=1
06-03 20:17:07.430 9954 9954 I echo : startup-root ok
06-03 20:17:07.442 9956 9956 I id : uid=0(root) gid=0(root) groups=0(root),3009(readproc) context=u:r:vendor_modprobe:s0
06-03 20:17:07.457 9958 9958 I getenforce: Permissive
06-03 20:17:07.473 9961 9961 I echo : startup-root 2
06-03 20:17:07.509 9963 9963 I echo : startup-root 3
06-03 20:17:07.582 9966 9966 I echo : startup-root 4
06-03 20:17:08.607 9979 9979 I logwrapper: type=1400 audit(0.0:846): avc: denied { read write } for name="0" dev="devpts" ino=3 scontext=u:r:vendor_modprobe:s0 tcontext=u:object_r:devpts:s0 tclass=chr_file permissive=1
06-03 20:17:08.607 9979 9979 I logwrapper: type=1400 audit(0.0:847): avc: denied { open } for path="/dev/pts/0" dev="devpts" ino=3 scontext=u:r:vendor_modprobe:s0 tcontext=u:object_r:devpts:s0 tclass=chr_file permissive=1
06-03 20:17:08.619 9979 9979 I echo : type=1400 audit(0.0:848): avc: denied { getattr } for path="/dev/pts/0" dev="devpts" ino=3 scontext=u:r:vendor_modprobe:s0 tcontext=u:object_r:devpts:s0 tclass=chr_file permissive=1
06-03 20:17:08.625 9978 9978 I echo : startup-root 5
06-03 20:17:08.631 9981 9981 I mkfifo : type=1400 audit(0.0:849): avc: denied { create } for name="reverse-fifo" scontext=u:r:vendor_modprobe:s0 tcontext=u:object_r:shell_data_file:s0 tclass=fifo_file permissive=1
06-03 20:17:08.635 9984 9984 I startup-root: type=1400 audit(0.0:850): avc: denied { write } for name="reverse-fifo" dev="dm-37" ino=28914 scontext=u:r:vendor_modprobe:s0 tcontext=u:object_r:shell_data_file:s0 tclass=fifo_file permissive=1
06-03 20:17:08.655 9985 9985 I echo : startup-root 6
06-03 20:17:09.204 726 726 W SELinux : Multiple same specifications for vendor.qti.gnss.ILocAidlGnss/default.
06-03 20:17:09.205 726 726 W SELinux : Multiple same specifications for OplusLocationManager.
06-03 20:17:09.208 726 726 I SELinux : SELinux: Loaded service_contexts from:
06-03 20:17:09.208 726 726 I SELinux : /system/etc/selinux/plat_service_contexts
06-03 20:17:09.209 726 726 I SELinux : /system_ext/etc/selinux/system_ext_service_contexts
06-03 20:17:09.209 726 726 I SELinux : /product/etc/selinux/product_service_contexts
06-03 20:17:09.209 726 726 I SELinux : /vendor/etc/selinux/vendor_service_contexts
06-03 20:17:09.209 726 726 I SELinux : avc: received setenforce notice (enforcing=0)
06-03 20:17:29.879 731 731 I SELinux : avc: received setenforce notice (enforcing=0)
I filtered only what I thought was relevant from the log. Needless to say, no reverse shell connected.
Previously I also tried a minimal startup-root
that only calls setprop
but it failed with error code 0xb (while it usually fails with 0x18 when you're not root).
EDIT: As I understand, it should be EAGAIN/EWOULDBLOCK. Maybe it's a socket failure.
I don't know if setprop
works on startup-root. Did you test telnetd method?
Uncomment this line,
DirtyPipe-Android/startup-root
Line 67 in fb05d53
then run
busybox telnet 127.0.0.1 10848
to access root shell.
magisk setup is very hacky and may be unstable. Try telnetd first.
I can get a root shell by using telnet, so it's really something with Magisk initialization
Can see magisk's log?
strace of su and magiskd will also help debugging.
This is the only thing in Magisk log:
06-06 19:30:46.040 10179 10179 I : Magisk 24.3(24300) daemon started
06-06 19:30:46.040 10179 10179 I : * Device API level: 31
06-06 19:32:33.359 10179 10431 W : su: request rejected (2000)
How can I strace su and/or magiskd?
Here is the output of strace -p $(pidof magiskd) -f
while running su
in adb shell: magiskd_strace.zip
Sorry for late response. Did you solve the issue?
According to the log, am
command called from su daemon was crashed.
[pid 11130] execve("/system/bin/app_process", ["/system/bin/app_process", "/system/bin", "com.android.commands.content.Con"..., "call", "--uri", "content://com.topjohnwu.magisk.p"..., "--user", "0", "--method", "log", "--extra", "from.uid:i:2000", "--extra", "to.uid:i:0", "--extra", "pid:i:11094", "--extra", "policy:i:1", "--extra", "command:s:/system/bin/sh", "--extra", "notify:b:true"], 0xb40000742164b000 /* 25 vars */ <unfinished ...>
[pid 11141] --- SIGRT_1 {si_signo=SIGRT_1, si_code=SI_TKILL, si_pid=11130, si_uid=0} ---
Check to see if am
command works from telnetd shell. Run am
without argument.
am
command sometimes doesn't work on root shell, while it properly works on adb shell
.
When I developed the magisk installation script, I encountered similar problem.
am
command requires valid mount namespace and write permission to stdio.
I got following error when running `am start having invalid mount namespace.
CANNOT LINK EXECUTABLE "/system/bin/app_process64": library "libnativeloader.so" not found: needed by main executable
Following line should fix issue by entering proper mount namespace then launch magiskd. It may not work for some reason.
DirtyPipe-Android/startup-root
Line 84 in fb05d53
When am
fails by not having permission to stdio, try to redirect output to file or pipe.
In addition, check logcat output for crash log of am
.
Unfortunately, I don't think I can test anymore. My whole point was to just change a ro property and trick the official app into allowing me to unlock the bootloader, and it worked. So basically I just installed Magisk the regular way. That's a shame because I really wanted to help port the exploit to more devices.
BTW I repackaged your work in an easy to use solution (and of course credited you): https://forum.xda-developers.com/t/eu-model-unlock-bootloader-of-european-model.4454787/
Permanent root is better than temporary magisk, because it is hacky and unstable. The main goal of this exploit is temporary root shell. It doesn't matter whether temp magisk is working or not for unlockable devices.
Thank you for crediting in the article. I added that link to README.