resolved conflicts for merge of a5d29b2c to jb-mr1-dev-plus-aosp

Change-Id: I21512d61b5c08cee5fed69b34c3275ba5c3fc0d8
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index 4da772a..4d49c8a 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -33,6 +33,7 @@
     char pkgdir[PKG_PATH_MAX];
     char libsymlink[PKG_PATH_MAX];
     char applibdir[PKG_PATH_MAX];
+    struct stat libStat;
 
     if ((uid < AID_SYSTEM) || (gid < AID_SYSTEM)) {
         ALOGE("invalid uid/gid: %d %d\n", uid, gid);
@@ -64,6 +65,25 @@
         return -1;
     }
 
+    if (lstat(libsymlink, &libStat) < 0) {
+        if (errno != ENOENT) {
+            ALOGE("couldn't stat lib dir: %s\n", strerror(errno));
+            return -1;
+        }
+    } else {
+        if (S_ISDIR(libStat.st_mode)) {
+            if (delete_dir_contents(libsymlink, 1, 0) < 0) {
+                ALOGE("couldn't delete lib directory during install for: %s", libsymlink);
+                return -1;
+            }
+        } else if (S_ISLNK(libStat.st_mode)) {
+            if (unlink(libsymlink) < 0) {
+                ALOGE("couldn't unlink lib directory during install for: %s", libsymlink);
+                return -1;
+            }
+        }
+    }
+
     if (symlink(applibdir, libsymlink) < 0) {
         ALOGE("couldn't symlink directory '%s' -> '%s': %s\n", libsymlink, applibdir,
                 strerror(errno));
@@ -142,7 +162,7 @@
     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);
+        ALOGE("fixing uid of non-root pkg: %s %lu %lu\n", pkgdir, s.st_uid, s.st_gid);
         return -1;
     }
 
@@ -167,18 +187,30 @@
     if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, persona))
         return -1;
 
-    /* delete contents, excluding "lib", but not the directory itself */
-    return delete_dir_contents(pkgdir, 0, "lib");
+    /* delete contents AND directory, no exceptions */
+    return delete_dir_contents(pkgdir, 1, NULL);
 }
 
 int make_user_data(const char *pkgname, uid_t uid, uid_t persona)
 {
     char pkgdir[PKG_PATH_MAX];
+    char applibdir[PKG_PATH_MAX];
+    char libsymlink[PKG_PATH_MAX];
+    struct stat libStat;
 
     // Create the data dir for the package
     if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, persona)) {
         return -1;
     }
+    if (create_pkg_path(libsymlink, pkgname, PKG_LIB_POSTFIX, persona)) {
+        ALOGE("cannot create package lib symlink origin path\n");
+        return -1;
+    }
+    if (create_pkg_path_in_dir(applibdir, &android_app_lib_dir, pkgname, PKG_DIR_POSTFIX)) {
+        ALOGE("cannot create package lib symlink dest path\n");
+        return -1;
+    }
+
     if (mkdir(pkgdir, 0751) < 0) {
         ALOGE("cannot create dir '%s': %s\n", pkgdir, strerror(errno));
         return -errno;
@@ -188,13 +220,55 @@
         unlink(pkgdir);
         return -errno;
     }
-    if (selinux_android_setfilecon(pkgdir, pkgname, uid) < 0) {
-        ALOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
+
+    if (lstat(libsymlink, &libStat) < 0) {
+        if (errno != ENOENT) {
+            ALOGE("couldn't stat lib dir for non-primary: %s\n", strerror(errno));
+            unlink(pkgdir);
+            return -1;
+        }
+    } else {
+        if (S_ISDIR(libStat.st_mode)) {
+            if (delete_dir_contents(libsymlink, 1, 0) < 0) {
+                ALOGE("couldn't delete lib directory during install for non-primary: %s",
+                        libsymlink);
+                unlink(pkgdir);
+                return -1;
+            }
+        } else if (S_ISLNK(libStat.st_mode)) {
+            if (unlink(libsymlink) < 0) {
+                ALOGE("couldn't unlink lib directory during install for non-primary: %s",
+                        libsymlink);
+                unlink(pkgdir);
+                return -1;
+            }
+        }
+    }
+
+    if (symlink(applibdir, libsymlink) < 0) {
+        ALOGE("couldn't symlink directory for non-primary '%s' -> '%s': %s\n", libsymlink,
+                applibdir, strerror(errno));
+        unlink(pkgdir);
+        return -1;
+    }
+
+    if (selinux_android_setfilecon(libsymlink, pkgname, AID_SYSTEM) < 0) {
+        ALOGE("cannot setfilecon dir '%s': %s\n", libsymlink, strerror(errno));
+        unlink(libsymlink);
         unlink(pkgdir);
         return -errno;
     }
+
+    if (selinux_android_setfilecon(pkgdir, pkgname, uid) < 0) {
+        ALOGE("cannot setfilecon dir '%s': %s\n", pkgdir, strerror(errno));
+        unlink(libsymlink);
+        unlink(pkgdir);
+        return -errno;
+    }
+
     if (chown(pkgdir, uid, uid) < 0) {
         ALOGE("cannot chown dir '%s': %s\n", pkgdir, strerror(errno));
+        unlink(libsymlink);
         unlink(pkgdir);
         return -errno;
     }
@@ -253,7 +327,7 @@
                 /* Get the file stat */
                 if (stat(pkg_path, &s) < 0) continue;
                 /* Get the uid of the package */
-                ALOGI("Adding datadir for uid = %d\n", s.st_uid);
+                ALOGI("Adding datadir for uid = %lu\n", s.st_uid);
                 uid = (uid_t) s.st_uid % PER_USER_RANGE;
                 /* Create the directory for the target */
                 make_user_data(name, uid + target_persona * PER_USER_RANGE,
@@ -990,75 +1064,71 @@
     return 0;
 }
 
-int linklib(const char* dataDir, const char* asecLibDir)
+int linklib(const char* pkgname, const char* asecLibDir, int userId)
 {
-    char libdir[PKG_PATH_MAX];
+    char pkgdir[PKG_PATH_MAX];
+    char libsymlink[PKG_PATH_MAX];
     struct stat s, libStat;
     int rc = 0;
 
-    const size_t libdirLen = strlen(dataDir) + strlen(PKG_LIB_POSTFIX);
-    if (libdirLen >= PKG_PATH_MAX) {
-        ALOGE("library dir len too large");
+    if (create_pkg_path(pkgdir, pkgname, PKG_DIR_POSTFIX, userId)) {
+        ALOGE("cannot create package path\n");
+        return -1;
+    }
+    if (create_pkg_path(libsymlink, pkgname, PKG_LIB_POSTFIX, userId)) {
+        ALOGE("cannot create package lib symlink origin path\n");
         return -1;
     }
 
-    if (snprintf(libdir, sizeof(libdir), "%s%s", dataDir, PKG_LIB_POSTFIX) != (ssize_t)libdirLen) {
-        ALOGE("library dir not written successfully: %s\n", strerror(errno));
+    if (stat(pkgdir, &s) < 0) return -1;
+
+    if (chown(pkgdir, AID_INSTALL, AID_INSTALL) < 0) {
+        ALOGE("failed to chown '%s': %s\n", pkgdir, strerror(errno));
         return -1;
     }
 
-    if (stat(dataDir, &s) < 0) return -1;
-
-    if (chown(dataDir, AID_INSTALL, AID_INSTALL) < 0) {
-        ALOGE("failed to chown '%s': %s\n", dataDir, strerror(errno));
-        return -1;
-    }
-
-    if (chmod(dataDir, 0700) < 0) {
-        ALOGE("linklib() 1: failed to chmod '%s': %s\n", dataDir, strerror(errno));
+    if (chmod(pkgdir, 0700) < 0) {
+        ALOGE("linklib() 1: failed to chmod '%s': %s\n", pkgdir, strerror(errno));
         rc = -1;
         goto out;
     }
 
-    if (lstat(libdir, &libStat) < 0) {
-        ALOGE("couldn't stat lib dir: %s\n", strerror(errno));
-        rc = -1;
-        goto out;
-    }
-
-    if (S_ISDIR(libStat.st_mode)) {
-        if (delete_dir_contents(libdir, 1, 0) < 0) {
+    if (lstat(libsymlink, &libStat) < 0) {
+        if (errno != ENOENT) {
+            ALOGE("couldn't stat lib dir: %s\n", strerror(errno));
             rc = -1;
             goto out;
         }
-    } else if (S_ISLNK(libStat.st_mode)) {
-        if (unlink(libdir) < 0) {
-            rc = -1;
-            goto out;
+    } else {
+        if (S_ISDIR(libStat.st_mode)) {
+            if (delete_dir_contents(libsymlink, 1, 0) < 0) {
+                rc = -1;
+                goto out;
+            }
+        } else if (S_ISLNK(libStat.st_mode)) {
+            if (unlink(libsymlink) < 0) {
+                ALOGE("couldn't unlink lib dir: %s\n", strerror(errno));
+                rc = -1;
+                goto out;
+            }
         }
     }
 
-    if (symlink(asecLibDir, libdir) < 0) {
-        ALOGE("couldn't symlink directory '%s' -> '%s': %s\n", libdir, asecLibDir, strerror(errno));
-        rc = -errno;
-        goto out;
-    }
-
-    if (lchown(libdir, AID_SYSTEM, AID_SYSTEM) < 0) {
-        ALOGE("cannot chown dir '%s': %s\n", libdir, strerror(errno));
-        unlink(libdir);
+    if (symlink(asecLibDir, libsymlink) < 0) {
+        ALOGE("couldn't symlink directory '%s' -> '%s': %s\n", libsymlink, asecLibDir,
+                strerror(errno));
         rc = -errno;
         goto out;
     }
 
 out:
-    if (chmod(dataDir, s.st_mode) < 0) {
-        ALOGE("linklib() 2: failed to chmod '%s': %s\n", dataDir, strerror(errno));
+    if (chmod(pkgdir, s.st_mode) < 0) {
+        ALOGE("linklib() 2: failed to chmod '%s': %s\n", pkgdir, strerror(errno));
         rc = -errno;
     }
 
-    if (chown(dataDir, s.st_uid, s.st_gid) < 0) {
-        ALOGE("failed to chown '%s' : %s\n", dataDir, strerror(errno));
+    if (chown(pkgdir, s.st_uid, s.st_gid) < 0) {
+        ALOGE("failed to chown '%s' : %s\n", pkgdir, strerror(errno));
         return -errno;
     }