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:
Jeff Sharkey
2013-08-12 20:31:36 -07:00
parent 998cfa2c63
commit 02e4d16ed9
5 changed files with 44 additions and 67 deletions

View File

@@ -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"

View File

@@ -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>

View File

@@ -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() {

View File

@@ -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;
}
}

View File

@@ -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();
}