My native process runs under root on Android device. Is it possible to modify UID of another process in order to give it the root?
The reason is to give an access to some Android "features" that inaccessible for non-root processes.
If you have a rooted phone, you can run processes explicitly using (usually) /system/xbin/su. You can't change the uid of a program that's already running, though. (In theory you could poke at kernel memory and change all the various stored uids, but this is a really bad idea because you can't lock the things you're modifying and if they change or move you could cause a kernel panic.)
No. If another app needs root access it needs to gain permissions itself.
You need make a exec bin(A) run as root and do:
attach to the process which you want to change the uid
get the state of the process and save
call the setuid system call remote
use the saved state to detach the process.
All above can be done by ptrace.
More info can be found here:
http://www.linuxjournal.com/node/6210/print
http://www.phrack.org/issues.html?issue=59&id=12&mode=txt
Related
I'm having trouble understanding the use cases for AtomicFile. Since it does not confer any thread safety, is it just for ensuring no partial/invalid files are written if the app crashes or device loses power during a file write? What would be the purpose of reading a file with AtomicFile?
is it just for ensuring no partial/invalid files are written if the app crashes or device loses power during a file write?
Yes.
Adding on to the cases, the OS can kill the process at anytime. AtomicFile should provide atomic guarantees in that case too.
as far as i understand each android process runs in a "sandbox" environment, what happen if an android application is a multi process application? do all processes use the one single sandbox since all the processes use the same user id?
As Android uses the Linux kernel for sanboxing, the real sandbox is per (unix) user id, rather than per process. And the Dalvik VM itself makes no attempt at sandboxing.
Of course proccesses owned by the same user id are somewhat isolated from each other, but tools like kill(), ptrace() and the /proc filesystem which pierce process isolation are available - and governed primarily by user id isolation.
There are a couple of oddities about how code maps to processes however:
Either an Activity or a Service can be designated in the manifest to run in a distinct process, but this will still be a process owned by the package user id
Distinct application packages with the same signing certificate can use the shared user id feature to share a sandbox; in some cases this can result in their code running in the same process.
The multiprocess attribute of the <activity> tag says that the activity could run in the process of whatever starts it - it's not entirely clear if this could mean it would end up running under a foreign userid (an idea that seems more risky for the caller than the callee).
The isolatedprocess attribute of the <service> says that it runs the service in an isolated process with "no permissions of its own" - while it doesn't come out and explicitly say so, I suspect this may mean that this would be a process owned by a distinct, minimally privileged user id.
A more definitive explanation on these last two points would be good. Perhaps I'll look at the implementing code when I have more time.
Each process is associated with a separate runtime (JVM) and sandbox in Android.
For example, if you tune couple of your activities to run on a separate processes (to take advantage of having a distinct memory space) then you end up with having 2 sandboxes when you launch the app and have to manage IPC if needed.
Another example is - if you set two different apps to share the same user id then you won't need IPC since they can see each other's data, but that doesn't mean they run on the same process or sandbox. You need to set process attribute of application element in the manifest.
Out of the context, you can also have multiple components belongs to separate apps to easy sharing and saving memory.
I am currently working on an Android project that monitors what applications a user is running and cross-checks the corresponding processes with a whitelist stored internally on the device.
In order to make this work, I need to know what the default or system processes for the device are so I can add them to the whitelist. That being said, I have a few questions I was hoping you might be able to answer:
Is there a way to differentiate between a default/system process that MUST be running, and a process that belongs to an app on the device?
Are there different default/system processes depending on what phone/version of android the user is running?
If so, are those process names available somewhere for developer use? Or is there some other way to obtain them?
If I need to elaborate more please let me know, thanks for the help.
Let's say that you try ActivityManager and getRunningAppProcesses(). Iterate over that array of RunningAppProcessInfo objects and find those with importance of IMPORTANCE_FOREGROUND. If the docs are correct (haven't tried this), there should only be one process that is IMPORTANCE_FOREGROUND -- the one that is truly in the UI foreground.
(services can call a startForeground() method to get foreground priority, but I am guessing they have IMPORTANCE_PERCEPTIBLE)
You could then examine the pkgList of that foreground process and compare that against your whitelist.
However, this breaks down if:
Something pops up asynchronously (alarm clock app, incoming phone call, etc.)
An app that is logically in your whitelist has changes that affect its package name (e.g., developer released a "pro" app that a student paid for, and the whitelist only has the free app)
if the device has multiple visible items (e.g., Samsung's multi-window capabilities), if all visible apps are not IMPORTANCE_FOREGROUND
This at least gets rid of the problem of pure background stuff that the student cannot control, including your "default/system processes".
However, it requires you to continuously poll, which will be a serious detriment to battery life. That, plus the privacy implications, means to me that this app should, at best, only be used for exams, and should be something that the student can install shortly before the exam and remove shortly after the exam.
Well I think my team and I have come up with the best solution so far. After reading the Android Docs, we found that by using ActivityManager.getRunningServices() we can use the constant FLAG_SYSTEM_PROCESS to determine what processes are core system processes. Then all we would do is cross-check that with the total list of running processes to differentiate between them.
I'm investigating the possible ways of obtaining superuser privileges in a Java Android application and/or its own JNI. The well-known answer seems to be that it's only possible to run a "su" subshell and command line commands from there, which is neither neat nor very practical. I am willing to accept this resolution but still I'd like to hear an opinion on this "what if" scenario.
Reading through Android sources near java.com.android.server.am.ActivityManagerService, java.android.os.Process and the dalvik_system_Zygote.cpp file, it seems to me that during application launch, the application record is examined for the UID and (a list of) GID(s) and all these values are passed to the Zygote through a socket. Z subsequently picks the data up and passes it, without further checks, to setuid() posterior to a fork() call. Therefore, it seems to me that if the Activity Manager pathway was altered, a simple passing of --setuid=0 and perhaps --setgid=0 to the Zygote socket should result in running my Activity with the root UID.
It all seems almost too simple, I suspect that something would go wrong along the way. Unfortunately, there's too much code and new stuff for an inexperienced programmer like me to actually go and try. Has anyone gone this way, or is there any obvious reason why this would NOT work?
I think I just found the answer to my own question. Credits go to #Chris Stratton who pointed me at using the emulator and also pointed out how ridiculous a situation this would be.
The key was in one place where I did not look, between sending commands through the Zygote socket and the Zygote binary itself. The point where the check takes place is com.android.internal.os.ZygoteConnection, method applyUidSecurityPolicy. If the caller process belongs to root, the UID of the spawn may be indeed requested to be zero (or anything else, for that matter). A regular user may use the socket as well but asking for a new UID or GID results in a ZygoteSecurityException.
I am getting started on Android & iOS development and hence links to relevant resources will also be appreciated, just that I couldn't find anything much relevant.
Case Detail: I have to build an app that holds some critical information in a variable that is created, sent over a ssl-encrypted connection and destroyed. This variable shouldn't be read by any other process on the device. So far, I know of two cases that can happen:
[1] a service or program monitors the foreground app(which here would be my app) and then if it can inject some code(getting the foreground to bind to the rogue service for example) to read off the variable contents in question. I know OS safeguards exist, but are there any proofs out in the wild that demonstrate this ability of injecting code?
[2] a service or program monitors the network connections and logs the data being sent over the wire. Is there a possibility of apps reading network data like this? I know apps exist which can log the amount of data exchanged per app, but I have no clue as to whether they read system log files or actually monitor the connection.
It will be appreciated if details could be provided for both the platforms.
I work only with android, so this is valid for android only:
No, a service cannot inject code in foreground up, due to (at least) 2 reasons:
Each installed application gets it's own user id, and each process, and their data is protected by the user id. So one process cannot access the memory of another process. So no process can modify the memory either (by inserting code)
The java bytecode is converted to dalvik code, and stored in a place where only the system process can write. So no other process can inject code by changing the compiled dex files.
That is the protection provided by the system. Of course hackers might find an exploit in a certain library, and using buffer overflow might be able to run some snippet of code, but that's a different story. Also note that the data files of the process are private by default (no other process can see it), but processes could have read access to the code. Which means storing private keys in the code is probably not safe.