summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorJoman Chu <jcchu@tycho.ncsc.mil>2012-11-16 13:09:27 -0500
committerRicardo Cerqueira <cyanogenmod@cerqueira.org>2013-07-18 20:56:46 +0100
commitae74c84819ce2a174d3df98d9888206938b0ebee (patch)
tree9367007db64a5744f7966f6d18f5262df20b7c2c /core
parent88aeb650afb72aeff6335ebfc9bfee59ed5751c8 (diff)
downloadframeworks_base-ae74c84819ce2a174d3df98d9888206938b0ebee.zip
frameworks_base-ae74c84819ce2a174d3df98d9888206938b0ebee.tar.gz
frameworks_base-ae74c84819ce2a174d3df98d9888206938b0ebee.tar.bz2
Add APIs to allow Device Admins to change SELinux settings
These calls, added to the Device Admin API, will allow Device Admin apps to change various SELinux settings, including: * Toggling SELinux enforcing and permissive modes * Toggle SELinux booleans * Load a new SELinux policy file (sepolicy) * Load new SELinux context files ({property,file,seapp}_contexts) In order to use these APIs, a Device Admin must first request USES_POLICY_ENFORCE_SELINUX, then become a SELinux Admin by calling setSELinuxAdmin(). All other set* calls relevant to SELinux are guarded by a check against whether the admin is a SELinux Admin. Otherwise, the style of the set* calls are very similar to the other calls setting device policy in the Device Admin API. That is, these calls change the Admin's internal state and then call a sync method to update the device's state to the Admin's state. Change-Id: I01f2a9084dfe7886087b1497070b0d7f2ad8476e
Diffstat (limited to 'core')
-rw-r--r--core/java/android/app/admin/DeviceAdminInfo.java13
-rw-r--r--core/java/android/app/admin/DevicePolicyManager.java297
-rw-r--r--core/java/android/app/admin/IDevicePolicyManager.aidl13
-rw-r--r--core/res/res/values/strings.xml4
-rw-r--r--core/res/res/values/symbols.xml2
5 files changed, 328 insertions, 1 deletions
diff --git a/core/java/android/app/admin/DeviceAdminInfo.java b/core/java/android/app/admin/DeviceAdminInfo.java
index 66fc816..6849a96 100644
--- a/core/java/android/app/admin/DeviceAdminInfo.java
+++ b/core/java/android/app/admin/DeviceAdminInfo.java
@@ -146,6 +146,14 @@ public final class DeviceAdminInfo implements Parcelable {
*/
public static final int USES_POLICY_DISABLE_KEYGUARD_FEATURES = 9;
+ /**
+ * A type of policy that this device admin can use: enforce SELinux policy.
+ *
+ * <p>To control this policy, the device admin must have a "enforce-selinux"
+ * tag in the "uses-policies" section of its meta-data.
+ */
+ public static final int USES_POLICY_ENFORCE_SELINUX = 10;
+
/** @hide */
public static class PolicyInfo {
public final int ident;
@@ -197,6 +205,9 @@ public final class DeviceAdminInfo implements Parcelable {
USES_POLICY_DISABLE_KEYGUARD_FEATURES, "disable-keyguard-features",
com.android.internal.R.string.policylab_disableKeyguardFeatures,
com.android.internal.R.string.policydesc_disableKeyguardFeatures));
+ sPoliciesDisplayOrder.add(new PolicyInfo(USES_POLICY_ENFORCE_SELINUX, "enforce-selinux",
+ com.android.internal.R.string.policylab_enforceSelinux,
+ com.android.internal.R.string.policydesc_enforceSelinux));
for (int i=0; i<sPoliciesDisplayOrder.size(); i++) {
PolicyInfo pi = sPoliciesDisplayOrder.get(i);
@@ -389,7 +400,7 @@ public final class DeviceAdminInfo implements Parcelable {
* {@link #USES_POLICY_RESET_PASSWORD}, {@link #USES_POLICY_FORCE_LOCK},
* {@link #USES_POLICY_WIPE_DATA},
* {@link #USES_POLICY_EXPIRE_PASSWORD}, {@link #USES_ENCRYPTED_STORAGE},
- * {@link #USES_POLICY_DISABLE_CAMERA}.
+ * {@link #USES_POLICY_DISABLE_CAMERA}, {@link #USES_POLICY_ENFORCE_SELINUX}.
*/
public boolean usesPolicy(int policyIdent) {
return (mUsesPolicies & (1<<policyIdent)) != 0;
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 719f050..a80898e 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -1421,6 +1421,303 @@ public class DevicePolicyManager {
}
/**
+ * Called by an application that is administering the device to start or stop
+ * controlling SELinux policies, enforcement, booleans, etc. When an admin app
+ * gives up control of SELinux policies, the policy in place prior to the app
+ * taking control will be applied.
+ *
+ * <p>The calling device admin must have requested
+ * {@link DeviceAdminInfo#USES_POLICY_ENFORCE_SELINUX} to be able to call
+ * this method; if it has not, a security exception will be thrown.
+ *
+ * <p>When an application gains control of SELinux settings, it is called an
+ * SELinux administrator. Admistration applications will call this with true and
+ * ensure this method returned true before attempting to toggle SELinux settings.
+ * When apps intend to stop controlling SELinux settings, apps should call this
+ * with false.
+ *
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated,
+ * must be self
+ * @param control true if the admin wishes to control SELinux, false if the admin
+ * wishes to give back control of SELinux
+ * @return true if the operation succeeded, false if the operation failed or
+ * SELinux was not enabled on the device.
+ */
+ public boolean setSELinuxAdmin(ComponentName admin, boolean control) {
+ return setSELinuxAdmin(admin, control, UserHandle.myUserId());
+ }
+
+ /** @hide per-user version */
+ public boolean setSELinuxAdmin(ComponentName admin, boolean control, int userHandle) {
+ if (mService != null) {
+ try {
+ return mService.setSELinuxAdmin(admin, control, userHandle);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed talking with device policy server", e);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks whether an admin app has control over SELinux policy.
+ *
+ * <p>The calling device admin must have requested
+ * {@link DeviceAdminInfo#USES_POLICY_ENFORCE_SELINUX} to be able to call
+ * this method; if it has not, a security exception will be thrown.
+ *
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated,
+ * must be self
+ * @return true if admin app can control SELinux policy, false otherwise
+ */
+ public boolean isSELinuxAdmin(ComponentName admin) {
+ return isSELinuxAdmin(admin, UserHandle.myUserId());
+ }
+
+ /** @hide per-user version */
+ public boolean isSELinuxAdmin(ComponentName admin, int userHandle) {
+ if (mService != null) {
+ try {
+ return mService.isSELinuxAdmin(admin, userHandle);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed talking with device policy server", e);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Called by a SELinux admin to set SELinux into enforcing or permissive mode.
+ *
+ * <p>The calling device admin must have requested
+ * {@link DeviceAdminInfo#USES_POLICY_ENFORCE_SELINUX} to be able to call
+ * this method; if it has not, a security exception will be thrown.
+ *
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+ * @param enforcing true for enforcing mode, false for permissive mode.
+ * @return false if Android was unable to set the desired mode
+ */
+ public boolean setSELinuxEnforcing(ComponentName admin, boolean enforcing) {
+ return setSELinuxEnforcing(admin, enforcing, UserHandle.myUserId());
+ }
+
+ /** @hide per-user version */
+ public boolean setSELinuxEnforcing(ComponentName admin, boolean enforcing, int userHandle) {
+ if (mService != null) {
+ try {
+ return mService.setSELinuxEnforcing(admin, enforcing, userHandle);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed talking with device policy server", e);
+ }
+ }
+ return false; // I guess this doesn't fit the spec, but it never happens...
+ }
+
+ /**
+ * Determine whether or not SELinux policies are currently being enforced
+ * by the current admin.
+ *
+ * <p>The calling device admin must have requested
+ * {@link DeviceAdminInfo#USES_POLICY_ENFORCE_SELINUX} to be able to call
+ * this method; if it has not, a security exception will be thrown.
+ *
+ * <p>The returned value is only meaningful if the current admin is a
+ * SELinux admin.
+ *
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+ */
+ public boolean getSELinuxEnforcing(ComponentName admin) {
+ return getSELinuxEnforcing(admin, UserHandle.myUserId());
+ }
+
+ /** @hide per-user version */
+ public boolean getSELinuxEnforcing(ComponentName admin, int userHandle) {
+ if (mService != null) {
+ try {
+ return mService.getSELinuxEnforcing(admin, userHandle);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed talking with device policy server", e);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Get a list of the SELinux booleans available on the system.
+ *
+ * <p>The calling device admin must have requested
+ * {@link DeviceAdminInfo#USES_POLICY_ENFORCE_SELINUX} to be able to call
+ * this method; if it has not, a security exception will be thrown.
+ *
+ * <p>The returned value is only meaningful if the current admin is a
+ * SELinux admin.
+ *
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+ */
+ public List<String> getSELinuxBooleanNames(ComponentName admin) {
+ return getSELinuxBooleanNames(admin, UserHandle.myUserId());
+ }
+
+ /** @hide per-user version */
+ public List<String> getSELinuxBooleanNames(ComponentName admin, int userHandle) {
+ if (mService != null) {
+ try {
+ return mService.getSELinuxBooleanNames(admin, userHandle);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed talking with device policy server", e);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get the value of a SELinux boolean.
+ *
+ * <p>The calling device admin must have requested
+ * {@link DeviceAdminInfo#USES_POLICY_ENFORCE_SELINUX} to be able to call
+ * this method; if it has not, a security exception will be thrown.
+ *
+ * <p>The returned value is only meaningful if the current admin is a
+ * SELinux admin.
+ *
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+ * @param name the name of the SELinux boolean
+ * @return the value of the SELinux boolean
+ */
+ public boolean getSELinuxBooleanValue(ComponentName admin, String name) {
+ return getSELinuxBooleanValue(admin, name, UserHandle.myUserId());
+ }
+
+ /** @hide per-user version */
+ public boolean getSELinuxBooleanValue(ComponentName admin, String name, int userHandle) {
+ if (mService != null) {
+ try {
+ return mService.getSELinuxBooleanValue(admin, name, userHandle);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed talking with device policy server", e);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Set the value of a SELinux boolean.
+ *
+ * <p>The calling device admin must have requested
+ * {@link DeviceAdminInfo#USES_POLICY_ENFORCE_SELINUX} to be able to call
+ * this method; if it has not, a security exception will be thrown.
+ *
+ * <p>The returned value is only meaningful if the current admin is a
+ * SELinux admin.
+ *
+ * @param admin Which {@link DeviceAdminReceiver} this request is associated with.
+ * @param name the name of the SELinux boolean
+ * @param value the desired value for the boolean
+ * @return false if Android was unable to set the desired mode
+ */
+ public boolean setSELinuxBooleanValue(ComponentName admin, String name,
+ boolean value) {
+ return setSELinuxBooleanValue(admin, name, value, UserHandle.myUserId());
+ }
+
+ /** @hide per-user version */
+ public boolean setSELinuxBooleanValue(ComponentName admin, String name,
+ boolean value, int userHandle) {
+ if (mService != null) {
+ try {
+ return mService.setSELinuxBooleanValue(admin, name, value, userHandle);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed talking with device policy server", e);
+ }
+ }
+ return false;
+ }
+
+ // Before changing these values, be sure to update
+ // DevicePolicyManagerService.java's POLICY_DESCRIPTIONS array.
+ public static final int SEPOLICY_FILE_SEPOLICY = 0;
+ public static final int SEPOLICY_FILE_PROPCTXS = 1;
+ public static final int SEPOLICY_FILE_FILECTXS = 2;
+ public static final int SEPOLICY_FILE_SEAPPCTXS = 3;
+ public static final int SEPOLICY_FILE_COUNT = SEPOLICY_FILE_SEAPPCTXS+1;
+
+ /**
+ * Sets a new policy file and reloads it at the proper time.
+ *
+ * <p>For {@link #SEPOLICY_FILE_SEPOLICY}, {@link #SEPOLICY_FILE_PROPCTXS},
+ * {@link #SEPOLICY_FILE_FILECTXS}, and {@link #SEPOLICY_FILE_SEAPPCTXS}, the admin
+ * must have requested {@link DeviceAdminInfo#USES_POLICY_ENFORCE_SELINUX}
+ * before calling this method. If it has not, a security exception will be
+ * thrown.
+ *
+ * <p>For {@link #SEPOLICY_FILE_SEPOLICY}, {@link #SEPOLICY_FILE_PROPCTXS},
+ * {@link #SEPOLICY_FILE_FILECTXS}, and {@link #SEPOLICY_FILE_SEAPPCTXS}, these
+ * files are reloaded before returning from the DevicePolicyManager.
+ *
+ * <p>For {@link #SEPOLICY_FILE_SEPOLICY}, {@link #SEPOLICY_FILE_PROPCTXS},
+ * {@link #SEPOLICY_FILE_FILECTXS}, and {@link #SEPOLICY_FILE_SEAPPCTXS}, the
+ * returned value is only meaingful if the current admin is a SELinux
+ * admin.
+ *
+ * @param admin which {@link DeviceAdminReceiver} this request is associated with
+ * @param policyType one of {@link #SEPOLICY_FILE_SEPOLICY}, {@link #SEPOLICY_FILE_PROPCTXS},
+ * {@link #SEPOLICY_FILE_FILECTXS}, or {@link #SEPOLICY_FILE_SEAPPCTXS}
+ * @param policy the new policy file in bytes, or null if you wish to revert to
+ * the default policy
+ * @return false if Android was unable to set the new policy
+ */
+ public boolean setCustomPolicyFile(ComponentName admin, int policyType, byte[] policy) {
+ return setCustomPolicyFile(admin, policyType, policy, UserHandle.myUserId());
+ }
+
+ /** @hide per-user version */
+ public boolean setCustomPolicyFile(ComponentName admin, int policyType, byte[] policy, int userHandle) {
+ if (mService != null) {
+ try {
+ return mService.setCustomPolicyFile(admin, policyType, policy, userHandle);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed talking with device policy server", e);
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Determine whether this admin set a custom policy file.
+ *
+ * <p>For {@link #SEPOLICY_FILE_SEPOLICY}, {@link #SEPOLICY_FILE_PROPCTXS},
+ * {@link #SEPOLICY_FILE_FILECTXS}, and {@link #SEPOLICY_FILE_SEAPPCTXS}, the admin
+ * must have requested {@link DeviceAdminInfo#USES_POLICY_ENFORCE_SELINUX}
+ * before calling this method. If it has not, a security exception will be
+ * thrown.
+ *
+ * <p>For {@link #SEPOLICY_FILE_SEPOLICY}, {@link #SEPOLICY_FILE_PROPCTXS},
+ * {@link #SEPOLICY_FILE_FILECTXS}, and {@link #SEPOLICY_FILE_SEAPPCTXS}, the
+ * returned value is only meaingful if the current admin is a SELinux
+ * admin.
+ *
+ * @param admin which {@link DeviceAdminReceiver} this request is associated with
+ * @param policyType one of {@link #SEPOLICY_FILE_SEPOLICY}, {@link #SEPOLICY_FILE_PROPCTXS},
+ * {@link #SEPOLICY_FILE_FILECTXS}, or {@link #SEPOLICY_FILE_SEAPPCTXS}
+ * @return true if the admin set a custom policy file
+ */
+ public boolean isCustomPolicyFile(ComponentName admin, int policyType) {
+ return isCustomPolicyFile(admin, policyType, UserHandle.myUserId());
+ }
+
+ /** @hide per-user version */
+ public boolean isCustomPolicyFile(ComponentName admin, int policyType, int userHandle) {
+ if (mService != null) {
+ try {
+ return mService.isCustomPolicyFile(admin, policyType, userHandle);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed talking with device policy server", e);
+ }
+ }
+ return false;
+ }
+
+ /**
* @hide
*/
public void setActiveAdmin(ComponentName policyReceiver, boolean refreshing) {
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index e061ab3..3e998fd 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -93,6 +93,19 @@ interface IDevicePolicyManager {
void removeActiveAdmin(in ComponentName policyReceiver, int userHandle);
boolean hasGrantedPolicy(in ComponentName policyReceiver, int usesPolicy, int userHandle);
+ boolean setSELinuxAdmin(in ComponentName who, boolean control, int userHandle);
+ boolean isSELinuxAdmin(in ComponentName who, int userHandle);
+
+ boolean setSELinuxEnforcing(in ComponentName who, boolean enforcing, int userHandle);
+ boolean getSELinuxEnforcing(in ComponentName who, int userHandle);
+
+ List<String> getSELinuxBooleanNames(in ComponentName who, int userHandle);
+ boolean getSELinuxBooleanValue(in ComponentName who, String name, int userHandle);
+ boolean setSELinuxBooleanValue(in ComponentName who, String name, boolean value, int userHandle);
+
+ boolean setCustomPolicyFile(in ComponentName who, int policyType, in byte[] policy, int userHandle);
+ boolean isCustomPolicyFile(in ComponentName who, int policyType, int userHandle);
+
void setActivePasswordState(int quality, int length, int letters, int uppercase, int lowercase,
int numbers, int symbols, int nonletter, int userHandle);
void reportFailedPasswordAttempt(int userHandle);
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index e061032..f67e9b2 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1820,6 +1820,10 @@
<string name="policylab_disableKeyguardFeatures">Disable features in keyguard</string>
<!-- Description of policy access to disable all device cameras [CHAR LIMIT=110]-->
<string name="policydesc_disableKeyguardFeatures">Prevent use of some features in keyguard.</string>
+ <!-- Title of policy access to start enforcing SELinux policy [CHAR LIMIT=30]-->
+ <string name="policylab_enforceSelinux">Enforce SELinux</string>
+ <!-- Description of policy access to start enforcing SELinux policy [CHAR LIMIT=110]-->
+ <string name="policydesc_enforceSelinux">Toggle SELinux policy enforcing or permissive mode.</string>
<!-- The order of these is important, don't reorder without changing Contacts.java --> <skip />
<!-- Phone number types from android.provider.Contacts. This could be used when adding a new phone number for a contact, for example. -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index e9aa1e4..06f9acb 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -863,6 +863,8 @@
<java-symbol type="string" name="media_route_status_available" />
<java-symbol type="string" name="media_route_status_not_available" />
<java-symbol type="string" name="owner_name" />
+ <java-symbol type="string" name="policylab_enforceSelinux" />
+ <java-symbol type="string" name="policydesc_enforceSelinux" />
<java-symbol type="plurals" name="abbrev_in_num_days" />
<java-symbol type="plurals" name="abbrev_in_num_hours" />