Add GIDs to packages.list, update SD card perms.
Write supplementary GIDs to packages.list for lower-level system components to parse. WRITE_EXTERNAL_STORAGE also implies sdcard_r GID. Switch to always enforce READ_EXTERNAL_STORAGE permission. Update permission docs to mention new behavior. Change-Id: I316ba4b21beebb387ac05c80980ae9b38235b37d
This commit is contained in:
@@ -1077,15 +1077,15 @@
|
||||
<!-- Allows an application to read from external storage.
|
||||
<p>Any app that declares the {@link #WRITE_EXTERNAL_STORAGE} permission is implicitly
|
||||
granted this permission.</p>
|
||||
<p>Currently, this permission is not enforced and all apps still have access to read from
|
||||
external storage without this permission. That will change in a future release and apps
|
||||
will require this permission to read from external storage. So if your
|
||||
app reads from the external storage, you should add this permission to your app now
|
||||
to ensure that it continues to work on future versions of Android.</p>
|
||||
<p>You can test your app with the permission enforced by either running your app on the
|
||||
Android Emulator when running Android 4.1 or higher, or enabling <em>Protect USB
|
||||
<p>This permission is enforced starting in API level 19. Before API level 19, this
|
||||
permission is not enforced and all apps still have access to read from external storage.
|
||||
You can test your app with the permission enforced by enabling <em>Protect USB
|
||||
storage</em> under Developer options in the Settings app on a device running Android 4.1 or
|
||||
higher.</p>
|
||||
<p>Also starting in API level 19, this permission is <em>not</em> required to
|
||||
read/write files in your application-specific directories returned by
|
||||
{@link android.content.Context#getExternalFilesDir} and
|
||||
{@link android.content.Context#getExternalCacheDir}.
|
||||
<p class="note"><strong>Note:</strong> If <em>both</em> your <a
|
||||
href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
|
||||
minSdkVersion}</a> and <a
|
||||
@@ -1108,7 +1108,11 @@
|
||||
targetSdkVersion}</a> values are set to 3 or lower, the system implicitly
|
||||
grants your app this permission. If you don't need this permission, be sure your <a
|
||||
href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
|
||||
targetSdkVersion}</a> is 4 or higher. -->
|
||||
targetSdkVersion}</a> is 4 or higher.
|
||||
<p>Starting in API level 19, this permission is <em>not</em> required to
|
||||
read/write files in your application-specific directories returned by
|
||||
{@link android.content.Context#getExternalFilesDir} and
|
||||
{@link android.content.Context#getExternalCacheDir}. -->
|
||||
<permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
|
||||
android:permissionGroup="android.permission-group.STORAGE"
|
||||
android:label="@string/permlab_sdcardWrite"
|
||||
|
||||
@@ -63,9 +63,16 @@
|
||||
</permission>
|
||||
|
||||
<permission name="android.permission.WRITE_EXTERNAL_STORAGE" >
|
||||
<group gid="sdcard_r" />
|
||||
<group gid="sdcard_rw" />
|
||||
</permission>
|
||||
|
||||
<permission name="android.permission.ACCESS_ALL_EXTERNAL_STORAGE" >
|
||||
<group gid="sdcard_r" />
|
||||
<group gid="sdcard_rw" />
|
||||
<group gid="sdcard_all" />
|
||||
</permission>
|
||||
|
||||
<permission name="android.permission.WRITE_MEDIA_STORAGE" >
|
||||
<group gid="media_rw" />
|
||||
</permission>
|
||||
|
||||
@@ -1792,8 +1792,8 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int[] getPackageGids(String packageName) {
|
||||
final boolean enforcedDefault = isPermissionEnforcedDefault(READ_EXTERNAL_STORAGE);
|
||||
// reader
|
||||
synchronized (mPackages) {
|
||||
PackageParser.Package p = mPackages.get(packageName);
|
||||
@@ -1801,17 +1801,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
Log.v(TAG, "getPackageGids" + packageName + ": " + p);
|
||||
if (p != null) {
|
||||
final PackageSetting ps = (PackageSetting)p.mExtras;
|
||||
final SharedUserSetting suid = ps.sharedUser;
|
||||
int[] gids = suid != null ? suid.gids : ps.gids;
|
||||
|
||||
// include GIDs for any unenforced permissions
|
||||
if (!isPermissionEnforcedLocked(READ_EXTERNAL_STORAGE, enforcedDefault)) {
|
||||
final BasePermission basePerm = mSettings.mPermissions.get(
|
||||
READ_EXTERNAL_STORAGE);
|
||||
gids = appendInts(gids, basePerm.gids);
|
||||
}
|
||||
|
||||
return gids;
|
||||
return ps.getGids();
|
||||
}
|
||||
}
|
||||
// stupid thing to indicate an error.
|
||||
@@ -2132,7 +2122,6 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
}
|
||||
|
||||
public int checkPermission(String permName, String pkgName) {
|
||||
final boolean enforcedDefault = isPermissionEnforcedDefault(permName);
|
||||
synchronized (mPackages) {
|
||||
PackageParser.Package p = mPackages.get(pkgName);
|
||||
if (p != null && p.mExtras != null) {
|
||||
@@ -2145,15 +2134,11 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
return PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
}
|
||||
if (!isPermissionEnforcedLocked(permName, enforcedDefault)) {
|
||||
return PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
}
|
||||
return PackageManager.PERMISSION_DENIED;
|
||||
}
|
||||
|
||||
public int checkUidPermission(String permName, int uid) {
|
||||
final boolean enforcedDefault = isPermissionEnforcedDefault(permName);
|
||||
synchronized (mPackages) {
|
||||
Object obj = mSettings.getUserIdLPr(UserHandle.getAppId(uid));
|
||||
if (obj != null) {
|
||||
@@ -2167,9 +2152,6 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
return PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
}
|
||||
if (!isPermissionEnforcedLocked(permName, enforcedDefault)) {
|
||||
return PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
}
|
||||
return PackageManager.PERMISSION_DENIED;
|
||||
}
|
||||
@@ -11112,42 +11094,9 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Deprecated
|
||||
public boolean isPermissionEnforced(String permission) {
|
||||
final boolean enforcedDefault = isPermissionEnforcedDefault(permission);
|
||||
synchronized (mPackages) {
|
||||
return isPermissionEnforcedLocked(permission, enforcedDefault);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if given permission should be enforced by default. Should always be
|
||||
* called outside of {@link #mPackages} lock.
|
||||
*/
|
||||
private boolean isPermissionEnforcedDefault(String permission) {
|
||||
if (READ_EXTERNAL_STORAGE.equals(permission)) {
|
||||
return android.provider.Settings.Global.getInt(mContext.getContentResolver(),
|
||||
android.provider.Settings.Global.READ_EXTERNAL_STORAGE_ENFORCED_DEFAULT, 0)
|
||||
!= 0;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if user has requested that given permission be enforced, using
|
||||
* given default if undefined.
|
||||
*/
|
||||
private boolean isPermissionEnforcedLocked(String permission, boolean enforcedDefault) {
|
||||
if (READ_EXTERNAL_STORAGE.equals(permission)) {
|
||||
if (mSettings.mReadExternalStorageEnforced != null) {
|
||||
return mSettings.mReadExternalStorageEnforced;
|
||||
} else {
|
||||
// User hasn't defined; fall back to secure default
|
||||
return enforcedDefault;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isStorageLow() {
|
||||
|
||||
@@ -52,4 +52,8 @@ final class PackageSetting extends PackageSettingBase {
|
||||
+ Integer.toHexString(System.identityHashCode(this))
|
||||
+ " " + name + "/" + appId + "}";
|
||||
}
|
||||
}
|
||||
|
||||
public int[] getGids() {
|
||||
return sharedUser != null ? sharedUser.gids : gids;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1385,9 +1385,10 @@ final class Settings {
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (final PackageSetting pkg : mPackages.values()) {
|
||||
ApplicationInfo ai = pkg.pkg.applicationInfo;
|
||||
String dataPath = ai.dataDir;
|
||||
boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
|
||||
final ApplicationInfo ai = pkg.pkg.applicationInfo;
|
||||
final String dataPath = ai.dataDir;
|
||||
final boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
|
||||
final int[] gids = pkg.getGids();
|
||||
|
||||
// Avoid any application that has a space in its path
|
||||
// or that is handled by the system.
|
||||
@@ -1401,6 +1402,7 @@ final class Settings {
|
||||
// debugFlag - 0 or 1 if the package is debuggable.
|
||||
// dataPath - path to package's data path
|
||||
// seinfo - seinfo label for the app (assigned at install time)
|
||||
// gids - supplementary gids this app launches with
|
||||
//
|
||||
// NOTE: We prefer not to expose all ApplicationInfo flags for now.
|
||||
//
|
||||
@@ -1417,6 +1419,16 @@ final class Settings {
|
||||
sb.append(dataPath);
|
||||
sb.append(" ");
|
||||
sb.append(ai.seinfo);
|
||||
sb.append(" ");
|
||||
if (gids != null && gids.length > 0) {
|
||||
sb.append(gids[0]);
|
||||
for (int i = 1; i < gids.length; i++) {
|
||||
sb.append(",");
|
||||
sb.append(gids[i]);
|
||||
}
|
||||
} else {
|
||||
sb.append("none");
|
||||
}
|
||||
sb.append("\n");
|
||||
str.write(sb.toString().getBytes());
|
||||
}
|
||||
@@ -1425,6 +1437,7 @@ final class Settings {
|
||||
str.close();
|
||||
journal.commit();
|
||||
} catch (Exception e) {
|
||||
Log.wtf(TAG, "Failed to write packages.list", e);
|
||||
IoUtils.closeQuietly(str);
|
||||
journal.rollback();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user