Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a57db58f authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

Surface "neverForLocation" through public API.

Since developers can declare the "neverForLocation" flag in their
manifest as public API, we should also offer a way to inspect the
value that we parsed from the manifest.  We do this by surfacing it
through the existing PackageInfo.requestedPermissionsFlags field.

This also means we can remove the PackageManagerInternal API, since
interested parties can now check PackageInfo directly.

Fix a potential security issue by only accepting flags from manifest
when the application is targeting a modern enough SDK.

Bug: 181812281
Test: atest CtsContentTestCases:PackageManagerTest
Test: atest FrameworksServicesTests:PackageParserTest
Test: atest com.android.server.pm.parsing
Change-Id: I877768c06ee15281f3334794034f4af563e74569
parent 5a347637
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1581,6 +1581,7 @@ package android {
    field public static final int useLevel = 16843167; // 0x101019f
    field public static final int userVisible = 16843409; // 0x1010291
    field public static final int usesCleartextTraffic = 16844012; // 0x10104ec
    field public static final int usesPermissionFlags = 16844356; // 0x1010644
    field public static final int value = 16842788; // 0x1010024
    field public static final int valueFrom = 16843486; // 0x10102de
    field public static final int valueTo = 16843487; // 0x10102df
@@ -12168,6 +12169,7 @@ package android.content.pm {
    field public static final int INSTALL_LOCATION_INTERNAL_ONLY = 1; // 0x1
    field public static final int INSTALL_LOCATION_PREFER_EXTERNAL = 2; // 0x2
    field public static final int REQUESTED_PERMISSION_GRANTED = 2; // 0x2
    field public static final int REQUESTED_PERMISSION_NEVER_FOR_LOCATION = 65536; // 0x10000
    field public android.content.pm.ActivityInfo[] activities;
    field public android.content.pm.ApplicationInfo applicationInfo;
    field @Nullable public android.content.pm.Attribution[] attributions;
+12 −2
Original line number Diff line number Diff line
@@ -232,13 +232,23 @@ public class PackageInfo implements Parcelable {
     *
     * @removed We do not support required permissions.
     */
    public static final int REQUESTED_PERMISSION_REQUIRED = 1<<0;
    public static final int REQUESTED_PERMISSION_REQUIRED = 0x00000001;

    /**
     * Flag for {@link #requestedPermissionsFlags}: the requested permission
     * is currently granted to the application.
     */
    public static final int REQUESTED_PERMISSION_GRANTED = 1<<1;
    public static final int REQUESTED_PERMISSION_GRANTED = 0x00000002;

    /**
     * Flag for {@link #requestedPermissionsFlags}: the requested permission has
     * declared {@code neverForLocation} in their manifest as a strong assertion
     * by a developer that they will never use this permission to derive the
     * physical location of the device, regardless of
     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} and/or
     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} being granted.
     */
    public static final int REQUESTED_PERMISSION_NEVER_FOR_LOCATION = 0x00010000;

    /**
     * Array of all signatures read from the package file. This is only filled
+17 −6
Original line number Diff line number Diff line
@@ -52,6 +52,7 @@ import android.content.pm.parsing.component.ParsedPermission;
import android.content.pm.parsing.component.ParsedPermissionGroup;
import android.content.pm.parsing.component.ParsedProvider;
import android.content.pm.parsing.component.ParsedService;
import android.content.pm.parsing.component.ParsedUsesPermission;
import android.os.Environment;
import android.os.UserHandle;

@@ -61,6 +62,7 @@ import libcore.util.EmptyArray;

import java.io.File;
import java.util.Collections;
import java.util.List;
import java.util.Set;

/** @hide **/
@@ -264,17 +266,26 @@ public class PackageInfoWithoutStateUtils {
                            flags);
                }
            }
            size = pkg.getRequestedPermissions().size();
            final List<ParsedUsesPermission> usesPermissions = pkg.getUsesPermissions();
            size = usesPermissions.size();
            if (size > 0) {
                pi.requestedPermissions = new String[size];
                pi.requestedPermissionsFlags = new int[size];
                for (int i = 0; i < size; i++) {
                    final String perm = pkg.getRequestedPermissions().get(i);
                    pi.requestedPermissions[i] = perm;
                    final ParsedUsesPermission usesPermission = usesPermissions.get(i);
                    pi.requestedPermissions[i] = usesPermission.name;
                    // The notion of required permissions is deprecated but for compatibility.
                    pi.requestedPermissionsFlags[i] |= PackageInfo.REQUESTED_PERMISSION_REQUIRED;
                    if (grantedPermissions != null && grantedPermissions.contains(perm)) {
                        pi.requestedPermissionsFlags[i] |= PackageInfo.REQUESTED_PERMISSION_GRANTED;
                    pi.requestedPermissionsFlags[i] |=
                            PackageInfo.REQUESTED_PERMISSION_REQUIRED;
                    if (grantedPermissions != null
                            && grantedPermissions.contains(usesPermission.name)) {
                        pi.requestedPermissionsFlags[i] |=
                                PackageInfo.REQUESTED_PERMISSION_GRANTED;
                    }
                    if ((usesPermission.usesPermissionFlags
                            & ParsedUsesPermission.FLAG_NEVER_FOR_LOCATION) != 0) {
                        pi.requestedPermissionsFlags[i] |=
                                PackageInfo.REQUESTED_PERMISSION_NEVER_FOR_LOCATION;
                    }
                }
            }
+3 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.content.pm.parsing.ParsingPackageImpl.sForInternedString;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.content.pm.PackageInfo;
import android.os.Parcel;
import android.os.Parcelable;

@@ -44,7 +45,8 @@ public class ParsedUsesPermission implements Parcelable {
     * to derive the physical location of the device, regardless of
     * ACCESS_FINE_LOCATION and/or ACCESS_COARSE_LOCATION being granted.
     */
    public static final int FLAG_NEVER_FOR_LOCATION = 0x1;
    public static final int FLAG_NEVER_FOR_LOCATION =
            PackageInfo.REQUESTED_PERMISSION_NEVER_FOR_LOCATION;

    /** @hide */
    @Retention(RetentionPolicy.SOURCE)
+3 −2
Original line number Diff line number Diff line
@@ -2063,13 +2063,14 @@
        requested.  If it does support the feature, it will be as if the manifest didn't
        request it at all. -->
        <attr name="requiredNotFeature" format="string" />
        <!-- Optional: set of flags that should apply to this permission request. -->
        <!-- Optional: set of flags that should apply to this permission request. Note that
             these flags start at 0x4 to match PackageInfo.requestedPermissionsFlags. -->
        <attr name="usesPermissionFlags">
            <!-- Strong assertion by a developer that they will never use this
                 permission to derive the physical location of the device, even
                 when the app has been granted the ACCESS_FINE_LOCATION and/or
                 ACCESS_COARSE_LOCATION permissions. -->
            <flag name="neverForLocation" value="0x1" />
            <flag name="neverForLocation" value="0x00010000" />
        </attr>
    </declare-styleable>

Loading