Search code examples
javaandroidshellportnetstat

Running Android shell command from Java code returns empty output


I am trying to run shell commands (netstat -an -pt, cat /proc/net/tcp) from my Java code in order to check for open TCP ports on Android device. The device is non-rooted (on rooted device, there is no problem with this).

I found out that there are 2 types to invoke shell commands from Java code.

To get the process object I tried using:

  1. Runtime.getRuntime().exec(command);

  2. new ProcessBuilder().command("sh", "-c", command).start();

Later on, I'm getting processes InputStream object and outputing the result.

The problem is that the result of cat /proc/net/tcp command is empty string, and result of netstat -an -pt is:

Active Internet connections (w/o servers) Proto Recv-Q Send-Q Local Address           Foreign Address         State       Active UNIX domain sockets (w/o servers) Proto RefCnt Flags    Type       State       I-Node Path

...which is the header of netstat command.

When running above commands in Android shell directly (by opening adb shell inside non-rooted device) everything works fine and outputs of the commands are shown in console.

I suspect that there is some problem with permissions since this works on rooted device.

Logcat output for when running one of the commands:

 W cat     : type=1400 audit(0.0:3***4): avc: denied { read } for name="tcp" dev="proc" ino=4*2653***6 scontext=u:r:untrusted_app:s*:c**9,c**7,c5**,c*6* tcontext=u:object_r:proc_net_tcp_udp:s0 tclass=file permissive=0

If this is a permission problem, is there another way to read currently open TCP ports on non-rooted Android device with my application?


Solution

  • I partially found my answer which is sufficient enough. Basically problem was with permissions as suspected in the first place.

    As stated in documentation: from Android version 10 /proc/net filesystem is restricted and can not be accessed. Unlucky (or should I say lucky) thing was that my non-rooted test device is Android 10 and therefore process object would have returned status 1 because it had no permission to read /proc/net filesystem.

    I tested the same code on Android 8 and everything worked as expected.

    I still haven't figured out how to access used ports, but I'll look into NetworkStatsManager and ConnectivityManager classes as noted in previously linked documentation.