You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Thanks for sharing Terminal.log. I traced the log from start to finish and found three distinct root causes in libcortex-hook.so (app/src/main/cpp/cortex-hook.c) that caused apt install gradle (and dependent packages) to fail:
dbus-system-bus-common and dbus failing during dpkg --configure (exit status 1): dbus-system-bus-common.postinst runs adduser --system --quiet --home /nonexistent --no-create-home --disabled-password --group messagebus. In cortex-hook.c, the NSS hooks (getpwnam, getpwnam_r, getpwuid, getpwuid_r, getgrnam, getgrnam_r, getgrgid, getgrgid_r) synthesized a fake uid = 0 (root) entry for every username, group, and UID not found in /etc/passwd or /etc/group instead of returning NULL. Because egetpwnam("messagebus") returned uid = 0 (< 100), adduser concluded that messagebus already existed as a non-system user and exited with status 1. In addition, first_avail_uid(100, 999) saw every UID in 100..999 as already taken because getpwuid never returned NULL.
Fix: I restricted the NSS fallback synthesis strictly to "root" and the current process's real UID/GID (0 or real_uid()/real_gid()). Lookups for non-existent service accounts and free UIDs (100..999) now return NULL as expected by adduser/useradd.
ca-certificates-java trigger failing with Unable to execute Java and gradle/java failing with libjli.so: cannot open shared object file:
On Ubuntu, /usr/bin/java is a symlink chain (/usr/bin/java -> /etc/alternatives/java -> /usr/lib/jvm/java-21-openjdk-arm64/bin/java). In cortex-hook.c, execve and posix_spawn passed the unresolved symlink path $CORTEX_ROOT/usr/bin/java as the target binary argument to ld-linux-aarch64.so.1 and to CORTEX_REAL_EXE (/proc/self/exe). When glibc's ld.so is invoked explicitly with a filename argument, _dl_new_object computes $ORIGIN from that argument's directory ($CORTEX_ROOT/usr/bin) without resolving symlinks. As a result, OpenJDK's DT_RUNPATH ($ORIGIN/../lib) searched /usr/lib/libjli.so instead of /usr/lib/jvm/java-21-openjdk-arm64/lib/libjli.so, and /proc/self/exe pointed to /usr/bin/java instead of the JRE installation directory.
Fix:execve and posix_spawn now resolve symlinks (resolve_symlinks) before wrapping dynamically linked ELF binaries with ld-linux, pass the resolved ELF path to both ld-linux and CORTEX_REAL_EXE, preserve the original argv[0] via --argv0, and prepend any caller LD_LIBRARY_PATH entries into --library-path.
useradd/groupaddNETLINK_AUDIT and dbus.postinst setuid chmod errors: socket(AF_NETLINK, ..., NETLINK_AUDIT) now returns -1 with errno = EPROTONOSUPPORT so libaudit disables kernel audit logging cleanly instead of aborting on Android SELinux EACCES/EPERM. In chmod, fchmod, and fchmodat, if setting setuid/setgid bits (mode & 06000, such as 04754 on dbus-daemon-launch-helper) fails on Android's nosuid/data mount, the hook retries with mode & 01777.
I have opened #9 with these fixes and regression tests.
The fix has been merged into the main branch via PR #9.
Official APKs are published under Releases whenever the repository maintainer (@ssfuisu) cuts a new release tag (the next release will likely be v1.25.25).
If you'd like to test the fix immediately before the next official release is tagged, you can build an APK directly from main:
git clone https://github.com/ssfuisu/cortex.git
cd cortex
./gradlew assembleDebug
The built APK will be located under app/build/outputs/apk/debug/.
Activity
Woffluon commentedon Oct 6, 2026
Thanks for sharing
Terminal.log. I traced the log from start to finish and found three distinct root causes inlibcortex-hook.so(app/src/main/cpp/cortex-hook.c) that causedapt install gradle(and dependent packages) to fail:dbus-system-bus-commonanddbusfailing duringdpkg --configure(exit status 1):dbus-system-bus-common.postinstrunsadduser --system --quiet --home /nonexistent --no-create-home --disabled-password --group messagebus. Incortex-hook.c, the NSS hooks (getpwnam,getpwnam_r,getpwuid,getpwuid_r,getgrnam,getgrnam_r,getgrgid,getgrgid_r) synthesized a fakeuid = 0(root) entry for every username, group, and UID not found in/etc/passwdor/etc/groupinstead of returningNULL. Becauseegetpwnam("messagebus")returneduid = 0(< 100),adduserconcluded thatmessagebusalready existed as a non-system user and exited with status1. In addition,first_avail_uid(100, 999)saw every UID in100..999as already taken becausegetpwuidnever returnedNULL."root"and the current process's real UID/GID (0orreal_uid()/real_gid()). Lookups for non-existent service accounts and free UIDs (100..999) now returnNULLas expected byadduser/useradd.ca-certificates-javatrigger failing withUnable to execute Javaandgradle/javafailing withlibjli.so: cannot open shared object file:On Ubuntu,
/usr/bin/javais a symlink chain (/usr/bin/java->/etc/alternatives/java->/usr/lib/jvm/java-21-openjdk-arm64/bin/java). Incortex-hook.c,execveandposix_spawnpassed the unresolved symlink path$CORTEX_ROOT/usr/bin/javaas the target binary argument told-linux-aarch64.so.1and toCORTEX_REAL_EXE(/proc/self/exe). When glibc'sld.sois invoked explicitly with a filename argument,_dl_new_objectcomputes$ORIGINfrom that argument's directory ($CORTEX_ROOT/usr/bin) without resolving symlinks. As a result, OpenJDK'sDT_RUNPATH($ORIGIN/../lib) searched/usr/lib/libjli.soinstead of/usr/lib/jvm/java-21-openjdk-arm64/lib/libjli.so, and/proc/self/exepointed to/usr/bin/javainstead of the JRE installation directory.execveandposix_spawnnow resolve symlinks (resolve_symlinks) before wrapping dynamically linked ELF binaries withld-linux, pass the resolved ELF path to bothld-linuxandCORTEX_REAL_EXE, preserve the originalargv[0]via--argv0, and prepend any callerLD_LIBRARY_PATHentries into--library-path.useradd/groupaddNETLINK_AUDITanddbus.postinstsetuidchmoderrors:socket(AF_NETLINK, ..., NETLINK_AUDIT)now returns-1witherrno = EPROTONOSUPPORTsolibauditdisables kernel audit logging cleanly instead of aborting on Android SELinuxEACCES/EPERM. Inchmod,fchmod, andfchmodat, if setting setuid/setgid bits (mode & 06000, such as04754ondbus-daemon-launch-helper) fails on Android'snosuid/datamount, the hook retries withmode & 01777.I have opened #9 with these fixes and regression tests.
Woffluon commentedon Oct 6, 2026
Update: I have pushed additional post-merge hardening commits to #9 addressing the CodeRabbit review findings:
movw r7, #imm+svc #0andmov.w r12, #imm+bl __libc_do_syscall) for 32-bit ARM/ARMHF environments._rfunctions (getpwnam_r,getpwuid_r,getgrnam_r,getgrgid_r) to propagate real libc errors (such asERANGE) rather than masking them./var/lib/dbus/machine-idzero-byte file issue by symlinking to/etc/machine-idduring bootstrap and runtime initialization.-ENOSYS.All 38 unit tests, 91 native C assertions, and 32 shell regression tests are passing cleanly.
Merge pull request #9 from Woffluon/fix/post-merge-hardening-issue-7
ani1nonly commentedon Oct 7, 2026
Where is the apk
Woffluon commentedon Oct 8, 2026
The fix has been merged into the
mainbranch via PR #9.Official APKs are published under Releases whenever the repository maintainer (@ssfuisu) cuts a new release tag (the next release will likely be
v1.25.25).If you'd like to test the fix immediately before the next official release is tagged, you can build an APK directly from
main:git clone https://github.com/ssfuisu/cortex.git cd cortex ./gradlew assembleDebugThe built APK will be located under
app/build/outputs/apk/debug/.