Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use androidboot.partition_map as a fallback for matching partition names in the preinit finding. #8293

Merged
merged 4 commits into from
Aug 15, 2024

Conversation

chsbuffer
Copy link
Contributor

Fixes Play Games Developer Emulator magiskinit: Cannot find preinit metadata, abort!.

only tested on the Play Games Developer Emulator, need to do some test on the production one, which runs on older version of Android iirc.

@yujincheng08
Copy link
Collaborator

Doesn't magisk --preinit-device print the device name before mapping? Like the following

QQ_1723051068867

@chsbuffer
Copy link
Contributor Author

chsbuffer commented Aug 8, 2024

magisk --preinit-device:

resetprop: get prop [ro.crypto.state]: [encrypted]
resetprop: get prop [ro.crypto.type]: [file]
resetprop: get prop [ro.crypto.metadata.enabled]: [true]
metadata

a script replicates magiskinit SecondStageInit collect_devices

parse_device() {
  local device_name="$1"
  local devpath=$(readlink -f "/sys/dev/block/$device_name")
  local uevent_file="/sys/dev/block/$device_name/uevent"
  local dm_name_file="/sys/dev/block/$device_name/dm/name"
        while IFS='=' read -r key value; do
          case "$key" in
            MAJOR)
              local major="$value"
              ;;
            MINOR)
              local minor="$value"
              ;;
            DEVNAME)
              local devname="$value"
              ;;
            PARTNAME)
              local partname="$value"
              ;;
          esac
        done < "$uevent_file"
  local dmname=$(cat "$dm_name_file" 2>/dev/null) || dm_name=""

  printf "%-18s\t%-18s\t%-18s\t%s\n" "$partname" "$dmname" "$devname" "$devpath"
}

printf "%-18s\t%-18s\t%-18s\t%s\n" "partname" "dmname" "devname" "devpath"
for device in /sys/dev/block/*; do
   parse_device "$(basename "$device")"
done

output:

partname                dmname                  devname                 devpath
                                                ram0                    /sys/devices/virtual/block/ram0
                                                ram1                    /sys/devices/virtual/block/ram1
                                                ram10                   /sys/devices/virtual/block/ram10
                                                ram11                   /sys/devices/virtual/block/ram11
                                                ram12                   /sys/devices/virtual/block/ram12
                                                ram13                   /sys/devices/virtual/block/ram13
                                                ram14                   /sys/devices/virtual/block/ram14
                                                ram15                   /sys/devices/virtual/block/ram15
                                                ram2                    /sys/devices/virtual/block/ram2
                                                ram3                    /sys/devices/virtual/block/ram3
                                                ram4                    /sys/devices/virtual/block/ram4
                                                ram5                    /sys/devices/virtual/block/ram5
                                                ram6                    /sys/devices/virtual/block/ram6
                                                ram7                    /sys/devices/virtual/block/ram7
                                                ram8                    /sys/devices/virtual/block/ram8
                                                ram9                    /sys/devices/virtual/block/ram9
                                                zram0                   /sys/devices/virtual/block/zram0
                                                vda                     /sys/devices/pci0000:00/0000:00:01.0/virtio0/block/vda
super                                           vda1                    /sys/devices/pci0000:00/0000:00:01.0/virtio0/block/vda/vda1
                                                vdb                     /sys/devices/pci0000:00/0000:00:02.0/virtio1/block/vdb
boot_a                                          vda2                    /sys/devices/pci0000:00/0000:00:01.0/virtio0/block/vda/vda2
vendor_boot_a                                   vda3                    /sys/devices/pci0000:00/0000:00:01.0/virtio0/block/vda/vda3
                                                vdc                     /sys/devices/pci0000:00/0000:00:03.0/virtio2/block/vdc
vbmeta_a                                        vda4                    /sys/devices/pci0000:00/0000:00:01.0/virtio0/block/vda/vda4
                                                vdd                     /sys/devices/pci0000:00/0000:00:04.0/virtio3/block/vdd
vbmeta_system_a                                 vda5                    /sys/devices/pci0000:00/0000:00:01.0/virtio0/block/vda/vda5
                        system_a                dm-0                    /sys/devices/virtual/block/dm-0
                        vendor_a                dm-1                    /sys/devices/virtual/block/dm-1
                        product_a               dm-2                    /sys/devices/virtual/block/dm-2
                        system-verity           dm-3                    /sys/devices/virtual/block/dm-3
                        vendor-verity           dm-4                    /sys/devices/virtual/block/dm-4
                        product-verity          dm-5                    /sys/devices/virtual/block/dm-5
                        userdata                dm-6                    /sys/devices/virtual/block/dm-6
                                                loop0                   /sys/devices/virtual/block/loop0
                                                loop13                  /sys/devices/virtual/block/loop13
                                                loop14                  /sys/devices/virtual/block/loop14
                                                loop15                  /sys/devices/virtual/block/loop15
                                                loop2                   /sys/devices/virtual/block/loop2
                                                loop3                   /sys/devices/virtual/block/loop3
                                                loop4                   /sys/devices/virtual/block/loop4
                                                loop5                   /sys/devices/virtual/block/loop5
                                                loop6                   /sys/devices/virtual/block/loop6
                                                loop7                   /sys/devices/virtual/block/loop7
                                                loop8                   /sys/devices/virtual/block/loop8
                                                loop9                   /sys/devices/virtual/block/loop9
                                                loop1                   /sys/devices/virtual/block/loop1
                                                loop10                  /sys/devices/virtual/block/loop10
                                                loop11                  /sys/devices/virtual/block/loop11
                                                loop12                  /sys/devices/virtual/block/loop12

/dev/block/by-name

boot_a -> /dev/block/vda2
metadata -> /dev/block/vdb
misc -> /dev/block/vdd
super -> /dev/block/vda1
userdata -> /dev/block/vdc
vbmeta_a -> /dev/block/vda4
vbmeta_system_a -> /dev/block/vda5
vda -> /dev/block/vda
vdb -> /dev/block/vdb
vdc -> /dev/block/vdc
vdd -> /dev/block/vdd
vendor_boot_a -> /dev/block/vda3

kernel cmdline fragment
androidboot.partition_map=vdb,metadata;vdc,userdata;vdd,misc

@yujincheng08
Copy link
Collaborator

send mountinfo?

@chsbuffer
Copy link
Contributor Author

mountinfo.txt

@yujincheng08
Copy link
Collaborator

also send /proc/self/mounts?

@chsbuffer
Copy link
Contributor Author

mounts.txt

@chsbuffer
Copy link
Contributor Author

Do you think maybe the fix should be a magisk find_preinit_device() change instead of a magiskinit change?

@yujincheng08
Copy link
Collaborator

hmm, both of them show /dev/block/by-name/metadata as the mount device and does not follow the link.

@chsbuffer
Copy link
Contributor Author

chsbuffer commented Aug 8, 2024

/metadata may be mounted by init which follows /ramdisk/fstab.cut_cvm.
I guess adding a xrealpath call to find_preinit_device() can fix this in another way?
magisk_patched.zip

@yujincheng08
Copy link
Collaborator

No, we have no permission to call realpath on /dev/block/by-name

@chsbuffer
Copy link
Contributor Author

chsbuffer commented Aug 8, 2024

Back to the pr state. I tested the change on the production one. turns out it runs the same version of android as the dev one. The patched system boots and the log looks good, but I can't get adb to work to check if magisk is working.
The developer emulator has an adbproxy service running /vendor/bin/adbproxy connect 127.0.0.1:5555 10.0.2.2:38068 but the production one removes the /vendor/bin/adbproxy. After messing with the Root Directory Overlay System, I still can't get it to work.

@chsbuffer chsbuffer marked this pull request as ready for review August 8, 2024 03:31
Copy link
Contributor Author

@chsbuffer chsbuffer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some code style issue

@chsbuffer chsbuffer force-pushed the partition-map-support branch 3 times, most recently from 699813b to eb9288a Compare August 8, 2024 09:42
native/src/init/mount.cpp Outdated Show resolved Hide resolved
@yujincheng08
Copy link
Collaborator

partition_map was added since Android 13; bootconfig was added since Android 12, so I think we only need to parse bootconfig.

@chsbuffer
Copy link
Contributor Author

chsbuffer commented Aug 8, 2024

partition_map was added since Android 13; bootconfig was added since Android 12, so I think we only need to parse bootconfig.

Google Play Games passes androidboot.partition_map via kernel cmdline, and the AOSP code also parse both bootconfig and kernel cmdline.

The partition_map might be considered dynamic, I assume that the bootconfig is hardcoded in the ROM and can't be changed, so Google Play Games Emulator does the cmdline way.

@chsbuffer
Copy link
Contributor Author

chsbuffer commented Aug 8, 2024

I will check the kernel cmdline and bootconfig later

@chsbuffer
Copy link
Contributor Author

chsbuffer commented Aug 8, 2024

vsoc_kiwi_x86_64:/ # cat /proc/cmdline | tr ' ' '\n'
stack_depot_disable=on
cgroup_disable=pressure
cgroup.memory=nokmem

bootconfig
init=/init
loop.max_part=7
printk.devkmsg=on
bootconfig
panic=-1
console=hvc0
earlycon=uart8250,io,0x3f8
androidboot.verifiedbootstate=orange
androidboot.boot_devices=pci0000:00/0000:00:01.0,pci0000:00/0000:00:02.0,pci0000:00/0000:00:03.0,pci0000:00/0000:00:04.0
androidboot.console=hvc0
androidboot.hardware.gltransport=virtio-gpu-asg
androidboot.hardware.gralloc=minigbm
androidboot.hardware.hwcomposer=ranchu
androidboot.kiwi.adbproxy.enabled=1
androidboot.kiwi.adbproxy.port=38068
androidboot.kiwi.client_version=24.6.902.0
androidboot.kiwi.logcatserial=1
androidboot.kiwi.logcatserial.dev=/dev/hvc0
androidboot.kiwi.logcatserial.filter=System.err:E,.android.common:E,*:I
androidboot.kiwi.metrics_group=devdogfood
androidboot.partition_map=vdb,metadata;vdc,userdata;vdd,misc
androidboot.serialno=2e9e3643154548bf83bd1d5e5bff0afe
androidboot.pcs.recvport=50051
androidboot.pcs.sendport=50050
androidboot.timezone=Asia/Shanghai
androidboot.hw_timeout_multiplier=1
noxsaves
no_timer_check
tsc=reliable
androidboot.pcs.use_vsock=true
androidboot.pcs.enable_host_ime=true
androidboot.ime.ime_port=60006
androidboot.pcs.enable_volume_control=true
androidboot.pcs.enable_pre_game_launch_memory_compaction=false
androidboot.opengles.version=196609
androidboot.dirty.expire.centisecs=500
androidboot.kiwi.prefetch.io_depth=20
androidboot.kiwi.prefetch.max_fds=2000
androidboot.kiwi.prefetch=replay
androidboot.async.persist.writes=true
androidboot.enable.min.free.kbytes=1
androidboot.standard.min.free.kbytes=61440
androidboot.optimized.min.free.kbytes=30720
androidboot.kiwi_enable_android_notifications=true
androidboot.kiwi_enable_multi_android_user=false
androidboot.kiwi_enable_multi_window=false
androidboot.kiwi_disable_force_stop=true
androidboot.kiwi_adv_controls.enable_control_hints_overlay=false
androidboot.kiwi_adv_controls.enable_context_detection=false
androidboot.kiwi_adv_controls.controls_editor_mode=disabled
snd-hda-intel.enable=0
snd_intel8x0.inside_vm=1
snd_intel8x0.ac97_clock=48000
androidboot.hardware.hwcomposer.display_finder_mode=drm
androidboot.hardware.egl=angle
androidboot.hardware.vulkan=ranchu
nopat
androidboot.kiwi.enable_houdini=1
androidboot.locale=zh-CN
androidboot.vsock_gatekeeper_port=31540
androidboot.vsock_keymaster_port=31541
androidboot.kiwi_out_period_count=4
virtio_snd.msg_timeout_ms=5000
androidboot.pcs.events_service=true
androidboot.angle_log_texture_decompression_events=true
ramoops.mem_address=0x1b8000000
ramoops.mem_size=0x100000

vsoc_kiwi_x86_64:/ # cat /proc/bootconfig
androidboot.hardware = "cutf_cvm"
androidboot.slot_suffix = "_a"
vsoc_kiwi_x86_64:/ #

The bootconfig document said so:

Implement the bootconfig feature for new devices launching with a 12-5.10.xx kernel version. You don't need to implement it if you're upgrading devices.

@chsbuffer
Copy link
Contributor Author

Maybe the bootloader is bugging out, I notice the difference in bootconfig size between before and after patching the bios.rom.

@yujincheng08 yujincheng08 force-pushed the partition-map-support branch 2 times, most recently from f6ded27 to 9317e55 Compare August 8, 2024 14:41
@yujincheng08 yujincheng08 marked this pull request as draft August 9, 2024 00:55
@yujincheng08 yujincheng08 marked this pull request as ready for review August 9, 2024 01:10
native/src/init/mount.cpp Outdated Show resolved Hide resolved
@yujincheng08 yujincheng08 force-pushed the partition-map-support branch 2 times, most recently from 283a1e8 to 15474a2 Compare August 12, 2024 11:15
@topjohnwu
Copy link
Owner

@yujincheng08 can you review and approve once the change is in an acceptable state?

@topjohnwu topjohnwu merged commit e9e2ecf into topjohnwu:master Aug 15, 2024
25 checks passed
else if (key == "PARTNAME")
strcpy(dev->partname, value.data());
strscpy(dev->partname, value.data(), sizeof(dev->devname));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it intentional that this is using sizeof(dev->devname) instead of sizeof(dev->partname)? Might be irrelevant, I'm not exactly sure how this code is called, I just happened to glance at it the other day.

Copy link
Contributor Author

@chsbuffer chsbuffer Aug 29, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't really matter, partname and devname are both 32.
@yujincheng08 Can you answer whether this is intentional or not?

I'm also worried that strscpy doesn't add zero terminators, maybe we should use strncat(dst, src, buffer_size - 1) or use strncasecmp instead of strcastcmp when comparing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants