d4rken-org / sdmaid

SD Maid is an Android app that helps you manage files and apps.
https://play.google.com/store/apps/details?id=eu.thedarken.sdm
1.51k stars 745 forks source link

Root relinquished due to `mount: '/system' not in /proc/mounts"` #2110

Closed toledofaustino85 closed 5 years ago

toledofaustino85 commented 5 years ago

LineageOS 15.1 with addonsu (not using magisk)

All apps with root (ex: totalcommander) work fine, but SD Maid :'(

Root accesos granted, of course, but SD Maid can't access "/" nor "/data" system cleaner don't delete anr, tombstones, etc...

1541416679054 D/Debug: Fingerprint: xiaomi/tissot/tissot_sprout:8.0.0/OPR1.170623.026/8.1.10:user/release-keys
1541416679055 D/Debug: ro.build.version.codename=REL
1541416679055 D/Debug: ro.build.version.incremental=b7d49dc8e6
1541416679055 D/Debug: ro.build.version.base_os=
1541416679055 D/Debug: ro.build.version.release=8.1.0
1541416679055 D/Debug: ro.build.display.id=lineage_tissot-userdebug 8.1.0 OPM7.181005.003 b7d49dc8e6
1541416679055 D/Debug: ro.product.name=lineage_tissot
1541416679056 D/Debug: ro.product.device=tissot
1541416679056 D/Debug: ro.product.board=MSM8953
1541416679056 D/Debug: ro.product.manufacturer=Xiaomi
1541416679056 D/Debug: ro.product.brand=Xiaomi
1541416679056 D/Debug: ro.product.model=Mi A1
1541416679056 D/Debug: ro.bootloader=MSM8953_TISSOT2.0_20180712204115
d4rken commented 5 years ago

What does the overview page show?

Please record a debug log of SD Maid checking root access: https://github.com/d4rken/sdmaid-public/wiki/Reporting-a-bug#debugrun-log

toledofaustino85 commented 5 years ago

I have sent you the requested log file by email. I have read the log and I think the problem is when SD Maid tries to "install" toybox_sdm in /system/xbin. Many phones have (including mine) the system partition read-only.

LineageOS includes by default a toybox binary preinstalled, maybe this would be enough for SD Maid to works (simply run toybox, I can send you the binary if you want it for testing purposes) Or maybe is posible to run toybox_sdm from another folder wirhout too much code changes.

I'll try later a possible workaround: To create a symlink from "/data/data/eu.thedarken.sdm/files/toybox_sdm" to "/system/xbin/toybox_sdm" Maybe it works but it don't is an easy and suitable solution for all people.

Thanks for your work.

d4rken commented 5 years ago

It's indeed related to the binaries, not root itself. In the log we see:

1541416689334 W/BinaryInstaller: We have root, but no complete applet source to use it with. Relinquishing root access!

A bit further up in the log we can see the required applets and their current state:

1541416689169 I/BinaryInstaller: Final applet: Applet(call=/data/user/0/eu.thedarken.sdm/files/toybox_sdm chmod, version=toybox 0.7.3-37-g04940678c81a, type=INTERNAL, compat=ALL)
1541416689169 I/BinaryInstaller: Final applet: Applet(call=/data/user/0/eu.thedarken.sdm/files/toybox_sdm mv, version=toybox 0.7.3-37-g04940678c81a, type=INTERNAL, compat=ALL)
1541416689169 I/BinaryInstaller: Final applet: Applet(call=/data/user/0/eu.thedarken.sdm/files/toybox_sdm pidof, version=toybox 0.7.3-37-g04940678c81a, type=INTERNAL, compat=ALL)
1541416689169 I/BinaryInstaller: Final applet: Applet(call=/data/user/0/eu.thedarken.sdm/files/toybox_sdm touch, version=toybox 0.7.3-37-g04940678c81a, type=INTERNAL, compat=ALL)
1541416689169 I/BinaryInstaller: Final applet: Applet(call=/data/user/0/eu.thedarken.sdm/files/toybox_sdm cp, version=toybox 0.7.3-37-g04940678c81a, type=INTERNAL, compat=ALL)
1541416689170 I/BinaryInstaller: Final applet: Applet(call=/data/user/0/eu.thedarken.sdm/files/toybox_sdm find, version=toybox 0.7.3-37-g04940678c81a, type=INTERNAL, compat=ALL)
1541416689170 I/BinaryInstaller: Final applet: Applet(call=/data/user/0/eu.thedarken.sdm/files/toybox_sdm rm, version=toybox 0.7.3-37-g04940678c81a, type=INTERNAL, compat=ALL)
1541416689170 I/BinaryInstaller: Final applet: Applet(call=/data/user/0/eu.thedarken.sdm/files/toybox_sdm test, version=toybox 0.7.3-37-g04940678c81a, type=INTERNAL, compat=ALL)
1541416689170 I/BinaryInstaller: Final applet: Applet(call=/data/user/0/eu.thedarken.sdm/files/toybox_sdm ps, version=toybox 0.7.3-37-g04940678c81a, type=INTERNAL, compat=ALL)
1541416689171 I/BinaryInstaller: Final applet: Applet(call=/data/user/0/eu.thedarken.sdm/files/toybox_sdm echo, version=toybox 0.7.3-37-g04940678c81a, type=INTERNAL, compat=ALL)
1541416689171 I/BinaryInstaller: Final applet: Applet(call=/data/user/0/eu.thedarken.sdm/files/toybox_sdm du, version=toybox 0.7.3-37-g04940678c81a, type=INTERNAL, compat=ALL)
1541416689171 I/BinaryInstaller: Final applet: Applet(call=/data/user/0/eu.thedarken.sdm/files/toybox_sdm kill, version=toybox 0.7.3-37-g04940678c81a, type=INTERNAL, compat=ALL)
1541416689171 I/BinaryInstaller: Final applet: Applet(call=/data/user/0/eu.thedarken.sdm/files/toybox_sdm chown, version=toybox 0.7.3-37-g04940678c81a, type=INTERNAL, compat=ALL)
1541416689171 I/BinaryInstaller: Final applet: Applet(call=/data/user/0/eu.thedarken.sdm/files/toybox_sdm cat, version=toybox 0.7.3-37-g04940678c81a, type=INTERNAL, compat=ALL)
1541416689171 I/BinaryInstaller: Final applet: Applet(call=/data/user/0/eu.thedarken.sdm/files/toybox_sdm rmdir, version=toybox 0.7.3-37-g04940678c81a, type=INTERNAL, compat=ALL)
1541416689172 I/BinaryInstaller: Final applet: Applet(call=/data/user/0/eu.thedarken.sdm/files/toybox_sdm xargs, version=toybox 0.7.3-37-g04940678c81a, type=INTERNAL, compat=ALL)
1541416689172 I/BinaryInstaller: Final applet: Applet(call=/data/user/0/eu.thedarken.sdm/files/toybox_sdm stat, version=toybox 0.7.3-37-g04940678c81a, type=INTERNAL, compat=ALL)
1541416689172 I/BinaryInstaller: Final applet: Applet(call=/data/user/0/eu.thedarken.sdm/files/toybox_sdm mount, version=toybox 0.7.3-37-g04940678c81a, type=INTERNAL, compat=USER, outputType=OutputType.DefaultVariant())
1541416689172 I/BinaryInstaller: Final applet: Applet(call=/data/user/0/eu.thedarken.sdm/files/toybox_sdm mkdir, version=toybox 0.7.3-37-g04940678c81a, type=INTERNAL, compat=ALL)
1541416689172 I/BinaryInstaller: Final applet: Applet(call=/data/user/0/eu.thedarken.sdm/files/toybox_sdm grep, version=toybox 0.7.3-37-g04940678c81a, type=INTERNAL, compat=ALL)

If we look closer we see that we almost have a complete set, most come from the toybox that ships with SD Maid INTERNAL and is run from it's own files dir. Looking closer we see that the issue is the mount applet.

1541416689172 I/BinaryInstaller: Final applet: Applet(call=/data/user/0/eu.thedarken.sdm/files/toybox_sdm mount, version=toybox 0.7.3-37-g04940678c81a, type=INTERNAL, compat=USER, outputType=OutputType.DefaultVariant())

The mount applet doesn't work with root, but why? SD Maids internal toybox mount is rejected due to this error:

1541416685363 V/RXS:Harvester:Error: mount: '/system' not in /proc/mounts

Looking further system one (/system/bin/toybox mount) is rejected due to the same error.

SD Maid then think's it is a permission issue (I don't think it is), and copies the internal binary to /tmp_sdm/toybox but this obviously doesn't help.

I have read the log and I think the problem is when SD Maid tries to "install" toybox_sdm in /system/xbin. Many phones have (including mine) the system partition read-only.

If necessary SD Maid will re-mount the partition to write the file there if it is the only way to get it to work.

LineageOS includes by default a toybox binary preinstalled, maybe this would be enough for SD Maid to works (simply run toybox, I can send you the binary if you want it for testing purposes) Or maybe is posible to run toybox_sdm from another folder wirhout too much code changes.

I'm not sure the folder from which it is executed is the issue in this case, it is in a lot of other cases though, e.g. KNOX & Samsung, which is why SD Maid tries it. SD Maid already tries alternative locations, including "/system/xbin":

 public List<SDMFile> getAlternativeLocations() {
        final List<SDMFile> nativeLocations = new ArrayList<>();
        if (ApiHelper.hasMarshmallow()) {
            nativeLocations.add(JavaFile.build("/system/xbin/toybox"));
            nativeLocations.add(JavaFile.build("/system/bin/toybox"));
        } else {
            nativeLocations.add(JavaFile.build("/system/xbin/toolbox"));
            nativeLocations.add(JavaFile.build("/system/bin/toolbox"));
        }

        nativeLocations.add(JavaFile.build("/system/xbin/busybox"));
        nativeLocations.add(JavaFile.build("/system/bin/busybox"));

        nativeLocations.add(JavaFile.build("/sbin/toybox"));
        nativeLocations.add(JavaFile.build("/su/xbin/toybox"));
        nativeLocations.add(JavaFile.build("/su/bin/toybox"));

        nativeLocations.add(JavaFile.build("/sbin/busybox"));
        nativeLocations.add(JavaFile.build("/su/xbin/busybox"));
        nativeLocations.add(JavaFile.build("/su/bin/busybox"));
        return nativeLocations;
    }
d4rken commented 5 years ago

TLDR: Get a mount applet to work with root without error.

toledofaustino85 commented 5 years ago

Ok, now I understand the problem. mount works perfectly but in my phone (and many others) /system is read-only and can't be remounted as writable. If I tries to run "mount -o rw,remount /system" I receive in response "'/system' not in /proc/mounts" In fact, to make some system patches like remapping the capacitive buttons I do flashable zips (with TWRP).

I guess (for ex.) cleaning "/data/data" doesn't need a writable system partition so I hope you can made a fix.

Thanks for your time.

toledofaustino85 commented 5 years ago

My mount points

rootfs on / type rootfs (rw,seclabel)
/dev/root on / type ext4 (ro,seclabel,relatime,data=ordered)
tmpfs on /dev type tmpfs (rw,seclabel,nosuid,relatime,size=1817972k,nr_inodes=454493,mode=755)
devpts on /dev/pts type devpts (rw,seclabel,relatime,mode=600)
proc on /proc type proc (rw,relatime,gid=3009,hidepid=2)
sysfs on /sys type sysfs (rw,seclabel,relatime)
selinuxfs on /sys/fs/selinux type selinuxfs (rw,relatime)
none on /acct type cgroup (rw,relatime,cpuacct)
debugfs on /sys/kernel/debug type debugfs (rw,seclabel,relatime)
tmpfs on /mnt type tmpfs (rw,seclabel,relatime,size=1817972k,nr_inodes=454493,mode=755,gid=1000)
none on /config type configfs (rw,relatime)
none on /dev/cpuctl type cgroup (rw,relatime,cpu)
none on /dev/cpuset type cgroup (rw,relatime,cpuset,noprefix,release_agent=/sbin/cpuset_release_agent)
pstore on /sys/fs/pstore type pstore (rw,seclabel,relatime)
none on /dev/bfqio type cgroup (rw,relatime,bfqio)
/dev/block/mmcblk0p27 on /persist type ext4 (rw,seclabel,nosuid,nodev,noatime,data=ordered)
/dev/block/mmcblk0p13 on /dsp type ext4 (ro,seclabel,nosuid,nodev,relatime,data=ordered)
/dev/block/mmcblk0p1 on /firmware type vfat (ro,context=u:object_r:firmware_file:s0,relatime,uid=1000,gid=1000,fmask=0337,dmask=0227,codepage=437,iocharset=utf8,shortname=lower,errors=remount-ro)
tmpfs on /storage type tmpfs (rw,seclabel,relatime,size=1817972k,nr_inodes=454493,mode=755,gid=1000)
tracefs on /sys/kernel/debug/tracing type tracefs (rw,seclabel,relatime)
adb on /dev/usb-ffs/adb type functionfs (rw,relatime)
/dev/block/dm-1 on /data type ext4 (rw,seclabel,nosuid,nodev,noatime,noauto_da_alloc,data=ordered)
/data/media on /mnt/runtime/default/emulated type sdcardfs (rw,nosuid,nodev,noexec,noatime,fsuid=1023,fsgid=1023,gid=1015,multiuser,mask=6,derive_gid)
/data/media on /storage/emulated type sdcardfs (rw,nosuid,nodev,noexec,noatime,fsuid=1023,fsgid=1023,gid=1015,multiuser,mask=6,derive_gid)
/data/media on /mnt/runtime/read/emulated type sdcardfs (rw,nosuid,nodev,noexec,noatime,fsuid=1023,fsgid=1023,gid=9997,multiuser,mask=23,derive_gid)
/data/media on /mnt/runtime/write/emulated type sdcardfs (rw,nosuid,nodev,noexec,noatime,fsuid=1023,fsgid=1023,gid=9997,multiuser,mask=7,derive_gid)
/dev/block/vold/public:179_65 on /mnt/media_rw/0000-0000 type sdfat (rw,dirsync,nosuid,nodev,noexec,noatime,fs=exfat,uid=1023,gid=1023,fmask=0007,dmask=0007,allow_utime=0020,codepage=cp437,iocharset=utf8,namecase=0,symlink=0,bps=512,errors=remount-ro)
/mnt/media_rw/0000-0000 on /mnt/runtime/default/0000-0000 type sdcardfs (rw,nosuid,nodev,noexec,noatime,fsuid=1023,fsgid=1023,gid=1015,mask=6)
/mnt/media_rw/0000-0000 on /storage/0000-0000 type sdcardfs (rw,nosuid,nodev,noexec,noatime,fsuid=1023,fsgid=1023,gid=1015,mask=6)
/mnt/media_rw/0000-0000 on /mnt/runtime/read/0000-0000 type sdcardfs (rw,nosuid,nodev,noexec,noatime,fsuid=1023,fsgid=1023,gid=9997,mask=18)
/mnt/media_rw/0000-0000 on /mnt/runtime/write/0000-0000 type sdcardfs (rw,nosuid,nodev,noexec,noatime,fsuid=1023,fsgid=1023,gid=9997,mask=18)

There is no /system to remount Try search in google "android /system not in /proc/mounts" (for ex.), is a common "problem" Please tell me if I can help in any way.

d4rken commented 5 years ago

Similar issue as https://github.com/d4rken/sdmaid-public/issues/1005

Ok, now I understand the problem. mount works perfectly but in my phone (and many others) /system is read-only and can't be remounted as writable.

It doesn't work perfectly because it doesn't show /system which definitely exists as mount point. It also can be remounted AFAIK.

There is no /system to remount

It's there, just not listed, which is the issue here. Some mount's seem to show it and some don't, e.g. if you install a busybox from Google Play (e.g. Stericson's) I'd bet that it works.

If I tries to run "mount -o rw,remount /system" I receive in response "'/system' not in /proc/mounts"

The actual test command is mount -o ro,remount '/system' (ro-read-only) which doesn't change anything, but allows SD Maid to make sure mount works correctly.

All apps with root (ex: totalcommander) work fine, but SD Maid :'(

What does this app say if you try to remount /system?

I guess (for ex.) cleaning "/data/data" doesn't need a writable system partition so I hope you can made a fix.

That's true. The check is there to determine wether SD Maid is subject to restrictions, experience has shown that trying to remount /system (even only to ro) is a good indicator for SELINUX/KNOX restrictions. It's also there because AppControl needs remounting of /system for uninstalling system apps.

Theoretically SD Maid could continue on and then just have AppControl fail if remounting doesn't work...

But there will be side effects on other ROMs. On some ROMs this error is what triggers SD Maid to try alternative busybox/toybox setups to circumvent SELINUX/KNOX, if we ignore this error, it could mean that SD Maid works on your ROM, but no longer on other ROMs...

Or we could run through all fallback options like it now happens, but then at the end if the error persists ignore it... will have to check how much work this would be... :unamused:

On the other hand this could very well be a ROM/root setup issue...

Can you try Magisk and also installing an extra busybox or toybox?

toledofaustino85 commented 5 years ago

Sorry, but you are wrong.

It doesn't work perfectly because it doesn't show /system which definitely exists as mount point. It also can be remounted AFAIK.

It's there, just not listed, which is the issue here. Some mount's seem to show it and some don't, e.g. if you install a busybox from Google Play (e.g. Stericson's) I'd bet that it works.

No, /system doesn't exists as mount point and can't be remounted. It's not a mount/toybox/busybox issue, I wrote you the result of cat /proc/mounts

In my phone like many others /system is only a folder of / "/" IS THE MOUNT POINT

If I run "mount -o rw,remount /system" (or -o ro) I receive an error in response, BUT if I run "mount -o rw,remount /" there is no error in response... and after... I CAN WRITE in /system

What does this app say if you try to remount /system?

After "mount -o rw,remount /" TotalCommander CAN write /system perfectly

Finally, fstab line in my old MotoG3. SD Maid works wondeful fine: /dev/block/bootdevice/by-name/system /system ext4 ro,barrier=1

fstab line in A1, :'( /dev/block/bootdevice/by-name/system / ext4ro,barrier=1,discard wait,slotselect

I can write /system at my will remounting /, but (as I said before) I prefer to make flashable zips for my little patches.

Solution for SD Maid: Maybe testing "mount -o ro,remount /" ?

I hope be helpful

Thanks for your time.

d4rken commented 5 years ago

No, /system doesn't exists as mount point and can't be remounted. It's not a mount/toybox/busybox issue, I wrote you the result of cat /proc/mounts

In my phone like many others /system is only a folder of / "/" IS THE MOUNT POINT

If I run "mount -o rw,remount /system" (or -o ro) I receive an error in response, BUT if I run "mount -o rw,remount /" there is no error in response... and after... I CAN WRITE in /system

Okay now I get it, makes sense :+1:

Solution for SD Maid: Maybe testing "mount -o ro,remount /" ?

I think that's a good idea. :ok_hand: If the normal check fails we check for this and if it passes, SD Maid accepts the mount command.

We should probably also check the AppControl remounting routine when it uninstalls systems apps, if it tries /system then that would probably fail :confused: ...

toledofaustino85 commented 5 years ago

Addendum (maybe helps)

An example. If I want to make a flashable zip to modify /system/etc/hosts I must use /system/system/etc/hosts as path

After kernel mounts /system partition as / this translates to /system/etc/hosts

As I said you before "my" /system is a folder of /, the mount point of system partition. But in "classic" phones like my MotoG3 system is mounted as /system

You can download the LOS addonsu to see a real example. The install script checks the "system type" and acts accordingly

https://mirrorbits.lineageos.org/su/20180912/addonsu-15.1-arm64-signed.zip

As I can see you don't sleep (yes, we have the same timezone)

d4rken commented 5 years ago

You can download the LOS addonsu to see a real example. The install script checks the "system type" and acts accordingly https://mirrorbits.lineageos.org/su/20180912/addonsu-15.1-arm64-signed.zip

The install scripts help, I can could check the prop fields too. :+1:

As I can see you don't sleep (yes, we have the same timezone)

:sleeping: :grin:

toledofaustino85 commented 5 years ago

The install scripts help, I can could check the prop fields too. +1

YESSSSS, I did not remember it. In my A1 "getprop ro.build.system_root_image" returns "true" In my old MotoG3 returns nothing.

d4rken commented 5 years ago

Hm

My pixel 2:

walleye:/ $ getprop ro.build.system_root_image                                                                         
true

but

walleye:/ $ cat /proc/mounts | grep system                                                                             
/dev/block/sda43 /system_root ext4 ro,seclabel,relatime,block_validity,delalloc,barrier,user_xattr 0 0
/dev/block/sda43 /system ext4 ro,seclabel,relatime,block_validity,delalloc,barrier,user_xattr 0 0
/dev/block/sda43 /sbin/.core/mirror/system ext4 ro,seclabel,relatime,block_validity,delalloc,barrier,user_xattr 0 0
d4rken commented 5 years ago

There is this previous issue which lead to the failure check on ... not in /proc/mounts.

https://github.com/d4rken/sdmaid-public/issues/1005

AFAIK it's the same symptoms, but there it was fixed by using a different applet.

How do we differentiate from that issue?

d4rken commented 5 years ago

AppControl is not affected btw, it automatically determines the matching mount going for the first one that matches a path, if nothing is found it should end up with /.

d4rken commented 5 years ago

@toledofaustino85 I've got something ready, would you be willing to test it? If so, send me a quick mal to support@darken.eu mentioning this ticket, :relaxed: .

toledofaustino85 commented 5 years ago

Hm

My pixel 2:

walleye:/ $ getprop ro.build.system_root_image
true

but

walleye:/ $ cat /proc/mounts | grep system
/dev/block/sda43 /system_root ext4 ro,seclabel,relatime,block_validity,delalloc,barrier,user_xattr 0 0 /dev/block/sda43 /system ext4 ro,seclabel,relatime,block_validity,delalloc,barrier,user_xattr 0 0 /dev/block/sda43 /sbin/.core/mirror/system ext4 ro,seclabel,relatime,block_validity,delalloc,barrier,user_xattr 0 0

This is because you have a "systemless root" (magisk maybe?) installed. https://www.xda-developers.com/root-is-now-available-for-the-google-pixel-and-pixel-xl/ I think the former link will be self explanatory.

The LOS addonsu is a "full" root, old phones (like my MotoG3) can remount rw "/system" and new phones (like my A1) can remount rw "/" With "systemless root" we must remount rw "/system_root"

I hope this will help.

toledofaustino85 commented 5 years ago

AFAIK "systemless root" allways mounts "/system_root" so, this is what I would do:

Try to remount /system_root if error check getprop ro.build.system_root_image if NOT "true" try to remount /system else try to remount "/"

I hope this will help.

d4rken commented 5 years ago

Yeah I use Magisk.

My current idea:

That's based on the idea that trying to remount /system should still be the default...

Does /system_root have to be used instead of /system when uninstalling system apps?

d4rken commented 5 years ago

I think you are on the right track. Your idea sounds better than mine.

So depending on the getprop we try to remount either /system_root or /system. If we don't have a system_root_image then we fail right there, if we have one we also try / and only if that fails we fail the test.

d4rken commented 5 years ago

Maybe we should still check /system first (for compatibility reasons) in case ro.build.system_root_image is unreliable on some ROMs, then the test would still pass if /system works. Otherwise a bad ro.build.system_root_image would lead us down the wrong path.

toledofaustino85 commented 5 years ago

Does /system_root have to be used instead of /system when uninstalling system apps?

Extracted from https://www.xda-developers.com/root-is-now-available-for-the-google-pixel-and-pixel-xl/

– The root / directory for Android is now part of the system partition, instead of the boot partition (initramfs)

This apply to all new phones like my A1

The system partition is mounted to /system_root and /system itself sim-linked to /system_root/system. And finally his kernel patch modifies the kernel such that it ignores the command sent from the bootloader which would ordinarily enforce dm-verity.

However, there are some rather trivial issues introduced with this new method. Certain apps, such as FlashFire or AdAway (both of which we’ve shown don’t work) expect the system partition to be mounted as /system, not /system_root, and will need to be updated accordingly. Although, you can try remounting system as such

mount -o rw,remount /system_root

Which should allow you to write to /system.

So the answer to your question is that after remounting /system_root you can write /system normally

AFAIK

d4rken commented 5 years ago

So the answer to your question is that after remounting /system_root you can write /system normally

/system is not a symlink on my pixel2 with magisk, but it's own mount. I can remount /system_root and any modifcations made there is reflected in /system, but /system is still read-only. So I have to remount the path I'll actually write to.

walleye:/ # mount -o rw,remount /system_root                                                                           
walleye:/ # mount | grep system                                                                                        
/dev/block/sda43 on /system_root type ext4 (rw,seclabel,relatime,block_validity,delalloc,barrier,user_xattr)
/dev/block/sda43 on /system type ext4 (ro,seclabel,relatime,block_validity,delalloc,barrier,user_xattr)
/dev/block/sda43 on /sbin/.core/mirror/system type ext4 (ro,seclabel,relatime,block_validity,delalloc,barrier,user_xattr)
walleye:/ # cd /system
walleye:/system # touch cake2
touch: 'cake2': Read-only file system
toledofaustino85 commented 5 years ago

/system is not a symlink on my pixel2 with magisk, but it's own mount. I can remount /system_root and any modifcations made there is reflected in /system, but /system is still read-only. So I have to remount the path I'll actually write to.

Hm, maybe there are slight differences between supersu and magisk. I don't use any of them and I haven't studied them in depth. Bad news, this complicates the "rooting-android-ecosystem" :-(

I have done some beta-testing. With your new build I have successfully created and deleted a subfolder in /system (using sd maid Explorer) ...and AppCleaner works fine.

d4rken commented 5 years ago

For my phone the default case of trying /system would just work.

I'll code your proposed logic now, and send you a new test version. The mount test doesn't need to write anything just needs to confirm that remounting is possible so that all other operations can rely on certain expected behavior.

I have done some beta-testing. With your new build I have successfully created and deleted a subfolder in /system (using sd maid Explorer) ...and AppCleaner works fine.

SD Maid has Storage classes that reflect distinct locations, one such class is /system. Each Storage gets mapped to a mount-point which is then used when the storage needs to be remounted. We'd need to check that that routine correctly handles these edge cases. Apparently it already does in your case. The code is unrelated to the code we are currently touching. I've made an extra TODO for this though #2135 just to confirm how it currently works.

toledofaustino85 commented 5 years ago

I guess we are in the right way. As you already know I can do beta-testing for you with a MotoG3 (full root system mounted as /system) and Mi A1 (full root system mounted as /)

Thanks for your work

toledofaustino85 commented 5 years ago

Hm, sometimes simple is better. If remounting /system works with your phone (magisk) and remounting "/" works with my phone (LOS) maybe trying both mounts will be enough for the vast majority of phones.

What do you think?

d4rken commented 5 years ago

Hm, the extra check won't cost too much, one more command in an already open shell. Though the primary purpose of this check is to ensure the mount applet command performs on what ever "system" is.

So the edge case is the elusive /system_root + /system symlink? Likely early SuperSU versions?

d4rken commented 5 years ago

The checks purpose is to filter out bad applets such that SD Maid can then try to use/setup a different applet.

Cmd.Result normalResult = Cmd.builder(directCall + " -o ro,remount '/system'").execute(rootSession);
boolean trySystemLess = false;
boolean ourAppletOK = normalResult.getExitCode() == Cmd.ExitCode.OK;
for (String line : normalResult.merge()) {
    if (line.contains("no /etc/mtab")) {
        ourAppletOK = false;
        break;
    } else if (PATTERN_SYSTEMLESS_ISSUE.matcher(line).matches()) {
        ourAppletOK = false;
        trySystemLess = ApiHelper.hasMarshmallow();
    }
}

// https://github.com/d4rken/sdmaid-public/issues/2110
if (trySystemLess) {
    Cmd.Result prop = Cmd.builder("getprop ro.build.system_root_image").execute(rootSession);

    if (prop.getOutput().contains("true")) {
        ourAppletOK = Cmd.builder(directCall + " -o ro,remount '/system_root'")
                .execute(rootSession)
                .getExitCode() == Cmd.ExitCode.OK;

        if (!ourAppletOK) {
            ourAppletOK = Cmd.builder(directCall + " -o ro,remount '/'")
                    .execute(rootSession)
                    .getExitCode() == Cmd.ExitCode.OK;
        }
    }
}

if (ourAppletOK) {
    compat = compat == Compat.USER ? Compat.ALL : Compat.ROOT;
    if (outputType == null) outputType = determineVariant(normalResult.getOutput());
}
toledofaustino85 commented 5 years ago

Hm, about your code:

ro.build.system_root_image (true) and "systemless root" aren't the same. Systemless root is a method of rooting the device without touching system partition (enginered due new restrictions and checks made to android) Magisk is open source but i don't have enough time to read his code so I have done some live-testing in my MotoG3. I've installed latest Magisk (17.3) and there is no /system_root mount point, however system partition is mounted as /system, so your code should runs fine. BUT my MotoG3 is on Marshmallow so we need some additional testing with a NON-ro.build.system_root_image (like MotoG3), android 7.1 or higher and Magisk.

I personally would prefer the following logic: Try /system_root and if ok we have a "systemless root" and possibly a "system_root_image=true" device. This check is only for information purposses. Check ro.build.system_root_image if NOT TRUE try /system (valid for old devices with "full root" and possibly for all devices with Magisk) else try "/" (valid for new devices with "full root") AFAIK this would works.

What do you think?

So the edge case is the elusive /system_root + /system symlink? Likely early SuperSU versions?

Yes, ...according to the XDA article that I linked before but I have no idea about SuperSU and we would need to do extra testing (or forget it) :-P

I hope this will help.

d4rken commented 5 years ago

I don't think the suggested logic is better in this case, what you propose would be better for when SD Maid has to actually determine what to remount to e.g. uninstall system apps, see #2135.

Currently we want to write something that devices whether the mount applet is usable, as quickly as possible. To do this we attempt to remount "the system partition".

In that regard I think we should always test /system first because it's the most common setup which means a faster test. No error on remount /system? => Applet is OK.

We could simplify the process and just attempt to remount "/" as that is available on every ROM, but "/system" or "/system_root" is more interesting and if we know it works with that there is less of a chance for something to go wrong. I don't remember which Android version it was but there were some security restrictions that prevented SD Maid from remounting when running the mount applet from it's own local directory, and this restriction only triggered when trying to remount "the system partition".

If this now works for you can you close this? We can then move over to #2135 and implement your algorithm there. This ticket/change is to throw stuff at the mount applet that could break it so we can accept/reject.

toledofaustino85 commented 5 years ago

I've tested latest beta (dcc07137c) in both MotoG3 (full root) and Mi A1 (full root) with same result, works fine. I've sent you a logfile by email.

Yes, I'll close this issue and we can move over to #2135. Thanks you for all.

paulyc commented 5 years ago

This fixed it for me with Magisk: mount -o bind /system /system

davidblus commented 4 years ago
  • Old phones with systemless root (magisk and ro.build.system_root_image not true) (if they exist) Hm, I have no idea :-(

Maybe it's a choice.

mount -o bind /system /system

I make it to put the certificate to the "/system/etc/security/cacerts" for systemless root!

mkdir /data/local/tmp/system
mount -o bind /system /data/local/tmp/system
mount -o rw,remount /data/local/tmp/system

Then I can put the certificate file to the "/data/local/tmp/system/etc/security/cacerts".

It will be removed by reboot!!!