diff options
Diffstat (limited to 'cmds')
| -rw-r--r-- | cmds/installd/commands.c | 41 | ||||
| -rw-r--r-- | cmds/installd/installd.c | 6 | ||||
| -rw-r--r-- | cmds/installd/installd.h | 1 |
3 files changed, 46 insertions, 2 deletions
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) { diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c index c2c749ace793..fa4b8a6a1749 100644 --- a/cmds/installd/installd.c +++ b/cmds/installd/installd.c @@ -57,6 +57,11 @@ static int do_rename(char **arg, char reply[REPLY_MAX]) return renamepkg(arg[0], arg[1]); /* oldpkgname, newpkgname */ } +static int do_fixuid(char **arg, char reply[REPLY_MAX]) +{ + return fix_uid(arg[0], atoi(arg[1]), atoi(arg[2])); /* pkgname, uid, gid */ +} + static int do_free_cache(char **arg, char reply[REPLY_MAX]) /* TODO int:free_size */ { return free_cache((int64_t)atoll(arg[0])); /* free_size */ @@ -141,6 +146,7 @@ struct cmdinfo cmds[] = { { "rmdex", 1, do_rm_dex }, { "remove", 2, do_remove }, { "rename", 2, do_rename }, + { "fixuid", 3, do_fixuid }, { "freecache", 1, do_free_cache }, { "rmcache", 1, do_rm_cache }, { "protect", 2, do_protect }, diff --git a/cmds/installd/installd.h b/cmds/installd/installd.h index 78342bb6ac09..1b843fd997ba 100644 --- a/cmds/installd/installd.h +++ b/cmds/installd/installd.h @@ -143,6 +143,7 @@ char *build_string3(char *s1, char *s2, char *s3); int install(const char *pkgname, uid_t uid, gid_t gid); int uninstall(const char *pkgname, uid_t persona); int renamepkg(const char *oldpkgname, const char *newpkgname); +int fix_uid(const char *pkgname, uid_t uid, gid_t gid); int delete_user_data(const char *pkgname, uid_t persona); int make_user_data(const char *pkgname, uid_t uid, uid_t persona); int delete_persona(uid_t persona); |