I made an Android app that internally calls su -c "pm ...". However, I get Permission denied when my app tries to execute this.
My app appears as Deny in the SuperUser log section, but CYM does not ask me via a Toast what I want to do, nor it appears in the Allow/Deny list...
Clues?
Thanks!
L.
I upgraded to CYM 11 M10, and now su works fine. No doubt it was a bug. So now I can mount/umount encrypted stuff as I was always able to do.
It seems the problem is solved in the M10 build.
Related
Background: I am developing for a signage device which is to be remotely operated. I need an application that can
Fetch and install new packages
Reboot the device (for troubleshooting)
I have an unrooted Android device. I also have files which I am told are the platform keys.
I have developed an application which attempts to kick off the su process.
Process p = Runtime.getRuntime().exec("su");
Before I signed the application with the platform keys this was throwing an IOException, with the message being Permission Denied.
I signed the application with these platform keys, and I am still getting the Permission Denied exception.
Here are three contradictory statements. Which one of these statements (if any) is correct?
Statment 1: This should work. The application, even though is is stored in /data/app, should be able to run su. Either I have the wrong keys, or there's some other entry I need to add to the manifest to get it to work.
Statement 2: This shouldn't work. Even though it is signed with the platform key, the application is in /data/app, so it's a data application, not a system application. Data applications cannot run su on an unrooted devices. If this application was installed into /system/app, then it would be able to run su. (And I can't get it into /system/app because it's unrooted, so I'm stuck).
Statment 3: This will never work. If the device is not rooted, then NOTHING can run su, even if it is a signed system app.
Android shouldn't even have a su binary if you didn't flash some sort of root method to the device, such as Magisk or SuperSU.
Even if it does have a su binary, I wouldn't expect it to work, for one of two reasons. Assuming that your device comes with a preinstalled su binary, who's managing it? If it's unmanaged, it should just deny all requests. If you flash a root method, then it's up to that manager to decide if your app gets access to su, regardless of whether you have signature-level permissions or nor (the root manager uses a different signature, after all).
And why would you even need access to su as a signature app? You have total access to the device anyway. If you need to run a command, you should have no problems no matter what you run, as long as it's done from your platform-signed package. But since you have full access, the native APIs should let you do everything you need.
As for the IOException returned when you try to execute su in a Process, that's just a weird Android quirk. If there's no su binary installed, it'll sometimes return command not found and other times permission denied, depending on the device.
The point I think I'm making is that, unless your app is the root manager, you could be part of the system_server and still have the same access to su as everyone else. For which statement I agree with, I think #3, although I don't fully agree with it, because chances are su just doesn't exist, or it's a dud binary.
I've explained why #1 shouldn't be true, but #2 is just incorrect. If you look at the platform manifest, every permission that requires a privileged app can also be granted to signature apps. So even if you did move your app to /system/priv-app/ (/system/app/ won't make it privileged), it wouldn't make a difference. Basically, if your app is signed by the platform signature, it doesn't matter where it's installed.
EDIT:
You can easily reboot by just running reboot as a command, since you have signature-level access to the system, but it's a little more elegant to use the proper API for this. If you use the API, you get the shutdown animation, but you also let the system shut down gracefully, stopping services and sending the ACTION_REBOOT broadcast to any apps that might be listening for that.
To use the API, first add the following permission to your AndroidManifest:
<uses-permission android:name="android.permission.STATUS_BAR_SERVICE" />
Now, where you need to call the reboot action, use the following code:
IStatusBarService bar = IStatusBarService.Stub.asInterface(ServiceManager.getService(Context.STATUS_BAR_SERVICE));
bar.reboot(false); //using true here will reboot to Safe Mode
This method is a hidden method, so if you're using Android Studio to edit and compile, it'll error out. You can use reflection, or use Android Hidden API to access it directly.
This is how System UI implements it in the power menu: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsComponent.java
This is the class that implements IStatusBar service: https://github.com/aosp-mirror/platform_frameworks_base/blob/master/services/core/java/com/android/server/statusbar/StatusBarManagerService.java#L969
I'd go with Statement 3. This will never work on an unrooted Android device. At least, not on recent Android OS versions (I have no idea if this might work on really old Android devices).
"su" is an application -- there has to be an "su" binary on disk in order to execute it, and Android does not by default provide an "su" binary for security purposes. When you use thirdparty rootkits, they install their own "su" binary to provide a mechanism for the user to elevate themselves to root privileges.
If your app is signed with a special key and granted elevated privileges from startup, why would you need to execute "su" anyway?
I am trying to port MIUI v6 to my phone (and no this thread is NOT about porting ROM, please read ahead).
First, its on Android 4.4.4
Now for problem->
It gets stuck on bootloop and I would like to know the cause. Now I do know how to take logcats using adb, but for some reason adb logcat doesnt detect phone during its bootanimation (and it doesnt go beyond bootanimation being it a bootloop). I am guessing it must have something to do with RSA fingerprint since there is no such key present being in/during the very first boot.
I have tried adding this to build.prop->
ro.debuggable=1
persist.sys.usb.config=mtp,adb
ro.adb.secure=0
But even that doesnt work. Now my base rom is CM 11 with default CM kernel. Since both rom and kernel are rooted, they are easily eligible to take a logcat during first boot.
At first I thought that it could be a miui rom-port problem. So I tested it with just CM simple rom installed. Ofcourse it booted fine and everything was fine, but even then I was unable to take logcat for first boot (it just doesn't "recognize" device until that RSA fingerprint authentication is accepted. I tested after adding the authentication and then it logged the boot just fine).
In addition to this, I have also attempted to pull last kernel message or kmsg, but I am unable to even pull that.
Finally, I also tried using init script. I added script to system/etc/init.d/ and the script had the following content:
#!/system/bin/sh
mount -o rw,remount "/system"
logcat > /sdcard/log.txt
Now this script does create a file, but that file is blank. No text at all.
So to sum it all, how can I take a logcat for very first boot without RSA fingerprint added? Any method goes. Even if I can make it store log in any partition anywhere, I can attempt to pull that log using adb pull. But for now, its not working.
What I'm doing:
I've built GNU emacs for native use on an phone.
I run emacs in daemon mode on the phone, so I connect to it anytime with emacsclient, to continue working with regular files, run processes, etc.
When logging in from the terminal on the phone, I'm currently user 10157, everything works:
$ id
uid=10157(10157) gid=10157(10157)
groups=10157(10157),1015(1015),1023(1023),1028(1028),3003(3003)
When I connect via ssh to the phone from a PC (I use DigiSSHd on the phone), it logs me in as a regular user 10282, everything works:
$ id
uid=10282 gid=10282 groups=1015(1015),1023(1023),1028(1028),3003(3003)
Emacs runs fine etc. However, this way I can't connect via emacsclient to the emacs process running under user 10157. This is desirable, since I don't want to start two emacs processes, since I want to continue working with files that I have open in emacs under user 10157.
Therefore:
$ su - 10157
Fine, I can run emacs etc. However, I cannot access the web.
$ ping -c1 google.com
You must have internet permissions to use ping. Aborting.
$ id
uid=10157(10157) gid=10157(10157) groups=10157(10157)
Thus I'm no longer in group 3003, necessary for internet access, besides other groups also.
Why does this group info get stripped, and how can I remedy this, so I can continue accessing the web when su as this user under ssh?
When i run the command:
busybox --list
I don't see su in the list.
su --help
shows Superuser.apk in the help text. It means su is provided by Superuser app.
I followed the steps described by you and i could su as another user and still have internet permission as shown below.
I have the following apps installed.
BusyBox v1.18.5-Stericson
Superuser v3.0.7
Terminal Emulator v1.0.45
SSHDroid v1.9.6
Suggestion:
I think the issue is with su on your device. You may try this one.
https://play.google.com/store/apps/details?id=com.noshufou.android.su
If i just use adb shell without running SSHDroid still i can su as another user with internet permission.
Note: The BusyBox id command doesn't show groups information always.
According to the standard man page for su (from a linux box)
When - is used, it must be specified as the last su option. The other forms (-l and --login) do not have this restriction.
Based on that, try
$ su 10157 -
I'm probably missing something here because this seems way too obvious but why not just 'sudo -u 10157' your emacs program?
you'd still have access to the net and your emacs would be working. or did I miss something important?
Permissions are not environment variables that can be inherited via su -.
Moreover, gid are are hard coded and their associations with each APP uid cannot be changed after installation.
10157 should be the uid of the DigiSSHd application, thus you could try to rebuild it after changing the AndroidManifest.xml to require the proper permission.
You can find something useful here and here.
The same should work for BusyBox (see here).
However, you could open some security hole by enabling NETWORK access through such applications.
There is a bug on some Samsung Android Phones causing USB-debugging to automatically be turned on if the USB is plugged in. This is obviously a security issue. I want to write a program which will disable USB debugging so that I can start it whenever usb-plug is inserted.
Any ideas on how to do this?
It seems to be impossible. I think I must use Settings.System with ADB_ENABLED, but ADB_ENABLED is a Secure-System-Setting which cannot be changed by a normal application. :-(
On the other hand, there is the permission android.permission.WRITE_SECURE_SETTINGS, so it looks like I can alter it. Can I get it on a rooted phone?
If someone has an idea on how to fix this security issue, it would be great.
I don't think it is a security issue.
First, it is the responsibility of a developer to only make debug messages available that do not compromise his application in the later.
Secondly, debug messages that are used for development should probably have another debug level than for production.
Third, if your application exposes data via adb that compromisses your application, maybe there's something wrong in the app design in the beginning?
Fourth: It is not recommended to toggle settings that the user should be able to configure. I would hate to see manything I configured go on and off by starting an app. Of course, you mentioned the Bug with Samsung. But I think they should be able to fix this.
Regards, Chris
To achieve this , you require android.permission.WRITE_SECURE_SETTINGS permission.
Without root : From ABD execute adb shell pm grant <package-name> android.permission.WRITE_SECURE_SETTINGS
With root : Root access means we can execute shell commands without adb, so workaround for that :
try {
Runtime.getRuntime().exec(new String[]{"su","-c",String.format("pm grant %s android.permission.WRITE_SECURE_SETTINGS",BuildConfig.APPLICATION_ID)});
} catch (IOException e) {
// handle IOException
}
I am developing an application and during my testing on a real device I have found that it will crash and cause the phone to reboot (worrying I know...)
Is there any way I retrieve the logcat from before the phone rebooted as the logcat seems to reset when the phone boots up.
Thanks in advance.
Use http://code.google.com/p/acra/, which is a great lib to send crash reports to a google form incl. stack trace. I use it in my app and works nicely. Let me know if you have any difficulties implementing it.
Read the http://code.google.com/p/acra/wiki/ACRAHowTo, it's easy to setup.
From slashfoo's blog, (check the logcat page for exact syntax)
hook up your computer to start off the logcat process in the background.
adb shell nohup logcat -f /dev/[your sdcard] -n60 -r3600
Although it means logcat will be saved to the sdcard but every time you reboot, you must perform the procedure again.
Easiest way:
Get aLogrec from Market for free.
This app saves the logs to sdcard.
Use the alogrec program. It writes the log to the SD card, and will automatically resume after rebooting.
Updating for 2019, Fabric, which was purchased by Google, does an excellent job of remote logging app crashes. Integration into the app was simple, and it is free (at least at whatever level I'm using it).
It has been extremely valuable to finding defects in my apps.
https://www.fabric.io
Try to open a terminal/command prompt and issue this in it :
adb -d logcat
This should dump you a live version of the logcat you could read to find the problem