am cf4c3191: fastboot: add the support of the second stage image

* commit 'cf4c319115fe019b61ff318d0e758398e1c4cfe9':
  fastboot: add the support of the second stage image
diff --git a/gatekeeperd/tests/gatekeeper_test.cpp b/gatekeeperd/tests/gatekeeper_test.cpp
index 15b2b69..47a8bfa 100644
--- a/gatekeeperd/tests/gatekeeper_test.cpp
+++ b/gatekeeperd/tests/gatekeeper_test.cpp
@@ -14,11 +14,12 @@
  * limitations under the License.
  */
 
-#include <gtest/gtest.h>
-#include <UniquePtr.h>
+#include <arpa/inet.h>
 #include <iostream>
 
+#include <gtest/gtest.h>
 #include <hardware/hw_auth_token.h>
+#include <UniquePtr.h>
 
 #include "../SoftGateKeeper.h"
 
diff --git a/init/builtins.cpp b/init/builtins.cpp
index ca31c50..58e9087 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -839,18 +839,31 @@
     return 0;
 }
 
+static bool is_file_crypto() {
+    char prop_value[PROP_VALUE_MAX] = {0};
+    property_get("ro.crypto.type", prop_value);
+    return strcmp(prop_value, "file") == 0;
+}
+
 int do_installkey(int nargs, char **args)
 {
     if (nargs != 2) {
         return -1;
     }
-
-    char prop_value[PROP_VALUE_MAX] = {0};
-    property_get("ro.crypto.type", prop_value);
-    if (strcmp(prop_value, "file")) {
+    if (!is_file_crypto()) {
         return 0;
     }
-
     return e4crypt_create_device_key(args[1],
                                      do_installkeys_ensure_dir_exists);
 }
+
+int do_setusercryptopolicies(int nargs, char **args)
+{
+    if (nargs != 2) {
+        return -1;
+    }
+    if (!is_file_crypto()) {
+        return 0;
+    }
+    return e4crypt_set_user_crypto_policies(args[1]);
+}
diff --git a/init/init_parser.cpp b/init/init_parser.cpp
index f975b6c..358d6d4 100644
--- a/init/init_parser.cpp
+++ b/init/init_parser.cpp
@@ -187,6 +187,7 @@
         if (!strcmp(s, "etenv")) return K_setenv;
         if (!strcmp(s, "etprop")) return K_setprop;
         if (!strcmp(s, "etrlimit")) return K_setrlimit;
+        if (!strcmp(s, "etusercryptopolicies")) return K_setusercryptopolicies;
         if (!strcmp(s, "ocket")) return K_socket;
         if (!strcmp(s, "tart")) return K_start;
         if (!strcmp(s, "top")) return K_stop;
diff --git a/init/keywords.h b/init/keywords.h
index 37f01b8..04229f2 100644
--- a/init/keywords.h
+++ b/init/keywords.h
@@ -22,6 +22,7 @@
 int do_rmdir(int nargs, char **args);
 int do_setprop(int nargs, char **args);
 int do_setrlimit(int nargs, char **args);
+int do_setusercryptopolicies(int nargs, char **args);
 int do_start(int nargs, char **args);
 int do_stop(int nargs, char **args);
 int do_swapon_all(int nargs, char **args);
@@ -78,6 +79,7 @@
     KEYWORD(setenv,      OPTION,  2, 0)
     KEYWORD(setprop,     COMMAND, 2, do_setprop)
     KEYWORD(setrlimit,   COMMAND, 3, do_setrlimit)
+    KEYWORD(setusercryptopolicies,   COMMAND, 1, do_setusercryptopolicies)
     KEYWORD(socket,      OPTION,  0, 0)
     KEYWORD(start,       COMMAND, 1, do_start)
     KEYWORD(stop,        COMMAND, 1, do_stop)
diff --git a/rootdir/init.rc b/rootdir/init.rc
index ec30ac8..d5fb6d4 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -236,6 +236,7 @@
 
     # Emulated internal storage area
     mkdir /data/media 0770 media_rw media_rw
+
     # Start bootcharting as soon as possible after the data partition is
     # mounted to collect more data.
     mkdir /data/bootchart 0755 shell shell
@@ -270,6 +271,7 @@
     chmod 0660 /data/misc/wifi/wpa_supplicant.conf
     mkdir /data/local 0751 root root
     mkdir /data/misc/media 0700 media media
+    mkdir /data/misc/vold 0700 root root
 
     # For security reasons, /data/local/tmp should always be empty.
     # Do not place files or directories in /data/local/tmp
@@ -319,6 +321,8 @@
     mkdir /data/system/heapdump 0700 system system
     mkdir /data/user 0711 system system
 
+    setusercryptopolicies /data/user
+
     # Reload policy from /data/security if present.
     setprop selinux.reload_policy 1
 
diff --git a/run-as/package.c b/run-as/package.c
index 9e1f5bb..aea89e5 100644
--- a/run-as/package.c
+++ b/run-as/package.c
@@ -16,6 +16,7 @@
 */
 #include <errno.h>
 #include <fcntl.h>
+#include <stdio.h>
 #include <string.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
@@ -421,7 +422,7 @@
  * If the package database is corrupted, return -1 and set errno to EINVAL
  */
 int
-get_package_info(const char* pkgName, PackageInfo *info)
+get_package_info(const char* pkgName, uid_t userId, PackageInfo *info)
 {
     char*        buffer;
     size_t       buffer_len;
@@ -506,7 +507,20 @@
         if (q == p)
             goto BAD_FORMAT;
 
-        p = string_copy(info->dataDir, sizeof info->dataDir, p, q - p);
+        /* If userId == 0 (i.e. user is device owner) we can use dataDir value
+         * from packages.list, otherwise compose data directory as
+         * /data/user/$uid/$packageId
+         */
+        if (userId == 0) {
+            p = string_copy(info->dataDir, sizeof info->dataDir, p, q - p);
+        } else {
+            snprintf(info->dataDir,
+                     sizeof info->dataDir,
+                     "/data/user/%d/%s",
+                     userId,
+                     pkgName);
+            p = q;
+        }
 
         /* skip spaces */
         if (parse_spaces(&p, end) < 0)
diff --git a/run-as/package.h b/run-as/package.h
index 34603c0..eeb5913 100644
--- a/run-as/package.h
+++ b/run-as/package.h
@@ -33,9 +33,11 @@
     char   seinfo[PATH_MAX];
 } PackageInfo;
 
-/* see documentation in package.c for these functiosn */
+/* see documentation in package.c for these functions */
 
-extern int  get_package_info(const char* packageName, PackageInfo*  info);
+extern int  get_package_info(const char* packageName,
+                             uid_t userId,
+                             PackageInfo*  info);
 
 extern int  check_data_path(const char* dataDir, uid_t uid);
 
diff --git a/run-as/run-as.c b/run-as/run-as.c
index 368b8f1..3f32e7d 100644
--- a/run-as/run-as.c
+++ b/run-as/run-as.c
@@ -102,13 +102,14 @@
 static void
 usage(void)
 {
-    panic("Usage:\n    " PROGNAME " <package-name> <command> [<args>]\n");
+    panic("Usage:\n    " PROGNAME " <package-name> [--user <uid>] <command> [<args>]\n");
 }
 
 int main(int argc, char **argv)
 {
     const char* pkgname;
-    int myuid, uid, gid;
+    uid_t myuid, uid, gid, userAppId = 0;
+    int commandArgvOfs = 2, userId = 0;
     PackageInfo info;
     struct __user_cap_header_struct capheader;
     struct __user_cap_data_struct capdata[2];
@@ -136,14 +137,31 @@
         panic("Could not set capabilities: %s\n", strerror(errno));
     }
 
-    /* retrieve package information from system (does setegid) */
     pkgname = argv[1];
-    if (get_package_info(pkgname, &info) < 0) {
+
+    /* get user_id from command line if provided */
+    if ((argc >= 4) && !strcmp(argv[2], "--user")) {
+        userId = atoi(argv[3]);
+        if (userId < 0)
+            panic("Negative user id %d is provided\n", userId);
+        commandArgvOfs += 2;
+    }
+
+    /* retrieve package information from system (does setegid) */
+    if (get_package_info(pkgname, userId, &info) < 0) {
         panic("Package '%s' is unknown\n", pkgname);
     }
 
+    /* verify that user id is not too big. */
+    if ((UID_MAX - info.uid) / AID_USER < (uid_t)userId) {
+        panic("User id %d is too big\n", userId);
+    }
+
+    /* calculate user app ID. */
+    userAppId = (AID_USER * userId) + info.uid;
+
     /* reject system packages */
-    if (info.uid < AID_APP) {
+    if (userAppId < AID_APP) {
         panic("Package '%s' is not an application\n", pkgname);
     }
 
@@ -153,14 +171,14 @@
     }
 
     /* check that the data directory path is valid */
-    if (check_data_path(info.dataDir, info.uid) < 0) {
+    if (check_data_path(info.dataDir, userAppId) < 0) {
         panic("Package '%s' has corrupt installation\n", pkgname);
     }
 
     /* Ensure that we change all real/effective/saved IDs at the
      * same time to avoid nasty surprises.
      */
-    uid = gid = info.uid;
+    uid = gid = userAppId;
     if(setresgid(gid,gid,gid) || setresuid(uid,uid,uid)) {
         panic("Permission denied\n");
     }
@@ -181,8 +199,9 @@
     }
 
     /* User specified command for exec. */
-    if ((argc >= 3) && (execvp(argv[2], argv+2) < 0)) {
-        panic("exec failed for %s: %s\n", argv[2], strerror(errno));
+    if ((argc >= commandArgvOfs + 1) &&
+        (execvp(argv[commandArgvOfs], argv+commandArgvOfs) < 0)) {
+        panic("exec failed for %s: %s\n", argv[commandArgvOfs], strerror(errno));
     }
 
     /* Default exec shell. */