to directly access the files of another app, you may use sharedUserId:
http://developer.android.com/intl/fr/guide/topics/manifest/manifest-element.html#uid
If you can't use sharedUserId (different apk signatures etc..), you may also
retrieve and make a local copy of the .so by using a content provider and
ContentResolver.openInputStream().
That said, there are several security questions if you load and run an external
executable. Please read the recent "Native add-ons" thread on this list.
Olivier
> --
> You received this message because you are subscribed to the Google
> Groups "android-ndk" group.
> To post to this group, send email to andro...@googlegroups.com.
> To unsubscribe from this group, send email to
> android-ndk...@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/android-ndk?hl=en.
sharedUserId is the best way to go for this (afaics).
Be warned that there are numerous serious bugs migrating to
sharedUserId if you are starting from an existing non-sharedUserId app
- depending on Android version it may be silently impossible, render
your existing files inaccessible, or crash the phone.
For ScummVM, I was unfortunate enough to start from a non-sharedUserId
app so I have to unpack .so's from other apks "manually". That was
necessary to work around several package installer bugs on older
Android releases anyway, so it wasn't all bad.
- Gus
Be warned that there are numerous serious bugs migrating tosharedUserId if you are starting from an existing non-sharedUserId app
- depending on Android version it may be silently impossible, render
your existing files inaccessible, or crash the phone.
So if:
- app A has been distributed for a long time and never used sharedUserId
- and app B is a brand new app (never deployed) which contains the plugins
Then what value to give to sharedUserId in those apps so that app A doesn't
require a reinstall?
--
Olivier
So if:- app A has been distributed for a long time and never used sharedUserId
- and app B is a brand new app (never deployed) which contains the plugins
Then what value to give to sharedUserId in those apps so that app A doesn't
require a reinstall?
Let me rephrase my question: what is the default user id of an application? Is
it predictable?
If yes, then a solution could be to set sharedUserId in app B so that it matches
the default user id of app A. Please remember that in my example, app B is a
brand new app which has not been deployed yet.
> That said, an installed .apk is world-readable, so just getting stuff
> out of it doesn't require shared user IDs.
>
> Also as far as I know ever since the platform has extracted .so
> libraries out of an .apk, this also have been world readable, so if you
> want to rely on it doing the extraction there still should be no need
> for shared user IDs.
Ok, world readable... It's quite a vulnerability. You already tried to address
it with (obsolete) forward locks. So, how to be sure we can rely on it in the
future? Won't you change your mind?
--
Olivier
Let me rephrase my question: what is the default user id of an application? Isit predictable?
If yes, then a solution could be to set sharedUserId in app B so that it matches
the default user id of app A. Please remember that in my example, app B is a
brand new app which has not been deployed yet.
Ok, world readable... It's quite a vulnerability. You already tried to addressit with (obsolete) forward locks. So, how to be sure we can rely on it in the
future? Won't you change your mind?
The fix is absolutely trivial: give the sharedUserId attribute a
well-known default value (I'd suggest the Android package name). This
lets future manifest changes refer to that value explicitly to achieve
the desired "give me the user id that I know was already allocated for
my other package" behaviour.
Fwiw, I tried to describe this solution on Android bug 4381 but there
didn't seem to be any way to reopen a bug that was closed prematurely
and I suspect the comment was never seen by anyone who mattered.
Where would be the best place for me to file such a bug / feature
request?
- Gus
Ok, thank you, then all is well, and one can simply locate the desired apk using
PackageManager, verify its authenticity, and extract the needed files. That's
fairly simple.
One last question. If the plugins are JNI libs, they get extracted in
<dataDir>/lib. Can another app (with a different UID) access these files
directly? I heard people saying that's possible. Can we rely on that too?
--
Olivier
The fix is absolutely trivial: give the sharedUserId attribute awell-known default value (I'd suggest the Android package name). This
lets future manifest changes refer to that value explicitly to achieve
the desired "give me the user id that I know was already allocated for
my other package" behaviour.
Fwiw, I tried to describe this solution on Android bug 4381 but there
didn't seem to be any way to reopen a bug that was closed prematurely
and I suspect the comment was never seen by anyone who mattered.
Where would be the best place for me to file such a bug / feature
request?
Ok, thank you, then all is well, and one can simply locate the desired apk usingPackageManager, verify its authenticity, and extract the needed files. That's
fairly simple.
One last question. If the plugins are JNI libs, they get extracted in
<dataDir>/lib. Can another app (with a different UID) access these files
directly? I heard people saying that's possible. Can we rely on that too?
Oh, I had assumed the only difference was how the uid was allocated
(and obvious implications on file ownership/access). Yes, differing
permissions makes things murkier indeed.
> Honestly, I strongly discourage people from using shared user IDs. They are
> really an exception to the Android sandbox model, and thus create a number
> of strange behavior and situations. There *are* some situations where they
> are useful, really the only reason they were created: to allow multiple
> well-defined .apks to run their components in the same process. Note this
> is *not* the same as plug-ins; it is only a memory optimization. As I said,
> you will generally be much happier if you implement plug-ins as services so
> they can be isolated from the main application.
Also for anyone wanting easy cross-platform code. Dynamically loaded
modules are a fairly universal feature, whereas services are uniquely
Android.
>> Fwiw, I tried to describe this solution on Android bug 4381 but there
>> didn't seem to be any way to reopen a bug that was closed prematurely
>> and I suspect the comment was never seen by anyone who mattered.
>> Where would be the best place for me to file such a bug / feature
>> request?
>
> I closed the bug because I have no intention to change this.
That's unfortunate, but not unexpected. I will try to avoid
sharedUserIds in future apps.
Olivier: you may be interested in the plugin unpacker I have in
ScummVM. You can get the code here (or via svn):
http://scummvm.svn.sourceforge.net/viewvc/scummvm/scummvm/trunk/backends/platform/android/org/inodes/gus/scummvm/Unpacker.java
The current approach is to use an OrderedBroadcast protected by a
signature-protected permission to find the list of plugin packages.
It turns out that signature-protected permissions are busted if the
packages get installed in the wrong order (Android bug 5521), so I
intend to switch to verifying the signatures myself. The rest
(finding packages, unpacking libraries) should still be re-usable
as-is though.
It's under GPL (same as the rest of ScummVM), so you are encouraged to
use/steal non-trivial pieces of it provided you make your source
available too (paraphrasing).
- Gus
I'm waking up an old thread, which was mainly about loading native plugins.
On 12/30/2010 01:25 AM, Dianne Hackborn wrote:
> As I said, you will generally be much happier if you
> implement plug-ins as services so they can be isolated from the main
> application.
Ok, let's say that instead of plugins intended to be loaded with dlopen(), such
plugins are provided as services.
Now, in my case this is for audio plugins. I am not going to send and receive
all PCM audio data through AIDL calls, this is heavy, right?
So, how can I get a piece of shared memory to exchange audio data with a
service? I mean in the same manner as libmedia communicates with audioflinger.
Also, in user-code, accessing services can only be done in Java, not in native
code, right?
TIA
Olivier
Hello Dianne and others,
I'm waking up an old thread, which was mainly about loading native plugins.
Ok, let's say that instead of plugins intended to be loaded with dlopen(), such
On 12/30/2010 01:25 AM, Dianne Hackborn wrote:
> As I said, you will generally be much happier if you
> implement plug-ins as services so they can be isolated from the main
> application.
plugins are provided as services.
Now, in my case this is for audio plugins. I am not going to send and receive
all PCM audio data through AIDL calls, this is heavy, right?
So, how can I get a piece of shared memory to exchange audio data with a
service? I mean in the same manner as libmedia communicates with audioflinger.
Also, in user-code, accessing services can only be done in Java, not in native
code, right?
TIA
Olivier
I'm waking up that old thread again... Been thinking.
On 03/02/2011 06:00 AM, David Turner wrote:
>
> On 12/30/2010 01:25 AM, Dianne Hackborn wrote:
>
> > As I said, you will generally be much happier if you
> > implement plug-ins as services so they can be isolated from the main
> > application.
>
> Ok, let's say that instead of plugins intended to be loaded with
> dlopen(), such
> plugins are provided as services.
>
> Now, in my case this is for audio plugins. I am not going to send
> and receive
> all PCM audio data through AIDL calls, this is heavy, right?
>
> I can't comment on AIDL, but Unix-domain sockets are *very* fast on
> Linux, and much easier to setup/manager than a shared memory buffer.
Nice, thanks for the advice. But right now I'm interested in shared memory.
> So, how can I get a piece of shared memory to exchange audio data with a
> service? I mean in the same manner as libmedia communicates with
> audioflinger.
Any answer to this question? I know I could share memory between processes and
supposedly different apps by using mmap(). But there is a security issue,
because the mmap'ed file would need to be readable by all, since this is
intended for inter-apps communication.
So, how can I get a piece of shared memory between two apps (third-party) and
this in a secure manner?
--
Olivier