在 Android SDK AVD API 23 x86_64 的系统镜像上 android_dlopen_ext 的 ANDROID_DLEXT_USE_LIBRARY_FD 参数无法正常使用
近期在测试 Android 纯内存无文件加载 elf/so 方案的低版本兼容性时,发现在 AVD API 23 (system-images/android-23/google_apis/x86_64) 上 ANDROID_DLEXT_USE_LIBRARY_FD 无法正常工作:尝试 android_dlopen_ext 一个 fd, 得到以下报错
显然这是一个通过 open+unlink 得到的普通 fd.(注:一开始用的 ashmem, 发现此问题后尝试 open+unlink 交叉验证寻找问题)
在 cs.android.com 搜索 "from verneed" 可以发现是 位于 linker 的 VersionTracker::init_verneed 函数。
为排查问题,将 linker 的
近期在测试 Android 纯内存无文件加载 elf/so 方案的低版本兼容性时,发现在 AVD API 23 (system-images/android-23/google_apis/x86_64) 上 ANDROID_DLEXT_USE_LIBRARY_FD 无法正常工作:尝试 android_dlopen_ext 一个 fd, 得到以下报错
dlopen failed: cannot find "libc.so" from verneed[1] in DT_NEEDED list for "/data/data/com.example.test.app.syscalldemo/cache/tmpfs-629392441675200/libmmkv.so (deleted)"
显然这是一个通过 open+unlink 得到的普通 fd.(注:一开始用的 ashmem, 发现此问题后尝试 open+unlink 交叉验证寻找问题)
在 cs.android.com 搜索 "from verneed" 可以发现是 位于 linker 的 VersionTracker::init_verneed 函数。
为排查问题,将 linker 的
__dl_g_ld_debug_verbosity 符号设置为 3, 可以得到以下输出。I [ 'libmmkv.so' find_loaded_library_by_soname returned false (*candidate=n/a@0x0). Trying harder...]
I name /data/data/com.example.test.app.syscalldemo/cache/tmpfs-629392441675200/libmmkv.so (deleted): allocated soinfo @ 0x7f6265742d98
W [ linking /data/data/com.example.test.app.syscalldemo/cache/tmpfs-629392441675200/libmmkv.so (deleted) ]
D DEBUG: si->base = 0x7f62678f1000 si->flags = 0x40000000
...
D DEBUG: si->base = 0x7f62678f1000, si->strtab = 0x7f62678f7bd4, si->symtab = 0x7f62678f1330
I [ 'liblog.so' find_loaded_library_by_soname returned false (*candidate=/system/lib64/liblog.so@0x7f6271aa85d8). Trying harder...]
I library "liblog.so" is already loaded under different name/path "/data/data/com.example.test.app.syscalldemo/cache/tmpfs-629392441675200/libmmkv.so (deleted)" - will return existing soinfo
I [ 'libz.so' find_loaded_library_by_soname returned false (*candidate=/system/lib64/libz.so@0x7f6271a9f008). Trying harder...]
I library "libz.so" is already loaded under different name/path "/data/data/com.example.test.app.syscalldemo/cache/tmpfs-629392441675200/libmmkv.so (deleted)" - will return existing soinfo
I [ 'libm.so' find_loaded_library_by_soname returned false (*candidate=/system/lib64/libm.so@0x7f6271aa21f8). Trying harder...]
I library "libm.so" is already loaded under different name/path "/data/data/com.example.test.app.syscalldemo/cache/tmpfs-629392441675200/libmmkv.so (deleted)" - will return existing soinfo
I [ 'libc.so' find_loaded_library_by_soname returned false (*candidate=/system/lib64/libc.so@0x7f6271aa2008). Trying harder...]
I library "libc.so" is already loaded under different name/path "/data/data/com.example.test.app.syscalldemo/cache/tmpfs-629392441675200/libmmkv.so (deleted)" - will return existing soinfo
D DEBUG: cannot find "libc.so" from verneed[1] in DT_NEEDED list for "/data/data/com.example.test.app.syscalldemo/cache/tmpfs-629392441675200/libmmkv.so (deleted)"
I /data/data/com.example.test.app.syscalldemo/cache/tmpfs-629392441675200/libmmkv.so (deleted)@0x7f6265742d98 needs to unload /data/data/com.example.test.app.syscalldemo/cache/tmpfs-629392441675200/libmmkv.so (deleted)@0x7f6265742d98
I /data/data/com.example.test.app.syscalldemo/cache/tmpfs-629392441675200/libmmkv.so (deleted)@0x7f6265742d98 needs to unload /data/data/com.example.test.app.syscalldemo/cache/tmpfs-629392441675200/libmmkv.so (deleted)@0x7f6265742d98
I /data/data/com.example.test.app.syscalldemo/cache/tmpfs-629392441675200/libmmkv.so (deleted)@0x7f6265742d98 needs to unload /data/data/com.example.test.app.syscalldemo/cache/tmpfs-629392441675200/libmmkv.so (deleted)@0x7f6265742d98
I /data/data/com.example.test.app.syscalldemo/cache/tmpfs-629392441675200/libmmkv.so (deleted)@0x7f6265742d98 needs to unload libdl.so@0x7f6271b0b6b0
I /data/data/com.example.test.app.syscalldemo/cache/tmpfs-629392441675200/libmmkv.so (deleted)@0x7f6265742d98 needs to unload /data/data/com.example.test.app.syscalldemo/cache/tmpfs-629392441675200/libmmkv.so (deleted)@0x7f6265742d98
I name /data/data/com.example.test.app.syscalldemo/cache/tmpfs-629392441675200/libmmkv.so (deleted): freeing soinfo @ 0x7f6265742d98
I not unloading 'libdl.so' - the binary is flagged with NODELETE
可以看到 "library "libc.so" is already loaded under different name/path", 其位于 linker 的 static soinfo* load_library(int fd, off64_t file_offset, LoadTaskList& load_tasks, const char* name, int rtld_flags, const android_dlextinfo* extinfo) 函数,显然 linker 的 load_library 认为我需要的 libc.so 与正在被加载的 libmmkv.so 是同一个对象。从调用分支结构不难看出 linker 正在加载 DT_NEEDED 的 libc.so, 而此时 extinfo.fd=libmmkv.so, 因而 load_library 直接返回了 libmmkv.so 的 soinfo.
注意到 load_library 有一个 android_dlextinfo* extinfo 参数传入,这个参数来源于 find_libraries->find_library_internal, 通过对比 android-6.0.0_r26 和 android-6.0.0_r41 tag 可以发现,在 android-6.0.0_r26 时,find_libraries 加载 DT_NEEDED 代码如下
// Step 1: load and pre-link all DT_NEEDED libraries in breadth first order.
for (LoadTask::unique_ptr task(load_tasks.pop_front());
task.get() != nullptr; task.reset(load_tasks.pop_front())) {
soinfo* si = find_library_internal(load_tasks, task->get_name(), rtld_flags, extinfo);
if (si == nullptr) {
return false;
}
soinfo* needed_by = task->get_needed_by();
if (needed_by != nullptr) {
needed_by->add_child(si);
}
而 android-6.0.0_r41 修改为了以下
// Step 1: load and pre-link all DT_NEEDED libraries in breadth first order.
for (LoadTask::unique_ptr task(load_tasks.pop_front());
task.get() != nullptr; task.reset(load_tasks.pop_front())) {
soinfo* needed_by = task->get_needed_by();
soinfo* si = find_library_internal(load_tasks, task->get_name(),
rtld_flags, needed_by == nullptr ? extinfo : nullptr);
if (si == nullptr) {
return false;
}
if (needed_by != nullptr) {
needed_by->add_child(si);
}
显然,extinfo 中携带的 ANDROID_DLEXT_USE_LIBRARY_FD 不应被用于其 DT_NEEDED 依赖,而 android-6.0.0_r1-android-6.0.0_r26 由于错误的将包含 ANDROID_DLEXT_USE_LIBRARY_FD 的 extinfo 传入了用于加载依赖的 find_library_internal 导致其依赖无法正常加载或链接。
盐酸乙酰胆碱
写了点奇怪的东西 纯 Java 调用任意 Linux syscall, 仅支持 Android 平台。 https://github.com/cinit/LibcoreSyscall
LibcoreSyscall 现已支持在 Android 5.0-15 x86/x64/arm/arm64 纯内存(文件不落地)加载 ELF shared object.
该项目本体仍然是纯 Java 编译的单 dex(无 so 无 assets)
无文件加载 so 的用例可以 参考项目 README
该项目本体仍然是纯 Java 编译的单 dex(无 so 无 assets)
无文件加载 so 的用例可以 参考项目 README
🤯10❤3🥰2
CVE-2024-54143
An attacker can compromise the build artifact delivered from the sysupgrade.openwrt.org, allowing the malicious firmware image to be installed to the OpenWrt installation that uses the attended firmware upgrade, firmware-selector.openwrt.org, or CLI upgrade.
https://github.com/openwrt/asu/security/advisories/GHSA-r3gq-96h6-3v7q
An attacker can compromise the build artifact delivered from the sysupgrade.openwrt.org, allowing the malicious firmware image to be installed to the OpenWrt installation that uses the attended firmware upgrade, firmware-selector.openwrt.org, or CLI upgrade.
https://github.com/openwrt/asu/security/advisories/GHSA-r3gq-96h6-3v7q
GitHub
Build artifact poisoning via truncated SHA-256 hash and command injection
## Summary
Due to the combination of the command injection in the `openwrt/imagebuilder` image and the truncated SHA-256 hash included in the build request hash, an attacker can pollute the legi...
Due to the combination of the command injection in the `openwrt/imagebuilder` image and the truncated SHA-256 hash included in the build request hash, an attacker can pollute the legi...
😱6
Arm64EC 的一些技术细节
注: Arm64EC 是 Windows 11 ARM64 运行 x86_64 应用程序所使用的方案
http://www.emulators.com/docs/abc_arm64ec_explained.htm
注: Arm64EC 是 Windows 11 ARM64 运行 x86_64 应用程序所使用的方案
http://www.emulators.com/docs/abc_arm64ec_explained.htm
在 ZeroTier 官方 controller 配置 RFC1918 以外的 IP 和路由时网页端会提示需要在客户端设置 AllowGlobal=1 才能生效.
然而注意到 ZeroTier 客户端源代码的 OneServiceImpl::checkIfManagedIsAllowed 函数当且仅当 CIDR 类型为 IP_SCOPE_GLOBAL 时才需要 AllowGlobal 为 1, 而依据 InetAddress::ipScope 函数可知 28.0.0.0/8 类型为 IP_SCOPE_PSEUDOPRIVATE, 显然这种情况下 OneServiceImpl::checkIfManagedIsAllowed 函数中 default 分支是返回 true 的,因而该 CIDR 不需要客户端配置 AllowGlobal=1.
然而注意到 ZeroTier 客户端源代码的 OneServiceImpl::checkIfManagedIsAllowed 函数当且仅当 CIDR 类型为 IP_SCOPE_GLOBAL 时才需要 AllowGlobal 为 1, 而依据 InetAddress::ipScope 函数可知 28.0.0.0/8 类型为 IP_SCOPE_PSEUDOPRIVATE, 显然这种情况下 OneServiceImpl::checkIfManagedIsAllowed 函数中 default 分支是返回 true 的,因而该 CIDR 不需要客户端配置 AllowGlobal=1.