Skip to content

Commit 965fd8d

Browse files
committed
Fix system certificate injection for Android 14
1 parent ca7bdee commit 965fd8d

File tree

1 file changed

+49
-1
lines changed

1 file changed

+49
-1
lines changed

src/interceptors/android/adb-commands.ts

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,11 @@ export async function injectSystemCertificate(
273273
mkdir -p -m 700 /data/local/tmp/htk-ca-copy
274274
275275
# Copy out the existing certificates
276-
cp /system/etc/security/cacerts/* /data/local/tmp/htk-ca-copy/
276+
if [ -d "/apex/com.android.conscrypt/cacerts" ]; then
277+
cp /apex/com.android.conscrypt/cacerts/* /data/local/tmp/htk-ca-copy/
278+
else
279+
cp /system/etc/security/cacerts/* /data/local/tmp/htk-ca-copy/
280+
fi
277281
278282
# Create the in-memory mount on top of the system certs folder
279283
mount -t tmpfs tmpfs /system/etc/security/cacerts
@@ -289,6 +293,50 @@ export async function injectSystemCertificate(
289293
chmod 644 /system/etc/security/cacerts/*
290294
chcon u:object_r:system_file:s0 /system/etc/security/cacerts/*
291295
296+
echo 'System cacerts setup completed'
297+
298+
# Deal with the APEX overrides in Android 14+, which need injecting into each namespace:
299+
if [ -d "/apex/com.android.conscrypt/cacerts" ]; then
300+
echo 'Injecting certificates into APEX cacerts'
301+
302+
# When the APEX manages cacerts, we need to mount them at that path too. We can't do
303+
# this globally as APEX mounts are namespaced per process, so we need to inject a
304+
# bind mount for this directory into every mount namespace.
305+
306+
# First we get the Zygote process(es), which launch each app
307+
ZYGOTE_PID=$(pidof zygote || true)
308+
ZYGOTE64_PID=$(pidof zygote64 || true)
309+
# N.b. some devices appear to have both!
310+
311+
# Apps inherit the Zygote's mounts at startup, so we inject here to ensure all newly
312+
# started apps will see these certs straight away:
313+
for Z_PID in "$ZYGOTE_PID $ZYGOTE64_PID"; do
314+
# We use 'echo' below to trim spaces
315+
nsenter --mount=/proc/$(echo $Z_PID)/ns/mnt -- \
316+
/bin/mount --bind /system/etc/security/cacerts /apex/com.android.conscrypt/cacerts
317+
done
318+
319+
echo 'Zygote APEX certificates remounted'
320+
321+
# Then we inject the mount into all already running apps, so they see these certs immediately.
322+
323+
# Get the PID of every process whose parent is one of the Zygotes:
324+
APP_PIDS=$(
325+
echo "$ZYGOTE_PID $ZYGOTE64_PID" | \
326+
xargs -n1 ps -o 'PID' -P | \
327+
grep -v PID
328+
)
329+
330+
# Inject into the mount namespace of each of those apps:
331+
for PID in $APP_PIDS; do
332+
nsenter --mount=/proc/$PID/ns/mnt -- \
333+
/bin/mount --bind /system/etc/security/cacerts /apex/com.android.conscrypt/cacerts &
334+
done
335+
wait # Launched in parallel - wait for completion here
336+
337+
echo "APEX certificates remounted for $(echo $APP_PIDS | wc -w) apps"
338+
fi
339+
292340
# Delete the temp cert directory & this script itself
293341
rm -r /data/local/tmp/htk-ca-copy
294342
rm ${injectionScriptPath}

0 commit comments

Comments
 (0)