DivestOS/Patches/LineageOS-21.0/android_frameworks_base/0013-Special_Permissions-6.patch
Tavi 07951955d3
21.0: more work
Signed-off-by: Tavi <tavi@divested.dev>
2024-05-20 18:13:59 -04:00

166 lines
7.3 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Dmitry Muhomor <muhomor.dmitry@gmail.com>
Date: Sun, 31 Jul 2022 18:00:35 +0300
Subject: [PATCH] improve compatibility of INTERNET special runtime permission
There are apps that refuse to work when they detect that INTERNET is revoked, usually because of
a library check that reminds the app developer to add INTERNET uses-permission element to app's
AndroidManifest.
Always report that INTERNET is granted unless the app has
<meta-data android:name="android.permission.INTERNET.mode" android:value="runtime" />
declaration inside <application> element in its AndroidManifest, or is a system app.
---
core/api/system-current.txt | 5 +++++
core/java/android/app/DownloadManager.java | 13 ++++++++++++
.../content/pm/AppPermissionUtils.java | 7 +++++++
.../pm/SpecialRuntimePermAppUtils.java | 20 +++++++++++++++++++
.../permission/SpecialRuntimePermUtils.java | 17 ++++++++++++++++
5 files changed, 62 insertions(+)
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 38e4b74acc38..d7461cbb5be3 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -4176,6 +4176,11 @@ package android.content.pm {
}
public class SpecialRuntimePermAppUtils {
+ method public static boolean awareOfRuntimeInternetPermission();
+ method public static boolean isInternetCompatEnabled();
+ method public static boolean requestsInternetPermission();
+ field public static final int FLAG_AWARE_OF_RUNTIME_INTERNET_PERMISSION = 4; // 0x4
+ field public static final int FLAG_REQUESTS_INTERNET_PERMISSION = 2; // 0x2
}
public final class SuspendDialogInfo implements android.os.Parcelable {
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index de0244f3934f..6285f4745c37 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -34,6 +34,7 @@ import android.content.Context;
import android.database.Cursor;
import android.database.CursorWrapper;
import android.database.DatabaseUtils;
+import android.database.MatrixCursor;
import android.net.ConnectivityManager;
import android.net.NetworkPolicyManager;
import android.net.Uri;
@@ -53,6 +54,8 @@ import android.util.LongSparseArray;
import android.util.Pair;
import android.webkit.MimeTypeMap;
+import android.content.pm.SpecialRuntimePermAppUtils;
+
import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
@@ -1124,6 +1127,11 @@ public class DownloadManager {
* future calls related to this download. Returns -1 if the operation fails.
*/
public long enqueue(Request request) {
+ if (SpecialRuntimePermAppUtils.isInternetCompatEnabled()) {
+ // invalid id (DownloadProvider uses SQLite and returns a row id)
+ return -1;
+ }
+
ContentValues values = request.toContentValues(mPackageName);
Uri downloadUri = mResolver.insert(Downloads.Impl.CONTENT_URI, values);
if (downloadUri == null) {
@@ -1176,6 +1184,11 @@ public class DownloadManager {
/** @hide */
public Cursor query(Query query, String[] projection) {
+ if (SpecialRuntimePermAppUtils.isInternetCompatEnabled()) {
+ // underlying provider is protected by the INTERNET permission
+ return new MatrixCursor(projection);
+ }
+
Cursor underlyingCursor = query.runQuery(mResolver, projection, mBaseUri);
if (underlyingCursor == null) {
return null;
diff --git a/core/java/android/content/pm/AppPermissionUtils.java b/core/java/android/content/pm/AppPermissionUtils.java
index 7dc20eec8485..6a96f70dcfcf 100644
--- a/core/java/android/content/pm/AppPermissionUtils.java
+++ b/core/java/android/content/pm/AppPermissionUtils.java
@@ -24,6 +24,13 @@ public class AppPermissionUtils {
// android.app.ApplicationPackageManager#checkPermission(String permName, String pkgName)
// android.app.ContextImpl#checkPermission(String permission, int pid, int uid)
public static boolean shouldSpoofSelfCheck(String permName) {
+ if (Manifest.permission.INTERNET.equals(permName)
+ && SpecialRuntimePermAppUtils.requestsInternetPermission()
+ && !SpecialRuntimePermAppUtils.awareOfRuntimeInternetPermission())
+ {
+ return true;
+ }
+
return false;
}
}
diff --git a/core/java/android/content/pm/SpecialRuntimePermAppUtils.java b/core/java/android/content/pm/SpecialRuntimePermAppUtils.java
index efd48cb49aa3..2f973a585d5c 100644
--- a/core/java/android/content/pm/SpecialRuntimePermAppUtils.java
+++ b/core/java/android/content/pm/SpecialRuntimePermAppUtils.java
@@ -28,9 +28,29 @@ import android.permission.PermissionManager;
@SystemApi
public class SpecialRuntimePermAppUtils {
private static final int FLAG_INITED = 1;
+ public static final int FLAG_REQUESTS_INTERNET_PERMISSION = 1 << 1;
+ public static final int FLAG_AWARE_OF_RUNTIME_INTERNET_PERMISSION = 1 << 2;
private static volatile int cachedFlags;
+ private static boolean hasInternetPermission() {
+ // checkSelfPermission() is spoofed, query the underlying API directly
+ return PermissionManager.checkPermission(Manifest.permission.INTERNET, Process.myPid(), Process.myUid())
+ == PackageManager.PERMISSION_GRANTED;
+ }
+
+ public static boolean requestsInternetPermission() {
+ return (getFlags() & FLAG_REQUESTS_INTERNET_PERMISSION) != 0;
+ }
+
+ public static boolean awareOfRuntimeInternetPermission() {
+ return (getFlags() & FLAG_AWARE_OF_RUNTIME_INTERNET_PERMISSION) != 0;
+ }
+
+ public static boolean isInternetCompatEnabled() {
+ return !hasInternetPermission() && requestsInternetPermission() && !awareOfRuntimeInternetPermission();
+ }
+
private static int getFlags() {
int cache = cachedFlags;
if (cache != 0) {
diff --git a/services/core/java/com/android/server/pm/permission/SpecialRuntimePermUtils.java b/services/core/java/com/android/server/pm/permission/SpecialRuntimePermUtils.java
index fe946ff5d5ca..6f5cabb8a8fc 100644
--- a/services/core/java/com/android/server/pm/permission/SpecialRuntimePermUtils.java
+++ b/services/core/java/com/android/server/pm/permission/SpecialRuntimePermUtils.java
@@ -34,11 +34,28 @@ public class SpecialRuntimePermUtils {
for (ParsedUsesPermission perm : pkg.getUsesPermissions()) {
String name = perm.getName();
switch (name) {
+ case Manifest.permission.INTERNET:
+ flags |= FLAG_REQUESTS_INTERNET_PERMISSION;
+ continue;
default:
continue;
}
}
+ if ((flags & FLAG_REQUESTS_INTERNET_PERMISSION) != 0) {
+ if (pkg.isSystem()) {
+ flags |= FLAG_AWARE_OF_RUNTIME_INTERNET_PERMISSION;
+ } else {
+ Bundle metadata = pkg.getMetaData();
+ if (metadata != null) {
+ String key = Manifest.permission.INTERNET + ".mode";
+ if ("runtime".equals(metadata.getString(key))) {
+ flags |= FLAG_AWARE_OF_RUNTIME_INTERNET_PERMISSION;
+ }
+ }
+ }
+ }
+
return flags;
}