Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android permission denied when reading /proc/self/exe from non-main thread

I'm trying to get the canonical path of /proc/self/exe. When I do this on the Main Thread it works, when I do this on an different thread it crashes with an IOException: "Permission denied":

                   DBG  E  Thread: main
                        E  Path: /system/bin/app_process32
                        E  Thread: Thread-21656
            System.err  W  java.io.IOException: Permission denied
                        W      at java.io.File.canonicalizePath(Native Method)
                        W      at java.io.File.getCanonicalPath(File.java:414)
                        W      at java.io.File.getCanonicalFile(File.java:428)
                        W      at com.quanturium.testbugprocselfexe.MyActivity.getPathOfExecutable(MyActivity.java:36)
                        W      at com.quanturium.testbugprocselfexe.MyActivity.access$000(MyActivity.java:12)
                        W      at com.quanturium.testbugprocselfexe.MyActivity$1.run(MyActivity.java:26)
                        W      at java.lang.Thread.run(Thread.java:818)

Code:

@Override
protected void onCreate (Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    getPathOfExecutable(); // Works as expected

    new Thread(new Runnable() {
        @Override
        public void run ()
        {
            getPathOfExecutable(); // Trigger the IOException: Permission denied
        }
    }).start();
}

private void getPathOfExecutable()
{
    try
    {
        Log.e("DBG", "Thread: " + Thread.currentThread().getName());
        Log.e("DBG", "Path: " + new File("/proc/self/exe").getCanonicalFile().getPath());
    }
    catch (IOException e)
    {
        e.printStackTrace();
    }
}

This error only happens when debuggable is configured to false in the build.gradle file

Code to try it out: https://github.com/quanturium/TestBugProcSelfExe

Is this a bug or an intended behavior? What would be a workaround to get the path of the current executable?

like image 347
Quanturium Avatar asked Nov 09 '22 18:11

Quanturium


1 Answers

Does the code block? If it doesn't, there should be no ramifications of running it in the main thread. You can, however, do that from another thread, with:

Context.runOnUiThread(new Runnable() {
    getPathOfExecutable();
});

This is the cleanest work around I can think of, short of editing the permissions of your file (that you can't get the path of without running your code on the main thread anyways) because you have r/w privileges on /proc/self/exe.

This is very weird, and I am still researching the permission differences in different threads on android.

If you can get it working in the main thread, my opinion would be to just do it in the main thread, and not worry much about optimization, as the performance is no different on different threads.

like image 162
MeetTitan Avatar answered Nov 15 '22 05:11

MeetTitan