image

可以观察到 这部分来源于tmpfs,向上看log 注意查看与其有关的内容,

[14964|14964|tivetest_zygote] lgetxattr(path=0x71fce05edf(/mnt), name=0x71fce081b6(security.selinux), value=0x7fe5090680, size=1023) LR:0x71fcf8263c PC:0x71fcf826c8 SP:0x7fe5090440
[14964|14964|tivetest_zygote] lgetxattr(path=0x71fce05edf, name=0x71fce081b6, value=0x7fe5090680, size=1023, ret=20)
[14964|14964|tivetest_zygote] newfstatat(dirfd=-100, pathname=0x71fce05edf(/mnt), statbuf=0x7fe50909a0, flags=0x0) LR:0x71fcf80994 PC:0x71fcf80b20 SP:0x7fe5090890
[14964|14964|tivetest_zygote] newfstatat(dirfd=-100, pathname=0x71fce05edf, statbuf=0x7fe50909a0{dev=61, ino=1, nlink=15, mode=16877, uid=0, gid=1000, rdev=0, size=320, blksize=4096, blocks=0, atim={tv_sec=1761287984, tv_nsec=280430803}, mtim={tv_sec=1761285881, tv_nsec=142225616}, ctim={tv_sec=1761285881, tv_nsec=142225616}}, flags=0x0, ret=0)
[14964|14964|tivetest_zygote] openat(dirfd=-100, *pathname=0x71fce05edf(/mnt), flags=0xa4000(O_CLOEXEC|O_DIRECTORY|O_LARGEFILE), mode=0o000) LR:0x71fcf1cf24 PC:0x71fcf1cffc SP:0x7fe5090830
[14964|14964|tivetest_zygote] openat(dirfd=-100, *pathname=0x71fce05edf, flags=0xa4000(O_CLOEXEC|O_DIRECTORY|O_LARGEFILE), mode=0o000, ret=42)
[14964|14964|tivetest_zygote] fcntl(fd=42, cmd=2, arg=1) LR:0x71fcf13e1c PC:0x71fcf13e80 SP:0x7fe5090900
[14964|14964|tivetest_zygote] fcntl(fd=42, cmd=2, arg=1, ret=0)
[14964|14964|tivetest_zygote] getdents64(fd=42, dirp=0x7335e88858, count=2048) LR:0x71fcf83954 PC:0x71fcf83a70 SP:0x7fe5090a20
[14964|14964|tivetest_zygote] getdents64(fd=42, dirp=0x7335e88858(fd=1, events=0, revents=0), count=0, ret=11780)
[14964|14964|tivetest_zygote] getuid() LR:0x74c35d7e54 PC:0x74b898ceb8 SP:0x7fe508f0c0
[14964|14964|tivetest_zygote] getuid(ret=10071)
[14964|14964|tivetest_zygote] writev(fd=5, *iov=0x7fe508f0c0(
    iov_0=(base=0x7fe508f108(\x00t:\x03=\xfbh2}\x0a3), buflen=0xb)
    iov_1=(base=0x7fe508f2cc(\x06), buflen=0x1)
    iov_2=(base=0x71fce092e5(NTRLog\x00), buflen=0x7)
    iov_3=(base=0x7fe50905c0(tmpfs permission loophole detected\x00), buflen=0x23)

第一个片段,首先检测/mnt的selinux上下文,然后 用newfstatat 查看属性 再用open带着O_CLOEXEC|O_DIRECTORY|O_LARGEFILE去打开遍历/mnt

[14964|14964|tivetest_zygote] writev(fd=5, *iov=0x7fe508f0c0, iovcnt=4, ret=54)
[14964|14964|tivetest_zygote] close(fd=42) LR:0x71fcf1cf24 PC:0x71fcf1cffc SP:0x7fe5090940
[14964|14964|tivetest_zygote] close(fd=42, ret=0)
[14964|14964|tivetest_zygote] lgetxattr(path=0x71fce067b9(/mnt/obb), name=0x71fce081b6(security.selinux), value=0x7fe5090680, size=1023) LR:0x71fcf8263c PC:0x71fcf826c8 SP:0x7fe5090440
[14964|14964|tivetest_zygote] lgetxattr(path=0x71fce067b9, name=0x71fce081b6, value=0x7fe5090680, size=1023, ret=20)
[14964|14964|tivetest_zygote] newfstatat(dirfd=-100, pathname=0x71fce067b9(/mnt/obb), statbuf=0x7fe50909a0, flags=0x0) LR:0x71fcf80994 PC:0x71fcf80b20 SP:0x7fe5090890
[14964|14964|tivetest_zygote] newfstatat(dirfd=-100, pathname=0x71fce067b9, statbuf=0x7fe50909a0{dev=61, ino=10, nlink=2, mode=16877, uid=0, gid=1000, rdev=0, size=40, blksize=4096, blocks=0, atim={tv_sec=1761287984, tv_nsec=280430803}, mtim={tv_sec=1761285881, tv_nsec=135559088}, ctim={tv_sec=1761285881, tv_nsec=135559088}}, flags=0x0, ret=0)
[14964|14964|tivetest_zygote] openat(dirfd=-100, *pathname=0x71fce067b9(/mnt/obb), flags=0xa4000(O_CLOEXEC|O_DIRECTORY|O_LARGEFILE), mode=0o000) LR:0x71fcf1cf24 PC:0x71fcf1cffc SP:0x7fe5090830
[14964|14964|tivetest_zygote] openat(dirfd=-100, *pathname=0x71fce067b9, flags=0xa4000(O_CLOEXEC|O_DIRECTORY|O_LARGEFILE), mode=0o000, ret=42)
[14964|14964|tivetest_zygote] fcntl(fd=42, cmd=2, arg=1) LR:0x71fcf13e1c PC:0x71fcf13e80 SP:0x7fe5090900
[14964|14964|tivetest_zygote] fcntl(fd=42, cmd=2, arg=1, ret=0)
[14964|14964|tivetest_zygote] getdents64(fd=42, dirp=0x7335e88858, count=2048) LR:0x71fcf83954 PC:0x71fcf83a70 SP:0x7fe5090a20
[14964|14964|tivetest_zygote] getdents64(fd=42, dirp=0x7335e88858(fd=10, events=0, revents=0), count=0, ret=11780)
[14964|14964|tivetest_zygote] getuid() LR:0x74c35d7e54 PC:0x74b898ceb8 SP:0x7fe508f0c0
[14964|14964|tivetest_zygote] getuid(ret=10071)
[14964|14964|tivetest_zygote] writev(fd=5, *iov=0x7fe508f0c0(
    iov_0=(base=0x7fe508f108(\x00t:\x03=\xfbh=\x95\x113), buflen=0xb)
    iov_1=(base=0x7fe508f2cc(\x06), buflen=0x1)
    iov_2=(base=0x71fce092e5(NTRLog\x00), buflen=0x7)
    iov_3=(base=0x7fe50905c0(tmpfs permission loophole detected\x00), buflen=0x23)

第二个片段 同理 就是换个地方

最终检测点就是检查/mnt目录下有没有/sdcard等目录

有关于 getdents64 的教程及思路这里有 https://eunomia.dev/tutorials/24-hide/?h=getdents64#kernel-ebpf-program-implementation

开启Selinux之后 这两个地方就检测不到了

然后 就是其他地方

image

这个pty selinux默认拒绝 因为/dev/ptmx (redroid)是软连接的/dev/pts/ptmx 需要放行,但是针对连接/dev/pts/2的时候 selinux规则要允许open read 千万千万不能授权 write

allow untrusted_app devpts:chr_file { open read write ioctl getattr };
allowxperm untrusted_app devpts:chr_file ioctl 0x5430;
allowxperm untrusted_app devpts:chr_file ioctl 0x5431;
allow system_server untrusted_app_all_devpts:chr_file { open read };

image

image

有点奇怪这个做法 reuse 目录本来就是不存在的 (file_contexts注意到有针对这个目录设置的label) 暂时还不清楚怎么做到的(25.10.24)

image

[27391|27423|Thread-2] faccessat(dirfd=-100, pathname=0x7b5740988f(/mnt/reuse), mode=0x0(F_OK), flags=0x0) LR:0x7b57580790 PC:0x7b575807fc SP:0x7b58599110
[27391|27423|Thread-2] faccessat(dirfd=-100, pathname=0x7b5740988f, mode=0x0(F_OK), flags=0x0, ret=-2)
[27391|27423|Thread-2] getuid() LR:0x7e6f521e54 PC:0x7e7af20eb8 SP:0x7b58597730
[27391|27423|Thread-2] getuid(ret=10071)
[27391|27423|Thread-2] writev(fd=3, *iov=0x7b58597730(
    iov_0=(base=0x7b58597778(\x00\x1fk)\x86\xfbh\xed\xeb\xd4\x17), buflen=0xb)
    iov_1=(base=0x7b5859793c(\x03), buflen=0x1)
    iov_2=(base=0x7b574092e5(NTRLog\x00), buflen=0x7)
    iov_3=(base=0x7b58598c28(checker.cpp:1595#void FindMountInfoLoophole(): group id 502 /data/misc/profiles/ref/icu.nullptr.nativetest\x00), buflen=0x6b)
), iovcnt=4) LR:0x7e6f521fb8 PC:0x7e7af21618 SP:0x7b58597730


[27391|27423|Thread-2] faccessat(dirfd=-100, pathname=0x7b5740988f(/mnt/reuse), mode=0x0(F_OK), flags=0x0) LR:0x7b57580790 PC:0x7b575807fc SP:0x7b58599110
[27391|27423|Thread-2] faccessat(dirfd=-100, pathname=0x7b5740988f, mode=0x0(F_OK), flags=0x0, ret=-2)
[27391|27423|Thread-2] getuid() LR:0x7e6f521e54 PC:0x7e7af20eb8 SP:0x7b58597740
[27391|27423|Thread-2] getuid(ret=10071)
[27391|27423|Thread-2] writev(fd=3, *iov=0x7b58597740(
    iov_0=(base=0x7b58597788(\x00\x1fk)\x86\xfbh\x19~\xd6\x17), buflen=0xb)
    iov_1=(base=0x7b5859794c(\x03), buflen=0x1)
    iov_2=(base=0x7b574092e5(NTRLog\x00), buflen=0x7)
    iov_3=(base=0x7b58598c40(checker.cpp:1616#void FindMountInfoLoophole(): Missing peer group 1\x00), buflen=0x44)

现推测估计是开发的时候 循环里面加了个函数所以检测 group id 的时候一直来回报 忽略 /mnt/reuse 即可 主要还是挂载,现在把用户态搞定前三项检测应该就都能过掉了(25.10.25)


image25.10.28