Encrypting a Geeksphone

I own a Geeksphone Revolution. The phone comes pre-rooted and with a bootloader which allows easy reflashing. What follows might be totally different for other devices, or might not.

Allegedly, Android can encrypt /data (i.e. all application data) with the standard linux dm-crypt device mapper. Getting it to work however turned out to be slightly nontrivial. As there is a bug open since July 2013.

However, judicious application of adb logcat finally left me in a position to add the following comment to the bug discussion:

"
Indeed a failed umount /data seems to be the culprit here. I finally got encryption to start as follows:

1. fire up the adb logcat and some adb shell
2. call mount and see whether some other FSes are mounted below /data (it was /data/dalvik-cache in my case)
3. kill processes maybe using those filesystems (zygote)
4. identify all processes still using /data via lsof | grep data, write down their pids
5. open two adb shell windows
6. prepare to kill all the pids from step 4 in window 1
7. vdc cryptfs enablecrypto inplace '<passwd>' in window 2, thereby requesting encryption from vold
8. execute prepared command from step 6
9. ??????
10. PROFIT^W Find out that /data/dalvik-cache also gets mounted in the vold created tempfs during password entry, and that vold subsequently fails to umount /data again, resulting in a semi-booted device.
11. adb shell
12. umount /data/dalvik-cache
13. vdc cryptfs restart
14. !!!!!!!
15. PROFIT (for this boot only thought)

... excuse me while I find out how to automatically umount /data/dalvik-cache during bootup (once)
"

The latter turned out to be slightly non-trivial, too. In principle I'd need to insert an exec /system/bin/umount /data/dalvik-cache in the on property:vold.decrypt=trigger_reset_main block in /init.rc

However, /init.rc resides on non-persistent storage, i.e. you cannot simply mount -o remount,rw / and patch it. However, my android came with a binary /system/bin/bootanimation the purpose of which was to draw some Intel logo onto the screen before continuing the boot. It runs once during boot as user graphics and seemed useless enough to repurpose.

Hence I replaced it with a very small shell script as follows:

#!/system/bin/sh

( (
	while ! getprop vold.decrypt | grep -q trigger_reset_main; do
		sleep 1
	done

	while getprop vold.decrypt | grep -q trigger_reset_main; do
		umount-dalvikcache
		sleep 1
	done
) & ) &

What's up with the ) & madness? init.rc will stop all services when vold.decrypt becomes trigger_reset_main. This includes bootanimation. By forking a few times, the child process becomes sufficiently independent from the parent to survive this.

Unfortunately (for the purpose of misuse) bootanimation does not run as root, hence it cannot umount /data/dalvik-cache. As it is a shell-script, it cannot run setuid root. So I created a special-purpose binary doing nothing but umount("/data/dalvik-cache"); exit(0);. As I do not have a ready-to-go Android binary toolchain, but the Geeksphone actually contains an Intel Atom, the source for this binary ended up as follows:

.data
.text
_start:

call umount
.ascii "/data/dalvik-cache\0"

umount:
popl %ebx # no, I cannot be bothered to find out how to specify memory layout today
movl $52, %eax
movl $0, %ecx
int $0x80

movl $1, %eax
movl $0, %ebx
int $0x80

Putting this binary into /system/bin and chmod 4755 it, this finally solves the problem of a mounted /data/dalvik-cache and lets the phone boot sucessfully.

I did not find any perceptible impact on performance yet. Whether the battery drains significantly faster remains to be seen.