Introduction

Since upgrading my LG G2 phone to LG G4 and running Cyanogenmod 13 on it, I found that DroidSSHd application was not usable anymore.

This blog post is more or less a recollection of the steps to get it running, and to be able to ssh back to the phone.

Steps

1. .pid file access

DroidSSHd attempts to use the .pid file created by dropbear so that it can start / stop and keep track of the server running or not. The problem is that the .pid file created by the native server was not readable (due to SE Linux) by the UI application as it did not have the rights to read the file.

This was solved with these two commands that grant more rights to the .pid file – so inside DroidSSHdService.java:

Also, if the daemon is ran as root, the .pid file will be created as root, thus UI won’t again be able to read it – so we need to make it owned by the user the UI runs with:

2. More .pid file troubles

While checking for the .pid file, DroidSSHd needs to have access to the /proc file system to check for self. However, under SE Linux of CM13 this is not possible anymore:

Unfortunately, this one needs SuperSU (from chainfire) which would allow editing the security policy to grants access of untrusted_app to the /proc folder. Without SuperSU I found no way to get around this problem (the only other alternative I saw was to disable SE Linux completely).

Once SuperSU installed, the command below takes care of the access. For more information about supolicy, check chapter 5.5.1. The supolicy tool from chainfire’s How-to SU

3. Linker is acting up

Attempting to connect to the ssh server failed (connection was closed right after authentication) but eventually I was able to get the error message (using the Close window on exit to Never in Putty):

Connection Closed

This was extremely puzzling since the dropbearmulti was statically linked, so why would it want to access the phone’s libc++.so file ?!

Initially I thought that the armv6/32bit build of dropbearmulti caused the problem, thus why not trying an armv8-a/64bit build ? Same behavior though. Unfortunately this meant I had to get my hands dirty and use strace to dwelve into the linker problems.

Apparently, the problem happened when the code was trying to launch the shell /system/bin/sh and now it made sense. Pulling it locally and checking it, the shell IS a 64bit executable BUT somehow, it is dynamically linked!

Luckily I have an older bash 3.2 statically compiled (armv6/32bit) and I decided to give it a go. DroidSSHd has options to allow paths for SU and SH, but checking the code it seems they are only used after the connection is established (and not initially, upon session creation for the user). So a quick recompile with the /system/xbin/bash3 hardcoded, et voilà:

Connection Success

Remaining issues

  • There are newer version of dropbear out there, including their patches for Android. I’ve downloaded the version dropbear-2016.73 and tried it, but it had problems. The patch was missing the atoi() instruction to convert the -U 0 argument to proper integer UID. I’ve decided not too loose time fixing even more problems, and went with the proven dropbear-0.52
  • Most executables on my phone (such as ls, cp, etc … ) exhibit the same problem with CANNOT_LINK_EXECUTABLE when launched from dropbear, although they work properly from adb shell. I don’t have time to investigate why, I will probably go to a static build of busybox.