From d0c5f515c05d05c9d24971695337daf9d6ce409c Mon Sep 17 00:00:00 2001 From: Dianne Hackborn Date: Thu, 7 Jun 2012 16:53:59 -0700 Subject: Fix issue #6295373: "Package com.google.android.apps.authenticator2 has... ...mismatched uid: X on disk, Y in settings" errors on Froyo and Gingerbread Deal more gracefully with the uid changing in three ways: 1. If the uid on disk has become root, then have installd change it to the application's uid. This is to correct a potential case where installd was interrupted while linking or unlinking the libs dir, during which it temporarily changes the owner of the dir to root so that a malicious app can not get in its way. So if the uid on disk has become root, we assume we can safely just change it back to the correct uid. 2. When scaning packages at boot, use the same "delete and rebuild data directory" code for third party applications as we have for system applications. This allows us to at least end up in a state where the app will run, even if its data is lost. 3. But we really don't want to get in to case 2, so if an application update is being installed and we find that the uid we now have for the app is different than the one on disk, fail the update. This will protect against for example a developer changing the sharedUserId of their app and getting into this bad state. Bug: 6295373 Change-Id: Ic802fdd818ac62449ff3c61d1fff1aa4d4942f39 --- cmds/installd/commands.c | 41 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) (limited to 'cmds/installd/commands.c') diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c index 203d180a6439..0bc737185b91 100644 --- a/cmds/installd/commands.c +++ b/cmds/installd/commands.c @@ -106,6 +106,43 @@ int renamepkg(const char *oldpkgname, const char *newpkgname) return 0; } +int fix_uid(const char *pkgname, uid_t uid, gid_t gid) +{ + char pkgdir[PKG_PATH_MAX]; + struct stat s; + int rc = 0; + + if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) { + ALOGE("invalid uid/gid: %d %d\n", uid, gid); + return -1; + } + + if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, 0)) { + ALOGE("cannot create package path\n"); + return -1; + } + + if (stat(pkgdir, &s) < 0) return -1; + + if (s.st_uid != 0 || s.st_gid != 0) { + ALOGE("fixing uid of non-root pkg: %s %d %d\n", pkgdir, s.st_uid, s.st_gid); + return -1; + } + + if (chmod(pkgdir, 0751) < 0) { + ALOGE("cannot chmod dir '%s': %s\n", pkgdir, strerror(errno)); + unlink(pkgdir); + return -errno; + } + if (chown(pkgdir, uid, gid) < 0) { + ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno)); + unlink(pkgdir); + return -errno; + } + + return 0; +} + int delete_user_data(const char *pkgname, uid_t persona) { char pkgdir[PKG_PATH_MAX]; @@ -950,7 +987,7 @@ int linklib(const char* dataDir, const char* asecLibDir) out: if (chmod(dataDir, s.st_mode) < 0) { ALOGE("failed to chmod '%s': %s\n", dataDir, strerror(errno)); - return -errno; + rc = -errno; } if (chown(dataDir, s.st_uid, s.st_gid) < 0) { @@ -1027,7 +1064,7 @@ int unlinklib(const char* dataDir) out: if (chmod(dataDir, s.st_mode) < 0) { ALOGE("failed to chmod '%s': %s\n", dataDir, strerror(errno)); - return -1; + rc = -1; } if (chown(dataDir, s.st_uid, s.st_gid) < 0) { -- cgit v1.2.3-59-g8ed1b