Fix getCallingPackage() to handle reentrance.

Keep any previous value in the stack frame and restore when the
current call is finished.

Bug: 10659409
Change-Id: I02b760ae9ca06a4b3602725e02f649f1ada460a0
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index 65a3a07..3438419 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -34,7 +34,6 @@
 import android.os.OperationCanceledException;
 import android.os.ParcelFileDescriptor;
 import android.os.Process;
-import android.os.RemoteException;
 import android.os.UserHandle;
 import android.util.Log;
 
@@ -196,13 +195,13 @@
                 return rejectQuery(uri, projection, selection, selectionArgs, sortOrder,
                         CancellationSignal.fromTransport(cancellationSignal));
             }
-            mCallingPackage.set(callingPkg);
+            final String original = setCallingPackage(callingPkg);
             try {
                 return ContentProvider.this.query(
                         uri, projection, selection, selectionArgs, sortOrder,
                         CancellationSignal.fromTransport(cancellationSignal));
             } finally {
-                mCallingPackage.set(null);
+                setCallingPackage(original);
             }
         }
 
@@ -216,11 +215,11 @@
             if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
                 return rejectInsert(uri, initialValues);
             }
-            mCallingPackage.set(callingPkg);
+            final String original = setCallingPackage(callingPkg);
             try {
                 return ContentProvider.this.insert(uri, initialValues);
             } finally {
-                mCallingPackage.set(null);
+                setCallingPackage(original);
             }
         }
 
@@ -229,11 +228,11 @@
             if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
                 return 0;
             }
-            mCallingPackage.set(callingPkg);
+            final String original = setCallingPackage(callingPkg);
             try {
                 return ContentProvider.this.bulkInsert(uri, initialValues);
             } finally {
-                mCallingPackage.set(null);
+                setCallingPackage(original);
             }
         }
 
@@ -256,11 +255,11 @@
                     }
                 }
             }
-            mCallingPackage.set(callingPkg);
+            final String original = setCallingPackage(callingPkg);
             try {
                 return ContentProvider.this.applyBatch(operations);
             } finally {
-                mCallingPackage.set(null);
+                setCallingPackage(original);
             }
         }
 
@@ -269,11 +268,11 @@
             if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
                 return 0;
             }
-            mCallingPackage.set(callingPkg);
+            final String original = setCallingPackage(callingPkg);
             try {
                 return ContentProvider.this.delete(uri, selection, selectionArgs);
             } finally {
-                mCallingPackage.set(null);
+                setCallingPackage(original);
             }
         }
 
@@ -283,11 +282,11 @@
             if (enforceWritePermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
                 return 0;
             }
-            mCallingPackage.set(callingPkg);
+            final String original = setCallingPackage(callingPkg);
             try {
                 return ContentProvider.this.update(uri, values, selection, selectionArgs);
             } finally {
-                mCallingPackage.set(null);
+                setCallingPackage(original);
             }
         }
 
@@ -296,12 +295,12 @@
                 String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal)
                 throws FileNotFoundException {
             enforceFilePermission(callingPkg, uri, mode);
-            mCallingPackage.set(callingPkg);
+            final String original = setCallingPackage(callingPkg);
             try {
                 return ContentProvider.this.openFile(
                         uri, mode, CancellationSignal.fromTransport(cancellationSignal));
             } finally {
-                mCallingPackage.set(null);
+                setCallingPackage(original);
             }
         }
 
@@ -310,22 +309,22 @@
                 String callingPkg, Uri uri, String mode, ICancellationSignal cancellationSignal)
                 throws FileNotFoundException {
             enforceFilePermission(callingPkg, uri, mode);
-            mCallingPackage.set(callingPkg);
+            final String original = setCallingPackage(callingPkg);
             try {
                 return ContentProvider.this.openAssetFile(
                         uri, mode, CancellationSignal.fromTransport(cancellationSignal));
             } finally {
-                mCallingPackage.set(null);
+                setCallingPackage(original);
             }
         }
 
         @Override
         public Bundle call(String callingPkg, String method, String arg, Bundle extras) {
-            mCallingPackage.set(callingPkg);
+            final String original = setCallingPackage(callingPkg);
             try {
                 return ContentProvider.this.call(method, arg, extras);
             } finally {
-                mCallingPackage.set(null);
+                setCallingPackage(original);
             }
         }
 
@@ -338,12 +337,12 @@
         public AssetFileDescriptor openTypedAssetFile(String callingPkg, Uri uri, String mimeType,
                 Bundle opts, ICancellationSignal cancellationSignal) throws FileNotFoundException {
             enforceFilePermission(callingPkg, uri, "r");
-            mCallingPackage.set(callingPkg);
+            final String original = setCallingPackage(callingPkg);
             try {
                 return ContentProvider.this.openTypedAssetFile(
                         uri, mimeType, opts, CancellationSignal.fromTransport(cancellationSignal));
             } finally {
-                mCallingPackage.set(null);
+                setCallingPackage(original);
             }
         }
 
@@ -357,11 +356,11 @@
             if (enforceReadPermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
                 return null;
             }
-            mCallingPackage.set(callingPkg);
+            final String original = setCallingPackage(callingPkg);
             try {
                 return ContentProvider.this.canonicalize(uri);
             } finally {
-                mCallingPackage.set(null);
+                setCallingPackage(original);
             }
         }
 
@@ -370,11 +369,11 @@
             if (enforceReadPermission(callingPkg, uri) != AppOpsManager.MODE_ALLOWED) {
                 return null;
             }
-            mCallingPackage.set(callingPkg);
+            final String original = setCallingPackage(callingPkg);
             try {
                 return ContentProvider.this.uncanonicalize(uri);
             } finally {
-                mCallingPackage.set(null);
+                setCallingPackage(original);
             }
         }
 
@@ -540,6 +539,16 @@
     }
 
     /**
+     * Set the calling package, returning the current value (or {@code null})
+     * which can be used later to restore the previous state.
+     */
+    private String setCallingPackage(String callingPackage) {
+        final String original = mCallingPackage.get();
+        mCallingPackage.set(callingPackage);
+        return original;
+    }
+
+    /**
      * Return the package name of the caller that initiated the request being
      * processed on the current thread. The returned package will have been
      * verified to belong to the calling UID. Returns {@code null} if not