summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/os/Process.java10
-rw-r--r--core/java/com/android/internal/os/ZygoteConnection.java115
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java2
3 files changed, 116 insertions, 11 deletions
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index e1bc275..50567b2 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -274,6 +274,7 @@ public class Process {
* @param gids Additional group-ids associated with the process.
* @param debugFlags Additional flags.
* @param targetSdkVersion The target SDK version for the app.
+ * @param seInfo null-ok SE Android information for the new process.
* @param zygoteArgs Additional arguments to supply to the zygote process.
*
* @return An object that describes the result of the attempt to start the process.
@@ -285,10 +286,11 @@ public class Process {
final String niceName,
int uid, int gid, int[] gids,
int debugFlags, int targetSdkVersion,
+ String seInfo,
String[] zygoteArgs) {
try {
return startViaZygote(processClass, niceName, uid, gid, gids,
- debugFlags, targetSdkVersion, zygoteArgs);
+ debugFlags, targetSdkVersion, seInfo, zygoteArgs);
} catch (ZygoteStartFailedEx ex) {
Log.e(LOG_TAG,
"Starting VM process through Zygote failed");
@@ -451,6 +453,7 @@ public class Process {
* new process should setgroup() to.
* @param debugFlags Additional flags.
* @param targetSdkVersion The target SDK version for the app.
+ * @param seInfo null-ok SE Android information for the new process.
* @param extraArgs Additional arguments to supply to the zygote process.
* @return An object that describes the result of the attempt to start the process.
* @throws ZygoteStartFailedEx if process start failed for any reason
@@ -460,6 +463,7 @@ public class Process {
final int uid, final int gid,
final int[] gids,
int debugFlags, int targetSdkVersion,
+ String seInfo,
String[] extraArgs)
throws ZygoteStartFailedEx {
synchronized(Process.class) {
@@ -510,6 +514,10 @@ public class Process {
argsForZygote.add("--nice-name=" + niceName);
}
+ if (seInfo != null) {
+ argsForZygote.add("--seinfo=" + seInfo);
+ }
+
argsForZygote.add(processClass);
if (extraArgs != null) {
diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java
index 9af7e96..b016e99 100644
--- a/core/java/com/android/internal/os/ZygoteConnection.java
+++ b/core/java/com/android/internal/os/ZygoteConnection.java
@@ -26,6 +26,8 @@ import android.util.Log;
import dalvik.system.PathClassLoader;
import dalvik.system.Zygote;
+import android.os.SELinux;
+
import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
@@ -73,6 +75,7 @@ class ZygoteConnection {
private final DataOutputStream mSocketOutStream;
private final BufferedReader mSocketReader;
private final Credentials peer;
+ private final String peerSecurityContext;
/**
* A long-lived reference to the original command socket used to launch
@@ -109,6 +112,8 @@ class ZygoteConnection {
Log.e(TAG, "Cannot read peer credentials", ex);
throw ex;
}
+
+ peerSecurityContext = SELinux.getPeerContext(mSocket.getFileDescriptor());
}
/**
@@ -207,10 +212,11 @@ class ZygoteConnection {
try {
parsedArgs = new Arguments(args);
- applyUidSecurityPolicy(parsedArgs, peer);
- applyRlimitSecurityPolicy(parsedArgs, peer);
- applyCapabilitiesSecurityPolicy(parsedArgs, peer);
- applyInvokeWithSecurityPolicy(parsedArgs, peer);
+ applyUidSecurityPolicy(parsedArgs, peer, peerSecurityContext);
+ applyRlimitSecurityPolicy(parsedArgs, peer, peerSecurityContext);
+ applyCapabilitiesSecurityPolicy(parsedArgs, peer, peerSecurityContext);
+ applyInvokeWithSecurityPolicy(parsedArgs, peer, peerSecurityContext);
+ applyseInfoSecurityPolicy(parsedArgs, peer, peerSecurityContext);
applyDebuggerSystemProperty(parsedArgs);
applyInvokeWithSystemProperty(parsedArgs);
@@ -229,7 +235,8 @@ class ZygoteConnection {
}
pid = Zygote.forkAndSpecialize(parsedArgs.uid, parsedArgs.gid,
- parsedArgs.gids, parsedArgs.debugFlags, rlimits);
+ parsedArgs.gids, parsedArgs.debugFlags, rlimits,
+ parsedArgs.seInfo, parsedArgs.niceName);
} catch (IOException ex) {
logAndPrintError(newStderr, "Exception creating pipe", ex);
} catch (ErrnoException ex) {
@@ -352,6 +359,10 @@ class ZygoteConnection {
long permittedCapabilities;
long effectiveCapabilities;
+ /** from --seinfo */
+ boolean seInfoSpecified;
+ String seInfo;
+
/** from all --rlimit=r,c,m */
ArrayList<int[]> rlimits;
@@ -429,6 +440,13 @@ class ZygoteConnection {
peerWait = true;
} else if (arg.equals("--runtime-init")) {
runtimeInit = true;
+ } else if (arg.startsWith("--seinfo=")) {
+ if (seInfoSpecified) {
+ throw new IllegalArgumentException(
+ "Duplicate arg specified");
+ }
+ seInfoSpecified = true;
+ seInfo = arg.substring(arg.indexOf('=') + 1);
} else if (arg.startsWith("--capabilities=")) {
if (capabilitiesSpecified) {
throw new IllegalArgumentException(
@@ -591,7 +609,8 @@ class ZygoteConnection {
* @param peer non-null; peer credentials
* @throws ZygoteSecurityException
*/
- private static void applyUidSecurityPolicy(Arguments args, Credentials peer)
+ private static void applyUidSecurityPolicy(Arguments args, Credentials peer,
+ String peerSecurityContext)
throws ZygoteSecurityException {
int peerUid = peer.getUid();
@@ -624,6 +643,17 @@ class ZygoteConnection {
}
}
+ if (args.uidSpecified || args.gidSpecified || args.gids != null) {
+ boolean allowed = SELinux.checkSELinuxAccess(peerSecurityContext,
+ peerSecurityContext,
+ "zygote",
+ "specifyids");
+ if (!allowed) {
+ throw new ZygoteSecurityException(
+ "Peer may not specify uid's or gid's");
+ }
+ }
+
// If not otherwise specified, uid and gid are inherited from peer
if (!args.uidSpecified) {
args.uid = peer.getUid();
@@ -664,7 +694,7 @@ class ZygoteConnection {
* @throws ZygoteSecurityException
*/
private static void applyRlimitSecurityPolicy(
- Arguments args, Credentials peer)
+ Arguments args, Credentials peer, String peerSecurityContext)
throws ZygoteSecurityException {
int peerUid = peer.getUid();
@@ -676,6 +706,17 @@ class ZygoteConnection {
"This UID may not specify rlimits.");
}
}
+
+ if (args.rlimits != null) {
+ boolean allowed = SELinux.checkSELinuxAccess(peerSecurityContext,
+ peerSecurityContext,
+ "zygote",
+ "specifyrlimits");
+ if (!allowed) {
+ throw new ZygoteSecurityException(
+ "Peer may not specify rlimits");
+ }
+ }
}
/**
@@ -689,7 +730,7 @@ class ZygoteConnection {
* @throws ZygoteSecurityException
*/
private static void applyCapabilitiesSecurityPolicy(
- Arguments args, Credentials peer)
+ Arguments args, Credentials peer, String peerSecurityContext)
throws ZygoteSecurityException {
if (args.permittedCapabilities == 0
@@ -698,6 +739,15 @@ class ZygoteConnection {
return;
}
+ boolean allowed = SELinux.checkSELinuxAccess(peerSecurityContext,
+ peerSecurityContext,
+ "zygote",
+ "specifycapabilities");
+ if (!allowed) {
+ throw new ZygoteSecurityException(
+ "Peer may not specify capabilities");
+ }
+
if (peer.getUid() == 0) {
// root may specify anything
return;
@@ -747,7 +797,8 @@ class ZygoteConnection {
* @param peer non-null; peer credentials
* @throws ZygoteSecurityException
*/
- private static void applyInvokeWithSecurityPolicy(Arguments args, Credentials peer)
+ private static void applyInvokeWithSecurityPolicy(Arguments args, Credentials peer,
+ String peerSecurityContext)
throws ZygoteSecurityException {
int peerUid = peer.getUid();
@@ -755,6 +806,52 @@ class ZygoteConnection {
throw new ZygoteSecurityException("Peer is not permitted to specify "
+ "an explicit invoke-with wrapper command");
}
+
+ if (args.invokeWith != null) {
+ boolean allowed = SELinux.checkSELinuxAccess(peerSecurityContext,
+ peerSecurityContext,
+ "zygote",
+ "specifyinvokewith");
+ if (!allowed) {
+ throw new ZygoteSecurityException("Peer is not permitted to specify "
+ + "an explicit invoke-with wrapper command");
+ }
+ }
+ }
+
+ /**
+ * Applies zygote security policy for SEAndroid information.
+ *
+ * @param args non-null; zygote spawner arguments
+ * @param peer non-null; peer credentials
+ * @throws ZygoteSecurityException
+ */
+ private static void applyseInfoSecurityPolicy(
+ Arguments args, Credentials peer, String peerSecurityContext)
+ throws ZygoteSecurityException {
+ int peerUid = peer.getUid();
+
+ if (args.seInfo == null) {
+ // nothing to check
+ return;
+ }
+
+ if (!(peerUid == 0 || peerUid == Process.SYSTEM_UID)) {
+ // All peers with UID other than root or SYSTEM_UID
+ throw new ZygoteSecurityException(
+ "This UID may not specify SEAndroid info.");
+ }
+
+ boolean allowed = SELinux.checkSELinuxAccess(peerSecurityContext,
+ peerSecurityContext,
+ "zygote",
+ "specifyseinfo");
+ if (!allowed) {
+ throw new ZygoteSecurityException(
+ "Peer may not specify SEAndroid info");
+ }
+
+ return;
}
/**
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 6190a63..0a4d19f 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1967,7 +1967,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// the PID of the new process, or else throw a RuntimeException.
Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread",
app.processName, uid, uid, gids, debugFlags,
- app.info.targetSdkVersion, null);
+ app.info.targetSdkVersion, null, null);
BatteryStatsImpl bs = app.batteryStats.getBatteryStats();
synchronized (bs) {