I am trying to set the Settings.Global.PACKAGE_VERIFIER_ENABLE value in Android by using
Settings.Global.putInt(mContext.getContentResolver(),key,value);
However, what ever value I set , I was not getting the value when do following adb command.
adb shell settings get global package_verifier_enable
Thanks InAdvance
in the official android documentation is described that
Applications can read these but are not allowed to write; like the "Secure" settings, these are for preferences that the user must explicitly modify through the system UI or specialized APIs for those values.
This means that unless your app is running as system you're not allowed to write to those settings.
If you have the right signing certificate for the android operating system that you're using, you can sign your app to run with system privileges. As long as you're just running as a "normal" app there is no way to modify these settings.
You can however (which is bad practice) use su to set this setting via
su -c 'settings set global package_verifier_enable 0'
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?
At work, we have an Android-based infotainment system that we're constantly deploying new versions to, on a half-dozen different test benches. The deployment script does the moral equivalent of:
for apk in ${apk_files}; do
adb install -r ${apk]
done
After this, we need to manually execute the following steps:
Set the home app to be one of our just-installed applications (Always, not Just Once)
Become a developer, and enable the Stay Awake option
Select the Google TTS engine for text-to-speech functionality rather than Pico
Executing these steps after each deploy is a giant PITA. People often forget one or more steps, and leave the test bench in a non-working state. This results in a bunch of 'bogus' bug reports that waste everbody's time.
Is there some way (using adb, perhaps) that we can automate these steps?
You can disable other home apps with adb shell pm disable .... I don't think there's a command line option to set apps as default. I remember looking into this before and there was a "preferred application" XML file where this was stored. If you want to look into it, the magic happens in PackageManagerService.addPreferredActivityInternal(). Looks like it writes the data to a file on disk: package-restrictions.xml. I suppose it's possible you could figure out the format thereof and write the file (you'd need root).
This is controlled by a system settings, "stay_on_while_plugged_in". You can set it using adb shell settings system put ....
The TTS engine is stored in a secure setting, "tts_default_synth". You can see the value like,
$ adb shell settings get secure tts_default_synth com.svox.pico
com.svox.pico
And you can set it with adb shell settings put secure "tts_default_synth" <the value>.
I noticed that if the value was not been previously set, when you get the value using the settings command you get null and it's not listed in settings list, even though there is a default value. As of Android 6 (I think), settings are no longer in a DB but rather are stored in XML files in /data/system/users/0/settings_*.xml. You can see the values therein.
What linux permissions are needed for SystemProperties.set to work? (android)
I am writing an app that runs in system/app on an android device.
It is running as
android:sharedUserId="android.uid.systemui"
in Android.mk
LOCAL_CERTIFICATE := platform
However, I am finding that I cannot create, write or set a property.
In the console, I can do a getprop, setprop.
However, my program cannot create it.
ls -l /data/property/
shows it does not exist.
Slog.d(TAG, "key is not set, will set APPLE");
SystemProperties.set(keyName, favorite);
if(SystemProperties.get(keyName).equals(favorite)) {
Slog.d(TAG, keyName + " = " + SystemProperties.get(keyName));
} else {
Slog.e(TAG, "setting SystemProperties failed. value written = " + SystemProperties.get(keyName));
}
logcat:
Line 1365: D/MyTag( 2593): keyName: persist.fruit.user.favorite
Line 1373: D/MyTag( 2593): keyName has value []
Line 1377: D/MyTag( 2593): key is not set, will set APPLE
Line 1381: E/MyTag( 2593): setting SystemProperties failed. value written =
evidently perhaps it is a matter of insufficient permissions - but which ones?
I had accepted fadden's answer but after more exploration, found it was incorrect though it was very helpful in reaching the correct answer.
step 1:
look at the array in https://android.googlesource.com/platform/system/core/+/kitkat-release/init/property_service.c
{ "persist.sys.", AID_SYSTEM, 0 },
the name of your property should begin with the same key string in the array.
thus I had to change my property name to "persist.sys.fruit.user.favorite"
step 2:
in your android manifest file, run as user id mentioned in the array above.
<manifest android:sharedUserId="android.uid.system" >
It depends. In the 4.4 "KitKat" release, the list was contained in init's property_service.c (look around line 65). You can see, for example, that properties named debug.* can be updated by the "system" or "shell" user. (The mapping of system-recognized user IDs to numeric values can be found in android_filesystem_config.h.)
Some properties, such as ro.*, persist.*, and ctl.*, have additional restrictions or special behaviors.
In Android 5.0 "Lollipop", the list moved, but the behavior is the same.
Use adb shell ps to see what user ID your app is running under. If it's not system or shell, it won't be able to set system properties.
TL;DR: The rules on Android 5+ are more or less the same as for Android 4.4. Check the whitelist from the accepted answer and use a system app for writing sysprops.
Since Android 5 access to system properties is controlled only by SELinux policies. Depending on source security context (where you're calling from) you will have access to different system properties, which live in a designated target security context. A system service running in system server has more access than an app running with shared system UID - a system app.
The rules consist of several files:
property_contexts - maps system property prefixes to SELinux contexts
shell.te - specifies (among other) which properties are settable by ADB shell (or an app with shell UID)
system_app.te - specifies which properties are settable by a system app (an app with system UID)
system_server.te - specifies which properties are accessible from the system server
Context files are available on the device in location that varies with system version. *.te files are compiled to a binary file.
The default values are stored in AOSP repositories and both the values and the location changed over the years.
Lollipop
https://android.googlesource.com/platform/external/sepolicy/+/lollipop-release/property_contexts
https://android.googlesource.com/platform/external/sepolicy/+/lollipop-release/system_app.te
https://android.googlesource.com/platform/external/sepolicy/+/lollipop-release/shell.te
Nougat
https://android.googlesource.com/platform/system/sepolicy/+/nougat-release/property_contexts
https://android.googlesource.com/platform/system/sepolicy/+/nougat-release/system-app.te
https://android.googlesource.com/platform/system/sepolicy/+/nougat-release/shell.te
Oreo
https://android.googlesource.com/platform/system/sepolicy/+/oreo-release/private/property_contexts
https://android.googlesource.com/platform/system/sepolicy/+/oreo-release/public/property.te
https://android.googlesource.com/platform/system/sepolicy/+/oreo-release/public/system_app.te
https://android.googlesource.com/platform/system/sepolicy/+/oreo-release/public/shell.te
Notes
Generally you'd want to set system properties as a system app with one exception. Only a shell UID app may write log.tag. until Pie. A system UID app may also write log.tag. since Pie.
seapp_contexts defines SELinux contexts for apps. On Pie you can't run an app with shell system UID.
For more information see https://source.android.com/security/selinux/images/SELinux_Treble.pdf
Does anyone know just where in the Android stack the "Restrict Background Data" setting is enforced and how it is enforced? (I.e. apps in the background are not allowed to use the phone data network while running in the background - WIFI not affected.)
Thanks much,
Dawg
Android uses iptables rules as on any linux box to restrict data-access to certain users (every user downloaded app on android runs under its own unique user id).
If you wish to remove restriction for your app, you can remove the rule from a root shell.
iptables -F penalty_box -j REJECT
or on newer devices, as below:
iptables -F bw_penalty_box -j REJECT
However on a restart, Android will re-enforce the rule to iptables automatically. To prevent this, you need to remove <uid-policy ...> from "/data/system/netpolicy.xml". Global Restrict Background Data settings can be removed by setting "restrictBackgroundData" atribute to "false" on <policy-list ...> node.
Along with the netpolicy.xml changes, you must perform a reboot for your changes to take effect.
Note: Any of these operations may require to be run as root.
Is it possible to disable the "grant/deny" popup dialog when my app needs to perform tasks that require root access? I have full control of the device the app will run on (internal project), the device is rooted and it has supersu 2.x app.
This tells me that I need to declare the android.permission.ACCESS_SUPERUSER permission for my app to disable the popup, but it has no effect.
Is there a simple way to solve this (without changing the option i supersu app settings)?
Remove the SuperSU APK (usually either /system/app/Superuser.apk or /data/app/eu.chainfire.supersu*.apk or /system/app/SuperSU/SuperSU.apk) and rm -rf the /data/data/eu.chainfire.supersu directory, and the su command will always grant access without showing the prompt.
If you're making a custom firmware image for your project, just exclude the APK.
Note that pm path eu.chainfire.supersu from an adb shell will give you the exact path for the APK.
You can't decide in you app to disable the prompt. That's a security measure which no app can change.
If your device is rooted and you have supersu, you can still get rid of the dialog. You have to change a setting in supersu: Settings --> Access --> Default access --> Grant
This is not possible, you can't interfere with the logic of another app, i.e. the one showing the popup when su is accessed (for example Superuser).