Skip to content

Commit 9bef329

Browse files
krutonAndroid (Google) Code Review
authored andcommitted
Merge changes Ie3c8ca8d,Ia175b36d into jb-mr1-dev
* changes: Try to free cache before giving up on install Robustly add symlink and add for non-primary users
2 parents 7e1664d + cea3743 commit 9bef329

File tree

9 files changed

+200
-104
lines changed

9 files changed

+200
-104
lines changed

cmds/installd/commands.c

Lines changed: 104 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ int install(const char *pkgname, uid_t uid, gid_t gid)
3636
char pkgdir[PKG_PATH_MAX];
3737
char libsymlink[PKG_PATH_MAX];
3838
char applibdir[PKG_PATH_MAX];
39+
struct stat libStat;
3940

4041
if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) {
4142
ALOGE("invalid uid/gid: %d %d\n", uid, gid);
@@ -67,6 +68,25 @@ int install(const char *pkgname, uid_t uid, gid_t gid)
6768
return -1;
6869
}
6970

71+
if (lstat(libsymlink, &libStat) < 0) {
72+
if (errno != ENOENT) {
73+
ALOGE("couldn't stat lib dir: %s\n", strerror(errno));
74+
return -1;
75+
}
76+
} else {
77+
if (S_ISDIR(libStat.st_mode)) {
78+
if (delete_dir_contents(libsymlink, 1, 0) < 0) {
79+
ALOGE("couldn't delete lib directory during install for: %s", libsymlink);
80+
return -1;
81+
}
82+
} else if (S_ISLNK(libStat.st_mode)) {
83+
if (unlink(libsymlink) < 0) {
84+
ALOGE("couldn't unlink lib directory during install for: %s", libsymlink);
85+
return -1;
86+
}
87+
}
88+
}
89+
7090
if (symlink(applibdir, libsymlink) < 0) {
7191
ALOGE("couldn't symlink directory '%s' -> '%s': %s\n", libsymlink, applibdir,
7292
strerror(errno));
@@ -140,7 +160,7 @@ int fix_uid(const char *pkgname, uid_t uid, gid_t gid)
140160
if (stat(pkgdir, &s) < 0) return -1;
141161

142162
if (s.st_uid != 0 || s.st_gid != 0) {
143-
ALOGE("fixing uid of non-root pkg: %s %d %d\n", pkgdir, s.st_uid, s.st_gid);
163+
ALOGE("fixing uid of non-root pkg: %s %lu %lu\n", pkgdir, s.st_uid, s.st_gid);
144164
return -1;
145165
}
146166

@@ -165,18 +185,30 @@ int delete_user_data(const char *pkgname, uid_t persona)
165185
if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, persona))
166186
return -1;
167187

168-
/* delete contents, excluding "lib", but not the directory itself */
169-
return delete_dir_contents(pkgdir, 0, "lib");
188+
/* delete contents AND directory, no exceptions */
189+
return delete_dir_contents(pkgdir, 1, NULL);
170190
}
171191

172192
int make_user_data(const char *pkgname, uid_t uid, uid_t persona)
173193
{
174194
char pkgdir[PKG_PATH_MAX];
195+
char applibdir[PKG_PATH_MAX];
196+
char libsymlink[PKG_PATH_MAX];
197+
struct stat libStat;
175198

176199
// Create the data dir for the package
177200
if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, persona)) {
178201
return -1;
179202
}
203+
if (create_pkg_path(libsymlink, pkgname, PKG_LIB_POSTFIX, persona)) {
204+
ALOGE("cannot create package lib symlink origin path\n");
205+
return -1;
206+
}
207+
if (create_pkg_path_in_dir(applibdir, &android_app_lib_dir, pkgname, PKG_DIR_POSTFIX)) {
208+
ALOGE("cannot create package lib symlink dest path\n");
209+
return -1;
210+
}
211+
180212
if (mkdir(pkgdir, 0751) < 0) {
181213
ALOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno));
182214
return -errno;
@@ -186,15 +218,49 @@ int make_user_data(const char *pkgname, uid_t uid, uid_t persona)
186218
unlink(pkgdir);
187219
return -errno;
188220
}
221+
222+
if (lstat(libsymlink, &libStat) < 0) {
223+
if (errno != ENOENT) {
224+
ALOGE("couldn't stat lib dir for non-primary: %s\n", strerror(errno));
225+
unlink(pkgdir);
226+
return -1;
227+
}
228+
} else {
229+
if (S_ISDIR(libStat.st_mode)) {
230+
if (delete_dir_contents(libsymlink, 1, 0) < 0) {
231+
ALOGE("couldn't delete lib directory during install for non-primary: %s",
232+
libsymlink);
233+
unlink(pkgdir);
234+
return -1;
235+
}
236+
} else if (S_ISLNK(libStat.st_mode)) {
237+
if (unlink(libsymlink) < 0) {
238+
ALOGE("couldn't unlink lib directory during install for non-primary: %s",
239+
libsymlink);
240+
unlink(pkgdir);
241+
return -1;
242+
}
243+
}
244+
}
245+
246+
if (symlink(applibdir, libsymlink) < 0) {
247+
ALOGE("couldn't symlink directory for non-primary '%s' -> '%s': %s\n", libsymlink,
248+
applibdir, strerror(errno));
249+
unlink(pkgdir);
250+
return -1;
251+
}
252+
189253
if (chown(pkgdir, uid, uid) < 0) {
190254
ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
255+
unlink(libsymlink);
191256
unlink(pkgdir);
192257
return -errno;
193258
}
194259

195260
#ifdef HAVE_SELINUX
196261
if (selinux_android_setfilecon(pkgdir, pkgname, uid) < 0) {
197262
ALOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
263+
unlink(libsymlink);
198264
unlink(pkgdir);
199265
return -errno;
200266
}
@@ -254,7 +320,7 @@ int clone_persona_data(uid_t src_persona, uid_t target_persona, int copy)
254320
/* Get the file stat */
255321
if (stat(pkg_path, &s) < 0) continue;
256322
/* Get the uid of the package */
257-
ALOGI("Adding datadir for uid = %d\n", s.st_uid);
323+
ALOGI("Adding datadir for uid = %lu\n", s.st_uid);
258324
uid = (uid_t) s.st_uid % PER_USER_RANGE;
259325
/* Create the directory for the target */
260326
make_user_data(name, uid + target_persona * PER_USER_RANGE,
@@ -991,75 +1057,71 @@ int movefiles()
9911057
return 0;
9921058
}
9931059

994-
int linklib(const char* dataDir, const char* asecLibDir)
1060+
int linklib(const char* pkgname, const char* asecLibDir, int userId)
9951061
{
996-
char libdir[PKG_PATH_MAX];
1062+
char pkgdir[PKG_PATH_MAX];
1063+
char libsymlink[PKG_PATH_MAX];
9971064
struct stat s, libStat;
9981065
int rc = 0;
9991066

1000-
const size_t libdirLen = strlen(dataDir) + strlen(PKG_LIB_POSTFIX);
1001-
if (libdirLen >= PKG_PATH_MAX) {
1002-
ALOGE("library dir len too large");
1067+
if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userId)) {
1068+
ALOGE("cannot create package path\n");
10031069
return -1;
10041070
}
1005-
1006-
if (snprintf(libdir, sizeof(libdir), "%s%s", dataDir, PKG_LIB_POSTFIX) != (ssize_t)libdirLen) {
1007-
ALOGE("library dir not written successfully: %s\n", strerror(errno));
1071+
if (create_pkg_path(libsymlink, pkgname, PKG_LIB_POSTFIX, userId)) {
1072+
ALOGE("cannot create package lib symlink origin path\n");
10081073
return -1;
10091074
}
10101075

1011-
if (stat(dataDir, &s) < 0) return -1;
1076+
if (stat(pkgdir, &s) < 0) return -1;
10121077

1013-
if (chown(dataDir, AID_INSTALL, AID_INSTALL) < 0) {
1014-
ALOGE("failed to chown '%s': %s\n", dataDir, strerror(errno));
1078+
if (chown(pkgdir, AID_INSTALL, AID_INSTALL) < 0) {
1079+
ALOGE("failed to chown '%s': %s\n", pkgdir, strerror(errno));
10151080
return -1;
10161081
}
10171082

1018-
if (chmod(dataDir, 0700) < 0) {
1019-
ALOGE("linklib() 1: failed to chmod '%s': %s\n", dataDir, strerror(errno));
1083+
if (chmod(pkgdir, 0700) < 0) {
1084+
ALOGE("linklib() 1: failed to chmod '%s': %s\n", pkgdir, strerror(errno));
10201085
rc = -1;
10211086
goto out;
10221087
}
10231088

1024-
if (lstat(libdir, &libStat) < 0) {
1025-
ALOGE("couldn't stat lib dir: %s\n", strerror(errno));
1026-
rc = -1;
1027-
goto out;
1028-
}
1029-
1030-
if (S_ISDIR(libStat.st_mode)) {
1031-
if (delete_dir_contents(libdir, 1, 0) < 0) {
1089+
if (lstat(libsymlink, &libStat) < 0) {
1090+
if (errno != ENOENT) {
1091+
ALOGE("couldn't stat lib dir: %s\n", strerror(errno));
10321092
rc = -1;
10331093
goto out;
10341094
}
1035-
} else if (S_ISLNK(libStat.st_mode)) {
1036-
if (unlink(libdir) < 0) {
1037-
rc = -1;
1038-
goto out;
1095+
} else {
1096+
if (S_ISDIR(libStat.st_mode)) {
1097+
if (delete_dir_contents(libsymlink, 1, 0) < 0) {
1098+
rc = -1;
1099+
goto out;
1100+
}
1101+
} else if (S_ISLNK(libStat.st_mode)) {
1102+
if (unlink(libsymlink) < 0) {
1103+
ALOGE("couldn't unlink lib dir: %s\n", strerror(errno));
1104+
rc = -1;
1105+
goto out;
1106+
}
10391107
}
10401108
}
10411109

1042-
if (symlink(asecLibDir, libdir) < 0) {
1043-
ALOGE("couldn't symlink directory '%s' -> '%s': %s\n", libdir, asecLibDir, strerror(errno));
1044-
rc = -errno;
1045-
goto out;
1046-
}
1047-
1048-
if (lchown(libdir, AID_SYSTEM, AID_SYSTEM) < 0) {
1049-
ALOGE("cannot chown dir '%s': %s\n", libdir, strerror(errno));
1050-
unlink(libdir);
1110+
if (symlink(asecLibDir, libsymlink) < 0) {
1111+
ALOGE("couldn't symlink directory '%s' -> '%s': %s\n", libsymlink, asecLibDir,
1112+
strerror(errno));
10511113
rc = -errno;
10521114
goto out;
10531115
}
10541116

10551117
out:
1056-
if (chmod(dataDir, s.st_mode) < 0) {
1057-
ALOGE("linklib() 2: failed to chmod '%s': %s\n", dataDir, strerror(errno));
1118+
if (chmod(pkgdir, s.st_mode) < 0) {
1119+
ALOGE("linklib() 2: failed to chmod '%s': %s\n", pkgdir, strerror(errno));
10581120
rc = -errno;
10591121
}
10601122

1061-
if (chown(dataDir, s.st_uid, s.st_gid) < 0) {
1062-
ALOGE("failed to chown '%s' : %s\n", dataDir, strerror(errno));
1123+
if (chown(pkgdir, s.st_uid, s.st_gid) < 0) {
1124+
ALOGE("failed to chown '%s' : %s\n", pkgdir, strerror(errno));
10631125
return -errno;
10641126
}
10651127

cmds/installd/installd.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ static int do_movefiles(char **arg, char reply[REPLY_MAX])
123123

124124
static int do_linklib(char **arg, char reply[REPLY_MAX])
125125
{
126-
return linklib(arg[0], arg[1]);
126+
return linklib(arg[0], arg[1], atoi(arg[2]));
127127
}
128128

129129
struct cmdinfo {
@@ -146,7 +146,7 @@ struct cmdinfo cmds[] = {
146146
{ "getsize", 5, do_get_size },
147147
{ "rmuserdata", 2, do_rm_user_data },
148148
{ "movefiles", 0, do_movefiles },
149-
{ "linklib", 2, do_linklib },
149+
{ "linklib", 3, do_linklib },
150150
{ "mkuserdata", 3, do_mk_user_data },
151151
{ "rmuser", 1, do_rm_user },
152152
{ "cloneuserdata", 3, do_clone_user_data },

cmds/installd/installd.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ char *build_string2(char *s1, char *s2);
188188
char *build_string3(char *s1, char *s2, char *s3);
189189

190190
int ensure_dir(const char* path, mode_t mode, uid_t uid, gid_t gid);
191+
int ensure_media_user_dirs(userid_t userid);
191192

192193
/* commands.c */
193194

@@ -209,4 +210,4 @@ int get_size(const char *pkgname, int persona, const char *apkpath, const char *
209210
int free_cache(int64_t free_size);
210211
int dexopt(const char *apk_path, uid_t uid, int is_public);
211212
int movefiles();
212-
int linklib(const char* target, const char* source);
213+
int linklib(const char* target, const char* source, int userId);

core/java/com/android/internal/app/IMediaContainerService.aidl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,4 +36,5 @@ interface IMediaContainerService {
3636
/** Return file system stats: [0] is total bytes, [1] is available bytes */
3737
long[] getFileSystemStats(in String path);
3838
void clearDirectory(in String directory);
39+
long calculateInstalledSize(in String packagePath, boolean isForwardLocked);
3940
}

core/tests/coretests/apks/install_bad_dex/AndroidManifest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
limitations under the License.
1515
-->
1616
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
17-
package="com.android.frameworks.coretests.install_loc">
17+
package="com.android.frameworks.coretests.install_bad_dex">
1818

1919
<application android:hasCode="true">
2020
<activity

core/tests/coretests/src/android/content/pm/PackageManagerTests.java

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -981,19 +981,22 @@ public boolean invokeDeletePackage(final String pkgName, int flags, GenericRecei
981981
try {
982982
DeleteObserver observer = new DeleteObserver(pkgName);
983983

984-
getPm().deletePackage(pkgName, observer, flags);
984+
getPm().deletePackage(pkgName, observer, flags | PackageManager.DELETE_ALL_USERS);
985985
observer.waitForCompletion(MAX_WAIT_TIME);
986986

987987
assertUninstalled(info);
988988

989989
// Verify we received the broadcast
990-
long waitTime = 0;
991-
while ((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME)) {
992-
receiver.wait(WAIT_TIME_INCR);
993-
waitTime += WAIT_TIME_INCR;
994-
}
995-
if (!receiver.isDone()) {
996-
throw new Exception("Timed out waiting for PACKAGE_REMOVED notification");
990+
// TODO replace this with a CountDownLatch
991+
synchronized (receiver) {
992+
long waitTime = 0;
993+
while ((!receiver.isDone()) && (waitTime < MAX_WAIT_TIME)) {
994+
receiver.wait(WAIT_TIME_INCR);
995+
waitTime += WAIT_TIME_INCR;
996+
}
997+
if (!receiver.isDone()) {
998+
throw new Exception("Timed out waiting for PACKAGE_REMOVED notification");
999+
}
9971000
}
9981001
return receiver.received;
9991002
} finally {
@@ -1331,7 +1334,7 @@ void cleanUpInstall(InstallParams ip) throws Exception {
13311334
}
13321335

13331336
DeleteObserver observer = new DeleteObserver(packageName);
1334-
getPm().deletePackage(packageName, observer, 0);
1337+
getPm().deletePackage(packageName, observer, PackageManager.DELETE_ALL_USERS);
13351338
observer.waitForCompletion(MAX_WAIT_TIME);
13361339

13371340
try {
@@ -1357,7 +1360,7 @@ private void cleanUpInstall(String pkgName) throws Exception {
13571360

13581361
if (info != null) {
13591362
DeleteObserver observer = new DeleteObserver(pkgName);
1360-
getPm().deletePackage(pkgName, observer, 0);
1363+
getPm().deletePackage(pkgName, observer, PackageManager.DELETE_ALL_USERS);
13611364
observer.waitForCompletion(MAX_WAIT_TIME);
13621365
assertUninstalled(info);
13631366
}
@@ -3126,7 +3129,7 @@ public void testCheckSignaturesUnknown() throws Exception {
31263129
int rawResId = apk2;
31273130
Uri packageURI = getInstallablePackage(rawResId, outFile);
31283131
PackageParser.Package pkg = parsePackage(packageURI);
3129-
getPm().deletePackage(pkg.packageName, null, 0);
3132+
getPm().deletePackage(pkg.packageName, null, PackageManager.DELETE_ALL_USERS);
31303133
// Check signatures now
31313134
int match = mContext.getPackageManager().checkSignatures(
31323135
ip1.pkg.packageName, pkg.packageName);
@@ -3265,7 +3268,7 @@ public void testCheckSignaturesSharedUnknown() throws Exception {
32653268
PackageManager pm = mContext.getPackageManager();
32663269
// Delete app2
32673270
PackageParser.Package pkg = getParsedPackage(apk2Name, apk2);
3268-
getPm().deletePackage(pkg.packageName, null, 0);
3271+
getPm().deletePackage(pkg.packageName, null, PackageManager.DELETE_ALL_USERS);
32693272
// Check signatures now
32703273
int match = mContext.getPackageManager().checkSignatures(
32713274
ip1.pkg.packageName, pkg.packageName);

packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,21 @@ public void clearDirectory(String path) throws RemoteException {
259259
eraseFiles(directory);
260260
}
261261
}
262+
263+
@Override
264+
public long calculateInstalledSize(String packagePath, boolean isForwardLocked)
265+
throws RemoteException {
266+
final File packageFile = new File(packagePath);
267+
try {
268+
return calculateContainerSize(packageFile, isForwardLocked) * 1024 * 1024;
269+
} catch (IOException e) {
270+
/*
271+
* Okay, something failed, so let's just estimate it to be 2x
272+
* the file size. Note this will be 0 if the file doesn't exist.
273+
*/
274+
return packageFile.length() * 2;
275+
}
276+
}
262277
};
263278

264279
public DefaultContainerService() {

services/java/com/android/server/pm/Installer.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,7 @@ public int moveFiles() {
369369
* @param nativeLibPath target native library path
370370
* @return -1 on error
371371
*/
372-
public int linkNativeLibraryDirectory(String dataPath, String nativeLibPath) {
372+
public int linkNativeLibraryDirectory(String dataPath, String nativeLibPath, int userId) {
373373
if (dataPath == null) {
374374
Slog.e(TAG, "linkNativeLibraryDirectory dataPath is null");
375375
return -1;
@@ -382,6 +382,8 @@ public int linkNativeLibraryDirectory(String dataPath, String nativeLibPath) {
382382
builder.append(dataPath);
383383
builder.append(' ');
384384
builder.append(nativeLibPath);
385+
builder.append(' ');
386+
builder.append(userId);
385387

386388
return execute(builder.toString());
387389
}

0 commit comments

Comments
 (0)