summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/hardware/fingerprint/FingerprintManager.java21
-rw-r--r--core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.aidl2
-rw-r--r--core/java/android/os/Process.java21
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java4
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java9
-rw-r--r--services/core/java/com/android/server/LockSettingsService.java6
-rwxr-xr-xservices/core/java/com/android/server/am/ActivityManagerService.java21
-rw-r--r--services/core/java/com/android/server/am/BroadcastQueue.java5
-rw-r--r--services/core/java/com/android/server/fingerprint/FingerprintService.java25
-rw-r--r--services/core/java/com/android/server/location/GpsXtraDownloader.java21
10 files changed, 103 insertions, 32 deletions
diff --git a/core/java/android/hardware/fingerprint/FingerprintManager.java b/core/java/android/hardware/fingerprint/FingerprintManager.java
index 122df23..62396a3 100644
--- a/core/java/android/hardware/fingerprint/FingerprintManager.java
+++ b/core/java/android/hardware/fingerprint/FingerprintManager.java
@@ -258,6 +258,7 @@ public class FingerprintManager {
public static class AuthenticationResult {
private Fingerprint mFingerprint;
private CryptoObject mCryptoObject;
+ private int mUserId;
/**
* Authentication result
@@ -266,9 +267,10 @@ public class FingerprintManager {
* @param fingerprint the recognized fingerprint data, if allowed.
* @hide
*/
- public AuthenticationResult(CryptoObject crypto, Fingerprint fingerprint) {
+ public AuthenticationResult(CryptoObject crypto, Fingerprint fingerprint, int userId) {
mCryptoObject = crypto;
mFingerprint = fingerprint;
+ mUserId = userId;
}
/**
@@ -285,6 +287,12 @@ public class FingerprintManager {
* @hide
*/
public Fingerprint getFingerprint() { return mFingerprint; }
+
+ /**
+ * Obtain the userId for which this fingerprint was authenticated.
+ * @hide
+ */
+ public int getUserId() { return mUserId; }
};
/**
@@ -754,7 +762,7 @@ public class FingerprintManager {
sendAcquiredResult((Long) msg.obj /* deviceId */, msg.arg1 /* acquire info */);
break;
case MSG_AUTHENTICATION_SUCCEEDED:
- sendAuthenticatedSucceeded((Fingerprint) msg.obj);
+ sendAuthenticatedSucceeded((Fingerprint) msg.obj, msg.arg1 /* userId */);
break;
case MSG_AUTHENTICATION_FAILED:
sendAuthenticatedFailed();
@@ -799,9 +807,10 @@ public class FingerprintManager {
}
}
- private void sendAuthenticatedSucceeded(Fingerprint fp) {
+ private void sendAuthenticatedSucceeded(Fingerprint fp, int userId) {
if (mAuthenticationCallback != null) {
- final AuthenticationResult result = new AuthenticationResult(mCryptoObject, fp);
+ final AuthenticationResult result =
+ new AuthenticationResult(mCryptoObject, fp, userId);
mAuthenticationCallback.onAuthenticationSucceeded(result);
}
}
@@ -941,8 +950,8 @@ public class FingerprintManager {
}
@Override // binder call
- public void onAuthenticationSucceeded(long deviceId, Fingerprint fp) {
- mHandler.obtainMessage(MSG_AUTHENTICATION_SUCCEEDED, fp).sendToTarget();
+ public void onAuthenticationSucceeded(long deviceId, Fingerprint fp, int userId) {
+ mHandler.obtainMessage(MSG_AUTHENTICATION_SUCCEEDED, userId, 0, fp).sendToTarget();
}
@Override // binder call
diff --git a/core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.aidl b/core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.aidl
index 57a429f..b024b29 100644
--- a/core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.aidl
+++ b/core/java/android/hardware/fingerprint/IFingerprintServiceReceiver.aidl
@@ -26,7 +26,7 @@ import android.os.UserHandle;
oneway interface IFingerprintServiceReceiver {
void onEnrollResult(long deviceId, int fingerId, int groupId, int remaining);
void onAcquired(long deviceId, int acquiredInfo);
- void onAuthenticationSucceeded(long deviceId, in Fingerprint fp);
+ void onAuthenticationSucceeded(long deviceId, in Fingerprint fp, int userId);
void onAuthenticationFailed(long deviceId);
void onError(long deviceId, int error);
void onRemoved(long deviceId, int fingerId, int groupId);
diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java
index 65b09eb..02466cc 100644
--- a/core/java/android/os/Process.java
+++ b/core/java/android/os/Process.java
@@ -539,6 +539,15 @@ public class Process {
ZygoteState zygoteState, ArrayList<String> args)
throws ZygoteStartFailedEx {
try {
+ // Throw early if any of the arguments are malformed. This means we can
+ // avoid writing a partial response to the zygote.
+ int sz = args.size();
+ for (int i = 0; i < sz; i++) {
+ if (args.get(i).indexOf('\n') >= 0) {
+ throw new ZygoteStartFailedEx("embedded newlines not allowed");
+ }
+ }
+
/**
* See com.android.internal.os.ZygoteInit.readArgumentList()
* Presently the wire format to the zygote process is:
@@ -555,13 +564,8 @@ public class Process {
writer.write(Integer.toString(args.size()));
writer.newLine();
- int sz = args.size();
for (int i = 0; i < sz; i++) {
String arg = args.get(i);
- if (arg.indexOf('\n') >= 0) {
- throw new ZygoteStartFailedEx(
- "embedded newlines not allowed");
- }
writer.write(arg);
writer.newLine();
}
@@ -570,11 +574,16 @@ public class Process {
// Should there be a timeout on this?
ProcessStartResult result = new ProcessStartResult();
+
+ // Always read the entire result from the input stream to avoid leaving
+ // bytes in the stream for future process starts to accidentally stumble
+ // upon.
result.pid = inputStream.readInt();
+ result.usingWrapper = inputStream.readBoolean();
+
if (result.pid < 0) {
throw new ZygoteStartFailedEx("fork() failed");
}
- result.usingWrapper = inputStream.readBoolean();
return result;
} catch (IOException ex) {
zygoteState.close();
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index dc2cf1e..5dc91d2 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -301,7 +301,7 @@ public class LockPatternUtils {
return false;
}
} catch (RemoteException re) {
- return true;
+ return false;
}
}
@@ -350,7 +350,7 @@ public class LockPatternUtils {
return false;
}
} catch (RemoteException re) {
- return true;
+ return false;
}
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
index f608f13..70a9f5c 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -462,7 +462,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
}
}
- private void handleFingerprintAuthenticated() {
+
+ private void handleFingerprintAuthenticated(int authUserId) {
try {
final int userId;
try {
@@ -471,6 +472,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
Log.e(TAG, "Failed to get current user id: ", e);
return;
}
+ if (userId != authUserId) {
+ Log.d(TAG, "Fingerprint authenticated for wrong user: " + authUserId);
+ return;
+ }
if (isFingerprintDisabled(userId)) {
Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
return;
@@ -737,7 +742,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
@Override
public void onAuthenticationSucceeded(AuthenticationResult result) {
- handleFingerprintAuthenticated();
+ handleFingerprintAuthenticated(result.getUserId());
}
@Override
diff --git a/services/core/java/com/android/server/LockSettingsService.java b/services/core/java/com/android/server/LockSettingsService.java
index 317e5a0..10b0bdd 100644
--- a/services/core/java/com/android/server/LockSettingsService.java
+++ b/services/core/java/com/android/server/LockSettingsService.java
@@ -565,6 +565,9 @@ public class LockSettingsService extends ILockSettings.Stub {
private VerifyCredentialResponse doVerifyPattern(String pattern, boolean hasChallenge,
long challenge, int userId) throws RemoteException {
checkPasswordReadPermission(userId);
+ if (TextUtils.isEmpty(pattern)) {
+ throw new IllegalArgumentException("Pattern can't be null or empty");
+ }
CredentialHash storedHash = mStorage.readPatternHash(userId);
boolean shouldReEnrollBaseZero = storedHash != null && storedHash.isBaseZeroPattern;
@@ -628,6 +631,9 @@ public class LockSettingsService extends ILockSettings.Stub {
private VerifyCredentialResponse doVerifyPassword(String password, boolean hasChallenge,
long challenge, int userId) throws RemoteException {
checkPasswordReadPermission(userId);
+ if (TextUtils.isEmpty(password)) {
+ throw new IllegalArgumentException("Password can't be null or empty");
+ }
CredentialHash storedHash = mStorage.readPasswordHash(userId);
return verifyCredential(userId, storedHash, password, hasChallenge, challenge,
new CredentialUtil() {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index d6480f3..3ae82a8 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -3651,6 +3651,15 @@ public final class ActivityManagerService extends ActivityManagerNative
app.killedByAm = false;
checkTime(startTime, "startProcess: starting to update pids map");
synchronized (mPidsSelfLocked) {
+ ProcessRecord oldApp;
+ // If there is already an app occupying that pid that hasn't been cleaned up
+ if ((oldApp = mPidsSelfLocked.get(startResult.pid)) != null && !app.isolated) {
+ // Clean up anything relating to this pid first
+ Slog.w(TAG, "Reusing pid " + startResult.pid
+ + " while app is still mapped to it");
+ cleanUpApplicationRecordLocked(oldApp, false, false, -1,
+ true /*replacingPid*/);
+ }
this.mPidsSelfLocked.put(startResult.pid, app);
if (isActivityProcess) {
Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
@@ -4804,7 +4813,8 @@ public final class ActivityManagerService extends ActivityManagerNative
private final void handleAppDiedLocked(ProcessRecord app,
boolean restarting, boolean allowRestart) {
int pid = app.pid;
- boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
+ boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
+ false /*replacingPid*/);
if (!kept && !restarting) {
removeLruProcessLocked(app);
if (pid > 0) {
@@ -15903,7 +15913,8 @@ public final class ActivityManagerService extends ActivityManagerNative
* app that was passed in must remain on the process lists.
*/
private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
- boolean restarting, boolean allowRestart, int index) {
+ boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
+ Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
if (index >= 0) {
removeLruProcessLocked(app);
ProcessList.remove(app.pid);
@@ -16033,7 +16044,9 @@ public final class ActivityManagerService extends ActivityManagerNative
if (!app.persistent || app.isolated) {
if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
"Removing non-persistent process during cleanup: " + app);
- removeProcessNameLocked(app.processName, app.uid);
+ if (!replacingPid) {
+ removeProcessNameLocked(app.processName, app.uid);
+ }
if (mHeavyWeightProcess == app) {
mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
mHeavyWeightProcess.userId, 0));
@@ -20001,7 +20014,7 @@ public final class ActivityManagerService extends ActivityManagerNative
// Ignore exceptions.
}
}
- cleanUpApplicationRecordLocked(app, false, true, -1);
+ cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
mRemovedProcesses.remove(i);
if (app.persistent) {
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index 589a4b8..e7fec19 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -297,6 +297,11 @@ public final class BroadcastQueue {
boolean didSomething = false;
final BroadcastRecord br = mPendingBroadcast;
if (br != null && br.curApp.pid == app.pid) {
+ if (br.curApp != app) {
+ Slog.e(TAG, "App mismatch when sending pending broadcast to "
+ + app.processName + ", intended target is " + br.curApp.processName);
+ return false;
+ }
try {
mPendingBroadcast = null;
processCurBroadcastLocked(br, app);
diff --git a/services/core/java/com/android/server/fingerprint/FingerprintService.java b/services/core/java/com/android/server/fingerprint/FingerprintService.java
index 429a31f..e5ab37f 100644
--- a/services/core/java/com/android/server/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/fingerprint/FingerprintService.java
@@ -127,6 +127,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
private IFingerprintDaemon mDaemon;
private final PowerManager mPowerManager;
private final AlarmManager mAlarmManager;
+ private int mCurrentUserId = UserHandle.USER_NULL;
private final BroadcastReceiver mLockoutReceiver = new BroadcastReceiver() {
@Override
@@ -340,7 +341,8 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
return;
}
stopPendingOperations(true);
- mEnrollClient = new ClientMonitor(token, receiver, groupId, restricted, token.toString());
+ mEnrollClient = new ClientMonitor(token, receiver, mCurrentUserId, groupId, restricted,
+ token.toString());
final int timeout = (int) (ENROLLMENT_TIMEOUT_MS / MS_PER_SEC);
try {
final int result = daemon.enroll(cryptoToken, groupId, timeout);
@@ -428,7 +430,8 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
return;
}
stopPendingOperations(true);
- mAuthClient = new ClientMonitor(token, receiver, groupId, restricted, opPackageName);
+ mAuthClient = new ClientMonitor(token, receiver, mCurrentUserId, groupId, restricted,
+ opPackageName);
if (inLockoutMode()) {
Slog.v(TAG, "In lockout mode; disallowing authentication");
if (!mAuthClient.sendError(FingerprintManager.FINGERPRINT_ERROR_LOCKOUT)) {
@@ -485,7 +488,8 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
}
stopPendingOperations(true);
- mRemoveClient = new ClientMonitor(token, receiver, userId, restricted, token.toString());
+ mRemoveClient = new ClientMonitor(token, receiver, mCurrentUserId, userId, restricted,
+ token.toString());
// The fingerprint template ids will be removed when we get confirmation from the HAL
try {
final int result = daemon.remove(fingerId, userId);
@@ -623,15 +627,17 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
private class ClientMonitor implements IBinder.DeathRecipient {
IBinder token;
IFingerprintServiceReceiver receiver;
- int userId;
+ int userId; // userId of the caller
+ int currentUserId; // current user id when this was created
boolean restricted; // True if client does not have MANAGE_FINGERPRINT permission
String owner;
- public ClientMonitor(IBinder token, IFingerprintServiceReceiver receiver, int userId,
- boolean restricted, String owner) {
+ public ClientMonitor(IBinder token, IFingerprintServiceReceiver receiver,
+ int currentUserId, int userId, boolean restricted, String owner) {
this.token = token;
this.receiver = receiver;
this.userId = userId;
+ this.currentUserId = currentUserId;
this.restricted = restricted;
this.owner = owner; // name of the client that owns this - for debugging
try {
@@ -720,9 +726,9 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
Slog.v(TAG, "onAuthenticated(owner=" + mAuthClient.owner
+ ", id=" + fpId + ", gp=" + groupId + ")");
}
- Fingerprint fp = !restricted ?
- new Fingerprint("" /* TODO */, groupId, fpId, mHalDeviceId) : null;
- receiver.onAuthenticationSucceeded(mHalDeviceId, fp);
+ Fingerprint fp = !restricted ? new Fingerprint("" /* TODO */, groupId, fpId,
+ mHalDeviceId) : null;
+ receiver.onAuthenticationSucceeded(mHalDeviceId, fp, currentUserId);
}
} catch (RemoteException e) {
Slog.w(TAG, "Failed to notify Authenticated:", e);
@@ -1147,6 +1153,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
Slog.e(TAG, "Failed to setActiveGroup():", e);
}
}
+ mCurrentUserId = userId;
}
private void listenForUserSwitches() {
diff --git a/services/core/java/com/android/server/location/GpsXtraDownloader.java b/services/core/java/com/android/server/location/GpsXtraDownloader.java
index 3585049..6310361 100644
--- a/services/core/java/com/android/server/location/GpsXtraDownloader.java
+++ b/services/core/java/com/android/server/location/GpsXtraDownloader.java
@@ -21,8 +21,11 @@ import android.util.Log;
import java.net.HttpURLConnection;
import java.net.URL;
-import libcore.io.Streams;
+import libcore.io.IoUtils;
+
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.Random;
@@ -36,6 +39,7 @@ public class GpsXtraDownloader {
private static final String TAG = "GpsXtraDownloader";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+ private static final long MAXIMUM_CONTENT_LENGTH_BYTES = 1000000; // 1MB.
private static final String DEFAULT_USER_AGENT = "Android";
private final String[] mXtraServers;
@@ -121,7 +125,19 @@ public class GpsXtraDownloader {
return null;
}
- return Streams.readFully(connection.getInputStream());
+ try (InputStream in = connection.getInputStream()) {
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+ byte[] buffer = new byte[1024];
+ int count;
+ while ((count = in.read(buffer)) != -1) {
+ bytes.write(buffer, 0, count);
+ if (bytes.size() > MAXIMUM_CONTENT_LENGTH_BYTES) {
+ if (DEBUG) Log.d(TAG, "XTRA file too large");
+ return null;
+ }
+ }
+ return bytes.toByteArray();
+ }
} catch (IOException ioe) {
if (DEBUG) Log.d(TAG, "Error downloading gps XTRA: ", ioe);
} finally {
@@ -133,3 +149,4 @@ public class GpsXtraDownloader {
}
}
+