Discussion:
[android-security-discuss] dlopen fails to open library from /data/data/<package> folder
Tomas Dirvanauskas
2018-09-25 11:41:22 UTC
Permalink
Hey,

let me shortly explain what I am trying to achieve.

For development purposes, I want to perform quick iteration during my app
development. So instead of doing:

* Change some native code
* Compile library
* Package apk
* Install apk
* Run apk

I want to do:

* Change some native code
* Compile library
* Send .so file to the device
* Restart the app


After doing initial apk installation, I push only single .so file to the
device (/data/data/com.Tomas.MyApplication/cache/) and instruct the app to
check that location first, if it finds a library there it will try to load
that library instead of the one from /data/app folder.

I am loading the library like this -
dlopen("/data/data/com.Tomas.MyApplication/files/libmylibrary.so",
RTLD_NOW);

And it works fine on Android 6.0, but doesn't work on Android 8.0, dlopen
returns 0.

The error is:
09-25 10:11:04.395 23925 23925 W Main: type=1400 audit(0.0:49): avc: denied
{ open } for path="/data/data/com.Tomas.MyApplication/cache/libmylibrary.so"
dev="dm-0" ino=112773 scontext=u:r:untrusted_app:s0:c512,c768
tcontext=u:object_r:app_data_file:s0 tclass=file permissive=0

I assume this is somehow related to this -
https://developer.android.com/about/versions/nougat/android-7.0-changes#ndk-errors

Is there any way to workaround this? Like I said this is strictly for
development purposes to speed up iteration time.

P.S I also tried putting libmylibrary.so file to
/storage/emulated/0/Android/data/com.Tomas.MyApplication/cache//libmylibrary
.so" , and tried using dlopen, but that fails both on Android 6.0 and
Android 8.0
--
You received this message because you are subscribed to the Google Groups "Android Security Discussions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to android-security-discuss+***@googlegroups.com.
Visit this group at https://groups.google.com/group/android-security-discuss.
For more options, visit https://groups.google.com/d/optout.
'Nick Kralevich' via Android Security Discussions
2018-09-25 15:58:20 UTC
Permalink
You are using a userdebug or eng build, and trying to manually copy a file
into an application home directory. The SELinux label of the file you
created isn't correct, and as a result, your app doesn't have permission to
open the file.

To fix this, you can use the "restorecon" command:

restorecon -R /data/data/com.Tomas.MyApplication

which will fixup all the labels on your app's home directory.

A cleaner approach, which would work on production builds of Android, would
be to use the /system/bin/run-as command to place the file into your app's
home directory. This will ensure that your application file is labeled
correctly, as well as work on all Android build types.

adb shell "cat /data/local/tmp/myfile.so | run-as <app-user> sh -c 'cat >
<app-directory>/cache/myfile.so'"

Having said all of this, you should not assume you can load executable
content from your application's home directory. Loading executable content
from your writable home directory is a W^X (
https://en.wikipedia.org/wiki/W%5EX) violation, and is a dangerous thing to
do because you're potentially executing unsigned code. The only executable
content should come from your own APK, which is signature checked by the
Android OS.

-- Nick
Post by Tomas Dirvanauskas
Hey,
let me shortly explain what I am trying to achieve.
For development purposes, I want to perform quick iteration during my app
* Change some native code
* Compile library
* Package apk
* Install apk
* Run apk
* Change some native code
* Compile library
* Send .so file to the device
* Restart the app
After doing initial apk installation, I push only single .so file to the
device (/data/data/com.Tomas.MyApplication/cache/) and instruct the app to
check that location first, if it finds a library there it will try to load
that library instead of the one from /data/app folder.
I am loading the library like this -
dlopen("/data/data/com.Tomas.MyApplication/files/libmylibrary.so",
RTLD_NOW);
And it works fine on Android 6.0, but doesn't work on Android 8.0, dlopen
returns 0.
denied { open } for path="/data/data/com.Tomas.MyApplication/cache/
libmylibrary.so" dev="dm-0" ino=112773
scontext=u:r:untrusted_app:s0:c512,c768
tcontext=u:object_r:app_data_file:s0 tclass=file permissive=0
I assume this is somehow related to this -
https://developer.android.com/about/versions/nougat/android-7.0-changes#ndk-errors
Is there any way to workaround this? Like I said this is strictly for
development purposes to speed up iteration time.
P.S I also tried putting libmylibrary.so file to
/storage/emulated/0/Android/data/com.Tomas.MyApplication/cache//
libmylibrary.so" , and tried using dlopen, but that fails both on Android
6.0 and Android 8.0
--
You received this message because you are subscribed to the Google Groups
"Android Security Discussions" group.
To unsubscribe from this group and stop receiving emails from it, send an
Visit this group at
https://groups.google.com/group/android-security-discuss.
For more options, visit https://groups.google.com/d/optout.
--
Nick Kralevich | ***@google.com
--
You received this message because you are subscribed to the Google Groups "Android Security Discussions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to android-security-discuss+***@googlegroups.com.
Visit this group at https://groups.google.com/group/android-security-discuss.
For more options, visit https://groups.google.com/d/optout.
Tomas Dirvanauskas
2018-09-26 13:15:26 UTC
Permalink
Thank you so much, that did the trick. I went with 'adb shell "cat
/data/local/tmp/myfile.so | run-as <app-user> sh -c 'cat >
<app-directory>/cache/myfile.so'" because I wanted for this to work on
retail phones as well, and it works perfectly now. Tested both on Google
Pixel with Android 8.0 and emulator.

P.S <app-user> in this case is a package name, right?


On Tuesday, September 25, 2018 at 2:41:22 PM UTC+3, Tomas Dirvanauskas
Post by Tomas Dirvanauskas
Hey,
let me shortly explain what I am trying to achieve.
For development purposes, I want to perform quick iteration during my app
* Change some native code
* Compile library
* Package apk
* Install apk
* Run apk
* Change some native code
* Compile library
* Send .so file to the device
* Restart the app
After doing initial apk installation, I push only single .so file to the
device (/data/data/com.Tomas.MyApplication/cache/) and instruct the app to
check that location first, if it finds a library there it will try to load
that library instead of the one from /data/app folder.
I am loading the library like this -
dlopen("/data/data/com.Tomas.MyApplication/files/libmylibrary.so",
RTLD_NOW);
And it works fine on Android 6.0, but doesn't work on Android 8.0, dlopen
returns 0.
denied { open } for path="/data/data/com.Tomas.MyApplication/cache/
libmylibrary.so" dev="dm-0" ino=112773
scontext=u:r:untrusted_app:s0:c512,c768
tcontext=u:object_r:app_data_file:s0 tclass=file permissive=0
I assume this is somehow related to this -
https://developer.android.com/about/versions/nougat/android-7.0-changes#ndk-errors
Is there any way to workaround this? Like I said this is strictly for
development purposes to speed up iteration time.
P.S I also tried putting libmylibrary.so file to
/storage/emulated/0/Android/data/com.Tomas.MyApplication/cache//
libmylibrary.so" , and tried using dlopen, but that fails both on Android
6.0 and Android 8.0
--
You received this message because you are subscribed to the Google Groups "Android Security Discussions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to android-security-discuss+***@googlegroups.com.
Visit this group at https://groups.google.com/group/android-security-discuss.
For more options, visit https://groups.google.com/d/optout.
'Don Turner' via Android Security Discussions
2018-09-26 13:48:22 UTC
Permalink
Thanks for posting this question. I'm also in a position where it'd
dramatically speed up my deploy/test cycle to have my app load a .so file
rather than rebuild the app each time.

Just something to watch out for: run-as is broken on Samsung
devices: https://stackoverflow.com/questions/37413667/run-as-could-not-set-capabilities-operation-not-permitted


On Wednesday, September 26, 2018 at 2:15:26 PM UTC+1, Tomas Dirvanauskas
Post by Tomas Dirvanauskas
Thank you so much, that did the trick. I went with 'adb shell "cat
/data/local/tmp/myfile.so | run-as <app-user> sh -c 'cat >
<app-directory>/cache/myfile.so'" because I wanted for this to work on
retail phones as well, and it works perfectly now. Tested both on Google
Pixel with Android 8.0 and emulator.
P.S <app-user> in this case is a package name, right?
On Tuesday, September 25, 2018 at 2:41:22 PM UTC+3, Tomas Dirvanauskas
Post by Tomas Dirvanauskas
Hey,
let me shortly explain what I am trying to achieve.
For development purposes, I want to perform quick iteration during my app
* Change some native code
* Compile library
* Package apk
* Install apk
* Run apk
* Change some native code
* Compile library
* Send .so file to the device
* Restart the app
After doing initial apk installation, I push only single .so file to the
device (/data/data/com.Tomas.MyApplication/cache/) and instruct the app to
check that location first, if it finds a library there it will try to load
that library instead of the one from /data/app folder.
I am loading the library like this -
dlopen("/data/data/com.Tomas.MyApplication/files/libmylibrary.so",
RTLD_NOW);
And it works fine on Android 6.0, but doesn't work on Android 8.0, dlopen
returns 0.
denied { open } for path="/data/data/com.Tomas.MyApplication/cache/
libmylibrary.so" dev="dm-0" ino=112773
scontext=u:r:untrusted_app:s0:c512,c768
tcontext=u:object_r:app_data_file:s0 tclass=file permissive=0
I assume this is somehow related to this -
https://developer.android.com/about/versions/nougat/android-7.0-changes#ndk-errors
Is there any way to workaround this? Like I said this is strictly for
development purposes to speed up iteration time.
P.S I also tried putting libmylibrary.so file to
/storage/emulated/0/Android/data/com.Tomas.MyApplication/cache//
libmylibrary.so" , and tried using dlopen, but that fails both on
Android 6.0 and Android 8.0
--
You received this message because you are subscribed to the Google Groups "Android Security Discussions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to android-security-discuss+***@googlegroups.com.
Visit this group at https://groups.google.com/group/android-security-discuss.
For more options, visit https://groups.google.com/d/optout.
Loading...