Merge "system/extras/verity: BoringSSL fix."
diff --git a/su/su.c b/su/su.c
index 75d6850..af97173 100644
--- a/su/su.c
+++ b/su/su.c
@@ -16,7 +16,10 @@
 
 #include <errno.h>
 #include <error.h>
+#include <getopt.h>
+#include <paths.h>
 #include <pwd.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -77,35 +80,46 @@
     free(clobberablegids);
 }
 
-/*
- * SU can be given a specific command to exec. UID _must_ be
- * specified for this.
- *
- * Usage:
- *   su 1000
- *   su 1000 ls -l
- *  or
- *   su [uid[,gid[,group1]...] [cmd]]
- *  E.g.
- *  su 1000,shell,net_bw_acct,net_bw_stats id
- * will return
- *  uid=1000(system) gid=2000(shell) groups=3006(net_bw_stats),3007(net_bw_acct)
- */
 int main(int argc, char** argv) {
     uid_t current_uid = getuid();
     if (current_uid != AID_ROOT && current_uid != AID_SHELL) error(1, 0, "not allowed");
 
+    // Handle -h and --help.
+    while (true) {
+        int option_index = 0;
+        static struct option long_options[] = {
+            { "help", no_argument, 0, 'h' },
+            { 0, 0, 0, 0 },
+        };
+
+        int c = getopt_long(argc, argv, "h", long_options, &option_index);
+        if (c == -1) break;
+        switch (c) {
+          case 'h':
+          default:
+            fprintf(stderr,
+                    "usage: su [UID[,GID[,GID2]...]] [COMMAND [ARG...]]\n"
+                    "\n"
+                    "Switch to WHO (default 'root') and run the given command (default sh).\n"
+                    "\n"
+                    "where WHO is a comma-separated list of user, group,\n"
+                    "and supplementary groups in that order.\n"
+                    "\n");
+            return 0;
+        }
+    }
+    // Bump argv to the first non-option argument.
+    argv += optind;
+
     // The default user is root.
     uid_t uid = 0;
     gid_t gid = 0;
 
-    // TODO: use getopt and support at least -- and --help.
-
     // If there are any arguments, the first argument is the uid/gid/supplementary groups.
-    if (argc >= 2) {
+    if (*argv) {
         gid_t gids[10];
         int gids_count = sizeof(gids)/sizeof(gids[0]);
-        extract_uidgids(argv[1], &uid, &gid, gids, &gids_count);
+        extract_uidgids(*argv, &uid, &gid, gids, &gids_count);
         if (gids_count) {
             if (setgroups(gids_count, gids)) {
                 error(1, errno, "setgroups failed");
@@ -117,18 +131,22 @@
     if (setgid(gid)) error(1, errno, "setgid failed");
     if (setuid(uid)) error(1, errno, "setuid failed");
 
-    // TODO: reset $PATH.
+    // Reset parts of the environment.
+    setenv("PATH", _PATH_DEFPATH, 1);
+    unsetenv("IFS");
+    struct passwd* pw = getpwuid(uid);
+    setenv("LOGNAME", pw->pw_name, 1);
+    setenv("USER", pw->pw_name, 1);
 
     // Set up the arguments for exec.
-    char* exec_args[argc];  // Having too much space is fine.
-    memset(exec_args, 0, sizeof(exec_args));
-    // Skip "su" and copy any other args. We already skipped the optional uid above.
-    ++argv;
-    for (size_t i = 0; argv[i] != NULL; ++i) {
-      exec_args[i] = argv[i];
+    char* exec_args[argc + 1];  // Having too much space is fine.
+    size_t i = 0;
+    for (; *argv != NULL; ++i) {
+      exec_args[i] = *argv++;
     }
     // Default to the standard shell.
-    if (!exec_args[0]) exec_args[0] = "/system/bin/sh";
+    if (i == 0) exec_args[i++] = "/system/bin/sh";
+    exec_args[i] = NULL;
 
     execvp(exec_args[0], exec_args);
     error(1, errno, "failed to exec %s", exec_args[0]);
diff --git a/tests/fstest/Android.mk b/tests/fstest/Android.mk
index 7f2bdfc..d607d9b 100644
--- a/tests/fstest/Android.mk
+++ b/tests/fstest/Android.mk
@@ -15,52 +15,13 @@
 LOCAL_PATH := $(call my-dir)
 
 include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := perm_checker.c
-
-LOCAL_SHARED_LIBRARIES := libc
-
-LOCAL_MODULE := perm_checker
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/local
-
-include $(BUILD_EXECUTABLE)
-
-####
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := perm_checker.conf
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE_CLASS := DATA
-
-LOCAL_MODULE_PATH := $(TARGET_OUT_DATA)/local
-
-LOCAL_SRC_FILES := $(LOCAL_MODULE)
-
-include $(BUILD_PREBUILT)
-
-####
-
-include $(CLEAR_VARS)
-
 LOCAL_MODULE_TAGS := tests
-
 LOCAL_MODULE := recovery_test
-
 LOCAL_SRC_FILES := recovery_test.cpp
-
 LOCAL_SHARED_LIBRARIES += libcutils libutils liblog liblogwrap
-
 LOCAL_STATIC_LIBRARIES += libtestUtil libfs_mgr
-
 LOCAL_C_INCLUDES += system/extras/tests/include \
                     system/core/fs_mgr/include \
                     system/extras/ext4_utils \
                     system/core/logwrapper/include
-
 include $(BUILD_NATIVE_TEST)
diff --git a/tests/fstest/README b/tests/fstest/README
deleted file mode 100644
index b328100..0000000
--- a/tests/fstest/README
+++ /dev/null
@@ -1,68 +0,0 @@
-All files and directories will be matched against entries taken from 
-/data/local/perm_checker.conf, and any file/directory which fails the ruleset 
-will cause an error message along with a corresponding explicit (fully 
-specified and minimal) rule for that file/directory to be printed on 
-stdout. If only the message "Passed." is printed on stdout, all files are 
-correctly matched by perm_checker.conf.
-
-A file or directory will always fail the ruleset unless there is AT LEAST 
-one matching rule. If there is an explicit (fully specified) <spec> 
-matching the file or directory name, it will fail if and only if that 
-explicit <spec> rule fails (i.e., other matching <spec> rules will be 
-ignored). Otherwise, it will fail if _any_ matching wildcard or recursive 
-<spec> rule fails to hold.
-
-Entries in the perm_checker.conf file are of the following form:
-
-<spec> <min_mode> <max_mode> <min_uid> <max_uid> <min_gid> <max_gid>
-
-Where <spec> is one of the following:
-
-A fully specified path name, which must end in /         ex: /dev/
-A fully specified filename, symlink, device node, etc.   ex: /dev/tty0
-
-A recursive path specification, which ends in /...       ex: /dev/...
-A wildcard file specification, which ends in *           ex: /dev/tty*
-
-By convention /dev/* will include all files directly in /dev/, but not files 
-that are in subdirectories of /dev/, such as /dev/input/, unlike a 
-recursive path specification. The wildcard notation * will never result in 
-a match to a directory name.
-
-NOTE: Symbolic links are treated specially to prevent infinite recursion
-and simplify the ruleset. Symbolic links are ignored unless an explicit
-rule with the same name as the symlink exists, in which case the permissions
-on the rule must match the permissions on the symlink itself, not the target.
-
-<min_mode> is a numeric mode mask, and a mode will match it if and only if 
-(min_mode & mode) == min_mode.
-
-<max_mode> is a numeric mode mask, and a mode will match it if and only if 
-(max_mode | mode) == max_mode.
-
-<min_uid> may be either a numeric user id, or a user name (which must not 
-start with a number). If it is a user name, getpwnam() will be used to 
-translate it to a numeric user id.
-
-<max_uid>, <min_gid>, and <max_gid> have similar syntax to <min_uid>.
-
-
--- Tips --
-
-I recommend to use 19999 as the maximum uid/gid whenever any valid
-application uid/gid is acceptable.
-
-Once the test is installed, it can be executed via:
-
-adb shell perm_checker
-
-To get a list of all failing rules:
-
-adb shell perm_checker | grep "^# INFO #" | sort | uniq
-
-To get a fully specified set of rules for all failing files:
-
-adb shell perm_checker | grep -v "^#"
-
-NOTE: There may be failing files even if no rules have failed, since a 
-file that does not match any rule is a failure.
diff --git a/tests/fstest/mounts-test.sh b/tests/fstest/mounts-test.sh
deleted file mode 100755
index 1919750..0000000
--- a/tests/fstest/mounts-test.sh
+++ /dev/null
@@ -1,34 +0,0 @@
-#!/bin/sh
-
-rtrn=0
-
-adb shell mount | grep -q /sdcard
-if [ 0 -ne $? ]
-then
-    echo FAILURE: /sdcard is not mounted
-    exit 1
-fi
-
-for i in nosuid noexec
-do
-    adb shell mount | grep /sdcard | grep -q $i
-    if [ 0 -ne $? ]
-    then
-        echo FAILURE: /sdcard is not mounted $i
-        rtrn=$(expr $rtrn + 1)
-    fi
-done
-
-for i in mem kmem
-do
-    adb shell ls /dev/*mem | grep -q $i
-    if [ 0 -ne $? ]
-    then
-        echo FAILURE: $i is present on system
-        rtrn=$(expr $rtrn + 1)
-    fi
-
-done
-
-exit $rtrn
-
diff --git a/tests/fstest/perm_checker.c b/tests/fstest/perm_checker.c
deleted file mode 100644
index e6b2105..0000000
--- a/tests/fstest/perm_checker.c
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-// A simple file permissions checker. See associated README.
-
-#define _GNU_SOURCE
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <ctype.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <errno.h>
-
-#include <sys/stat.h>
-#include <unistd.h>
-#include <time.h>
-
-#include <pwd.h>
-#include <grp.h>
-
-#include <linux/kdev_t.h>
-
-#define DEFAULT_CONFIG_FILE "/data/local/perm_checker.conf"
-
-#define PERMS(M) (M & ~S_IFMT)
-#define MAX_NAME_LEN 4096
-#define MAX_UID_LEN 256
-#define MAX_GID_LEN MAX_UID_LEN
-
-static char *config_file;
-static char *executable_file;
-
-enum perm_rule_type {EXACT_FILE = 0, EXACT_DIR, WILDCARD, RECURSIVE,
-    NUM_PR_TYPES};
-
-struct perm_rule {
-    char *rule_text;
-    int rule_line;
-    char *spec;
-    mode_t min_mode;
-    mode_t max_mode;
-    uid_t min_uid;
-    uid_t max_uid;
-    gid_t min_gid;
-    gid_t max_gid;
-    enum perm_rule_type type;
-    struct perm_rule *next;
-};
-
-typedef struct perm_rule perm_rule_t;
-
-static perm_rule_t *rules[NUM_PR_TYPES];
-
-static uid_t str2uid(char *str, int line_num)
-{
-    struct passwd *pw;
-
-    if (isdigit(str[0]))
-        return (uid_t) atol(str);
-
-    if (!(pw = getpwnam(str))) {
-        printf("# ERROR # Invalid uid '%s' reading line %d\n", str, line_num);
-        exit(255);
-    }
-    return pw->pw_uid;
-}
-
-static gid_t str2gid(char *str, int line_num)
-{
-    struct group *gr;
-
-    if (isdigit(str[0]))
-        return (uid_t) atol(str);
-
-    if (!(gr = getgrnam(str))) {
-        printf("# ERROR # Invalid gid '%s' reading line %d\n", str, line_num);
-        exit(255);
-    }
-    return gr->gr_gid;
-}
-
-static void add_rule(int line_num, char *spec,
-                     unsigned long min_mode, unsigned long max_mode,
-                     char *min_uid_buf, char *max_uid_buf,
-                     char *min_gid_buf, char *max_gid_buf) {
-
-    char rule_text_buf[MAX_NAME_LEN + 2*MAX_UID_LEN + 2*MAX_GID_LEN + 9];
-    perm_rule_t *pr = malloc(sizeof(perm_rule_t));
-    if (!pr) {
-        printf("Out of memory.\n");
-        exit(255);
-    }
-    if (snprintf(rule_text_buf, sizeof(rule_text_buf),
-                 "%s %lo %lo %s %s %s %s", spec, min_mode, max_mode,
-                 min_uid_buf, max_uid_buf, min_gid_buf, max_gid_buf)
-                 >= (long int) sizeof(rule_text_buf)) {
-        // This should never happen, but just in case...
-        printf("# ERROR # Maximum length limits exceeded on line %d\n",
-               line_num);
-        exit(255);
-    }
-    pr->rule_text = strndup(rule_text_buf, sizeof(rule_text_buf));
-    pr->rule_line = line_num;
-    if (strstr(spec, "/...")) {
-        pr->spec = strndup(spec, strlen(spec) - 3);
-        pr->type = RECURSIVE;
-    } else if (spec[strlen(spec) - 1] == '*') {
-        pr->spec = strndup(spec, strlen(spec) - 1);
-        pr->type = WILDCARD;
-    } else if (spec[strlen(spec) - 1] == '/') {
-        pr->spec = strdup(spec);
-        pr->type = EXACT_DIR;
-    } else {
-        pr->spec = strdup(spec);
-        pr->type = EXACT_FILE;
-    }
-    if ((pr->spec == NULL) || (pr->rule_text == NULL)) {
-        printf("Out of memory.\n");
-        exit(255);
-    }
-    pr->min_mode = min_mode;
-    pr->max_mode = max_mode;
-    pr->min_uid = str2uid(min_uid_buf, line_num);
-    pr->max_uid = str2uid(max_uid_buf, line_num);
-    pr->min_gid = str2gid(min_gid_buf, line_num);
-    pr->max_gid = str2gid(max_gid_buf, line_num);
-
-    // Add the rule to the appropriate set
-    pr->next = rules[pr->type];
-    rules[pr->type] = pr;
-#if 0  // Useful for debugging
-    printf("rule #%d: type = %d spec = %s min_mode = %o max_mode = %o "
-           "min_uid = %d max_uid = %d min_gid = %d max_gid = %d\n",
-           num_rules, pr->type, pr->spec, pr->min_mode, pr->max_mode,
-           pr->min_uid, pr->max_uid, pr->min_gid, pr->max_gid);
-#endif
-}
-
-static int read_rules(FILE *fp)
-{
-    char spec[MAX_NAME_LEN + 5];  // Allows for "/..." suffix + terminator
-    char min_uid_buf[MAX_UID_LEN + 1], max_uid_buf[MAX_UID_LEN + 1];
-    char min_gid_buf[MAX_GID_LEN + 1], max_gid_buf[MAX_GID_LEN + 1];
-    unsigned long min_mode, max_mode;
-    int res;
-    int num_rules = 0, num_lines = 0;
-
-    // Note: Use of an unsafe C function here is OK, since this is a test
-    while ((res = fscanf(fp, "%s %lo %lo %s %s %s %s\n", spec,
-                         &min_mode, &max_mode, min_uid_buf, max_uid_buf,
-                         min_gid_buf, max_gid_buf)) != EOF) {
-        num_lines++;
-        if (res < 7) {
-            printf("# WARNING # Invalid rule on line number %d\n", num_lines);
-            continue;
-        }
-        add_rule(num_lines, spec,
-                 min_mode, max_mode,
-                 min_uid_buf, max_uid_buf,
-                 min_gid_buf, max_gid_buf);
-        num_rules++;
-    }
-
-    // Automatically add a rule to match this executable itself
-    add_rule(-1, executable_file,
-             000, 0777,
-             "root", "shell",
-             "root", "shell");
-
-    // Automatically add a rule to match the configuration file
-    add_rule(-1, config_file,
-             000, 0777,
-             "root", "shell",
-             "root", "shell");
-
-    return num_lines - num_rules;
-}
-
-static void print_failed_rule(const perm_rule_t *pr)
-{
-    printf("# INFO # Failed rule #%d: %s\n", pr->rule_line, pr->rule_text);
-}
-
-static void print_new_rule(const char *name, mode_t mode, uid_t uid, gid_t gid)
-{
-    struct passwd *pw;
-    struct group *gr;
-    gr = getgrgid(gid);
-    pw = getpwuid(uid);
-    printf("%s %4o %4o %s %d %s %d\n", name, mode, mode, pw->pw_name, uid,
-           gr->gr_name, gid);
-}
-
-// Returns 1 if the rule passes, prints the failure and returns 0 if not
-static int pass_rule(const perm_rule_t *pr, mode_t mode, uid_t uid, gid_t gid)
-{
-    if (((pr->min_mode & mode) == pr->min_mode) &&
-            ((pr->max_mode | mode) == pr->max_mode) &&
-            (pr->min_gid <= gid) && (pr->max_gid >= gid) &&
-            (pr->min_uid <= uid) && (pr->max_uid >= uid))
-        return 1;
-    print_failed_rule(pr);
-    return 0;
-}
-
-// Returns 0 on success
-static int validate_file(const char *name, mode_t mode, uid_t uid, gid_t gid)
-{
-    perm_rule_t *pr;
-    int rules_matched = 0;
-    int retval = 0;
-
-    pr = rules[EXACT_FILE];
-    while (pr != NULL) {
-        if (strcmp(name, pr->spec) == 0) {
-            if (!pass_rule(pr, mode, uid, gid))
-                retval++;
-            else
-                rules_matched++;  // Exact match found
-        }
-        pr = pr->next;
-    }
-
-    if ((retval + rules_matched) > 1)
-        printf("# WARNING # Multiple exact rules for file: %s\n", name);
-
-    // If any exact rule matched or failed, we are done with this file
-    if (retval)
-        print_new_rule(name, mode, uid, gid);
-    if (rules_matched || retval)
-        return retval;
-
-    pr = rules[WILDCARD];
-    while (pr != NULL) {
-        // Check if the spec is a prefix of the filename, and that the file
-        // is actually in the same directory as the wildcard.
-        if ((strstr(name, pr->spec) == name) &&
-                (!strchr(name + strlen(pr->spec), '/'))) {
-            if (!pass_rule(pr, mode, uid, gid))
-                retval++;
-            else
-                rules_matched++;
-        }
-        pr = pr->next;
-    }
-
-    pr = rules[RECURSIVE];
-    while (pr != NULL) {
-        if (strstr(name, pr->spec) == name) {
-            if (!pass_rule(pr, mode, uid, gid))
-                retval++;
-            else
-                rules_matched++;
-        }
-        pr = pr->next;
-    }
-
-    if (!rules_matched)
-        retval++;  // In case no rules either matched or failed, be sure to fail
-
-    if (retval)
-        print_new_rule(name, mode, uid, gid);
-
-    return retval;
-}
-
-// Returns 0 on success
-static int validate_link(const char *name, mode_t mode, uid_t uid, gid_t gid)
-{
-    perm_rule_t *pr;
-    int rules_matched = 0;
-    int retval = 0;
-
-    // For now, we match links against "exact" file rules only
-    pr = rules[EXACT_FILE];
-    while (pr != NULL) {
-        if (strcmp(name, pr->spec) == 0) {
-            if (!pass_rule(pr, mode, uid, gid))
-                retval++;
-            else
-                rules_matched++;  // Exact match found
-        }
-        pr = pr->next;
-    }
-
-    if ((retval + rules_matched) > 1)
-        printf("# WARNING # Multiple exact rules for link: %s\n", name);
-    if (retval)
-        print_new_rule(name, mode, uid, gid);
-
-    // Note: Unlike files, if no rules matches for links, retval = 0 (success).
-    return retval;
-}
-
-// Returns 0 on success
-static int validate_dir(const char *name, mode_t mode, uid_t uid, gid_t gid)
-{
-    perm_rule_t *pr;
-    int rules_matched = 0;
-    int retval = 0;
-
-    pr = rules[EXACT_DIR];
-    while (pr != NULL) {
-        if (strcmp(name, pr->spec) == 0) {
-            if (!pass_rule(pr, mode, uid, gid))
-                retval++;
-            else
-                rules_matched++;  // Exact match found
-        }
-        pr = pr->next;
-    }
-
-    if ((retval + rules_matched) > 1)
-        printf("# WARNING # Multiple exact rules for directory: %s\n", name);
-
-    // If any exact rule matched or failed, we are done with this directory
-    if (retval)
-        print_new_rule(name, mode, uid, gid);
-    if (rules_matched || retval)
-        return retval;
-
-    pr = rules[RECURSIVE];
-    while (pr != NULL) {
-        if (strstr(name, pr->spec) == name) {
-            if (!pass_rule(pr, mode, uid, gid))
-                retval++;
-            else
-                rules_matched++;
-        }
-        pr = pr->next;
-    }
-
-    if (!rules_matched)
-        retval++;  // In case no rules either matched or failed, be sure to fail
-
-    if (retval)
-        print_new_rule(name, mode, uid, gid);
-
-    return retval;
-}
-
-// Returns 0 on success
-static int check_path(const char *name)
-{
-    char namebuf[MAX_NAME_LEN + 1];
-    char tmp[MAX_NAME_LEN + 1];
-    DIR *d;
-    struct dirent *de;
-    struct stat s;
-    int err;
-    int retval = 0;
-
-    err = lstat(name, &s);
-    if (err < 0) {
-        if (errno != ENOENT)
-        {
-            perror(name);
-            return 1;
-        }
-        return 0;  // File doesn't exist anymore
-    }
-
-    if (S_ISDIR(s.st_mode)) {
-        if (name[strlen(name) - 1] != '/')
-            snprintf(namebuf, sizeof(namebuf), "%s/", name);
-        else
-            snprintf(namebuf, sizeof(namebuf), "%s", name);
-
-        retval |= validate_dir(namebuf, PERMS(s.st_mode), s.st_uid, s.st_gid);
-        d = opendir(namebuf);
-        if(d == 0) {
-            printf("%s : opendir failed: %s\n", namebuf, strerror(errno));
-            return 1;
-        }
-
-        while ((de = readdir(d)) != 0) {
-            if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))
-                continue;
-            snprintf(tmp, sizeof(tmp), "%s%s", namebuf, de->d_name);
-            retval |= check_path(tmp);
-        }
-        closedir(d);
-        return retval;
-    } else if (S_ISLNK(s.st_mode)) {
-        return validate_link(name, PERMS(s.st_mode), s.st_uid, s.st_gid);
-    } else {
-        return validate_file(name, PERMS(s.st_mode), s.st_uid, s.st_gid);
-    }
-}
-
-int main(int argc, char **argv)
-{
-    FILE *fp;
-    int i;
-
-    if (argc > 2) {
-      printf("\nSyntax: %s [configfilename]\n", argv[0]);
-    }
-    config_file = (argc == 2) ? argv[1] : DEFAULT_CONFIG_FILE;
-    executable_file = argv[0];
-
-    // Initialize ruleset pointers
-    for (i = 0; i < NUM_PR_TYPES; i++)
-        rules[i] = NULL;
-
-    if (!(fp = fopen(config_file, "r"))) {
-        printf("Error opening %s\n", config_file);
-        exit(255);
-    }
-    read_rules(fp);
-    fclose(fp);
-
-    if (check_path("/"))
-        return 255;
-
-    printf("Passed.\n");
-    return 0;
-}
diff --git a/tests/fstest/perm_checker.conf b/tests/fstest/perm_checker.conf
deleted file mode 100644
index b4dd1e8..0000000
--- a/tests/fstest/perm_checker.conf
+++ /dev/null
@@ -1,163 +0,0 @@
-/ 755 755 root root root root
-/* 400 755 root root root root
-/cache/ 770 770 system system cache cache
-/cache/... 770 770 system system cache cache
-/cache/lost+found/ 700 770 root root root root
-/d/ 755 755 root root root root
-/d/... 000 770 root root root root
-/data/ 771 771 system system system system
-/data/* 000 744 system system system system
-/data/anr/ 000 751 root system log log
-/data/anr/... 000 662 root system log log
-/data/app/ 771 771 system system system system
-/data/app/... 644 664 system system system system
-/data/app-private/ 700 771 system system system system
-/data/dalvik-cache/ 750 771 root system root system
-/data/dalvik-cache/... 400 744 root 19999 root 19999
-/data/data 701 771 system system system system
-/data/data/... 000 775 system 19999 system 19999
-/data/local/ 751 751 root root root root
-/data/local/tmp/ 771 771 shell shell shell shell
-/data/lost+found/ 700 770 root root root root
-/data/misc/ 1711 1771 root system root misc
-/data/misc/akmd_set.txt 600 640 root compass compass compass
-/data/misc/rild* 600 660 root radio root radio
-/data/misc/dhcp/ 700 770 root dhcp dhcp dhcp
-/data/misc/dhcp/... 000 660 root dhcp dhcp dhcp
-/data/misc/hcid/ 700 770 root bluetooth bluetooth bluetooth
-/data/misc/hcid/... 600 770 root bluetooth bluetooth bluetooth
-/data/misc/wifi/ 000 1771 system wifi system wifi
-/data/misc/wifi/... 000 770 root wifi root wifi
-/data/property/ 700 770 root root root root
-/data/property/... 600 660 root root root root
-/data/system/ 000 775 system system system system
-/data/system/... 000 774 system system system system
-/data/testinfo/ 770 771 root system root system
-/data/testinfo/* 000 664 root system root system
-/data/tombstones/ 755 755 system system system system
-/data/tombstones/* 000 600 system 19999 system 19999
-/dev/ 755 755 root root root root
-/dev/alarm 600 664 root radio root radio
-/dev/ashmem 666 666 root root root root
-/dev/android_adb 600 660 root adb root adb
-/dev/android_adb_enable 600 660 root adb root adb
-/dev/android_ums 640 640 mount mount mount mount
-/dev/binder 666 666 root root root root
-/dev/console 600 600 root root root root
-/dev/full 666 666 root root root root
-/dev/hw3d 660 660 system system graphics graphics
-/dev/htc-acoustic 600 640 radio radio radio radio
-/dev/network_throughput 600 660 root system root system
-/dev/network_latency 600 660 root system root system
-/dev/cpu_dma_latency 600 660 root system root system
-/dev/mem 600 600 root root root root
-/dev/msm_mp3 600 660 root system root audio
-/dev/msm_pcm_ctl 660 660 system system audio audio
-/dev/msm_pcm_in 660 660 system system audio audio
-/dev/msm_pcm_out 660 660 system system audio audio
-/dev/msm_perf 600 600 root root root root
-/dev/null 666 666 root root root root
-/dev/pmem 660 660 system system graphics graphics
-/dev/pmem_adsp 660 660 system system audio audio
-/dev/pmem_camera 600 660 root system root camera
-/dev/ppp 660 660 radio radio vpn vpn
-/dev/psaux 600 600 root root root root
-/dev/ptmx 666 666 root root root root
-/dev/random 666 666 root root root root
-/dev/smd0 640 640 radio radio radio radio
-/dev/ttyMSM0 600 600 bluetooth bluetooth bluetooth bluetooth
-/dev/urandom 666 666 root root root root
-/dev/zero 666 666 root root root root
-/dev/akm* 640 640 compass compass system system
-/dev/km* 600 600 root root root root
-/dev/mt9* 600 660 system system system system
-/dev/pmem_gpu* 660 660 system system graphics graphics
-/dev/qmi* 600 640 radio radio radio radio
-/dev/rtc* 600 600 root root root root
-/dev/smd* 600 600 root root root root
-/dev/tty* 600 600 root root root root
-/dev/vc* 600 600 root root root root
-/dev/adsp/ 750 755 root root root root
-/dev/adsp/* 660 660 system system audio audio
-/dev/block/ 750 775 root root root root
-/dev/block/* 600 600 root root root root
-/dev/graphics/ 755 755 root root root root
-/dev/graphics/* 660 660 root root graphics graphics
-/dev/input/ 755 755 root root root root
-/dev/input/* 660 660 root root input input
-/dev/log/ 755 755 root root root root
-/dev/log/* 662 662 root root log log
-/dev/oncrpc/ 755 755 root root root root
-/dev/oncrpc/... 000 660 root camera root camera
-/dev/pts/ 755 755 root root root root
-/dev/pts/* 600 600 root shell root shell
-/dev/mtd/ 750 775 root root root root
-/dev/mtd/mtd0 460 460 radio radio diag diag
-/dev/mtd/* 600 600 root root root root
-/dev/socket/ 750 755 root system root system
-/dev/socket/bluetooth 600 660 root bluetooth bluetooth bluetooth
-/dev/socket/dbus 660 660 root bluetooth bluetooth bluetooth
-/dev/socket/dbus_bluetooth 600 660 root bluetooth bluetooth bluetooth
-/dev/socket/installd 600 660 system system system system
-/dev/socket/logd 666 666 logd logd logd logd
-/dev/socket/logdr 666 666 logd logd logd logd
-/dev/socket/logdw 222 222 logd logd logd logd
-/dev/socket/mountd 660 660 root mount root mount
-/dev/socket/property_service 666 666 root system root system
-/dev/socket/rild 660 660 root radio root radio
-/dev/socket/rild-debug 660 660 root radio root radio
-/dev/socket/usbd 660 660 root mount mount mount
-/dev/socket/wpa_* 600 660 root wifi wifi wifi
-/dev/socket/zygote 666 666 root root root root
-/etc 777 777 root root root root
-/proc/ 555 555 root root root root
-/proc/... 000 777 root 19999 root 19999
-/proc/sys/kernel/sched_nr_migrate 000 1664 root root root root
-/root/ 700 700 root root root root
-/sdcard/ 000 077 system system system system
-/sdcard/... 000 077 system system system system
-/sbin/ 700 770 root root root root
-/sbin/... 700 775 root root root root
-/sys/ 755 775 root system root system
-/sys/... 000 775 root system root system
-/sys/android_power/acquire_full_wake_lock 664 664 radio radio system system
-/sys/android_power/acquire_partial_wake_lock 664 664 radio radio system system
-/sys/android_power/release_wake_lock 664 664 radio radio system system
-/sys/android_power/request_state 664 664 radio radio system system
-/sys/android_power/state 664 664 radio radio system system
-/sys/module/board_trout/parameters/bluetooth_power_on 660 660 root bluetooth bluetooth bluetooth
-/sys/qemu_trace/process_name 000 777 root system root system
-/sys/qemu_trace/state 000 777 root system root system
-/sys/qemu_trace/symbol 000 777 root system root system
-/system/ 755 755 root root root root
-/system/* 000 664 root system root system
-/system/app/ 755 755 root root root root
-/system/app/... 600 644 root root root root
-/system/bin/... 000 755 root shell root shell
-/system/bin/netcfg 000 2750 root root inet inet
-/system/bin/ping 000 2755 root root net_raw net_raw
-/system/etc/ 755 755 root root root root
-/system/etc/... 000 664 root bluetooth root audio
-/system/etc/firmware/ 700 755 root root root root
-/system/etc/init.goldfish.sh 500 550 root root root shell
-/system/etc/init.gprs-pppd 500 550 root root root shell
-/system/etc/ppp/ 755 755 root root root root
-/system/etc/ppp/* 555 555 root root root root
-/system/etc/security/ 755 755 root root root root
-/system/etc/wifi/ 750 755 root system root system
-/system/lib/ 755 755 root root root root
-/system/lib/... 600 644 root root root root
-/system/lib/modules/ 755 755 root root root root
-/system/lost+found/ 700 770 root root root root
-/system/fonts/ 755 755 root root root root
-/system/fonts/... 644 644 root root root root
-/system/framework/ 755 755 root root root root
-/system/framework/... 600 644 root root root root
-/system/media/ 755 755 root root root root
-/system/media/... 644 644 root root root root
-/system/media/audio/ 755 755 root root root root
-/system/media/audio/notifications/ 755 755 root root root root
-/system/media/audio/ringtones/ 755 755 root root root root
-/system/sounds/ 755 755 root root root root
-/system/sounds/... 644 644 root root root root
-/system/usr/... 400 755 root root root root
diff --git a/verity/build_verity_tree.cpp b/verity/build_verity_tree.cpp
index 1281c6a..5e04ce5 100644
--- a/verity/build_verity_tree.cpp
+++ b/verity/build_verity_tree.cpp
@@ -9,6 +9,7 @@
 #include <getopt.h>
 #include <fcntl.h>
 #include <inttypes.h>
+#include <limits.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -126,7 +127,7 @@
     size_t salt_size = 0;
     bool sparse = false;
     size_t block_size = 4096;
-    size_t calculate_size = 0;
+    uint64_t calculate_size = 0;
 
     while (1) {
         const static struct option long_options[] = {
@@ -135,6 +136,7 @@
             {"help", no_argument, 0, 'h'},
             {"sparse", no_argument, 0, 'S'},
             {"verity-size", required_argument, 0, 's'},
+            {NULL, 0, 0, 0}
         };
         int c = getopt_long(argc, argv, "a:A:hSs:", long_options, NULL);
         if (c < 0) {
@@ -171,8 +173,19 @@
         case 'S':
             sparse = true;
             break;
-        case 's':
-            calculate_size = strtoul(optarg, NULL, 0);
+        case 's': {
+                char* endptr;
+                errno = 0;
+                unsigned long long int inSize = strtoull(optarg, &endptr, 0);
+                if (optarg[0] == '\0' || *endptr != '\0' ||
+                        (errno == ERANGE && inSize == ULLONG_MAX)) {
+                    FATAL("invalid value of verity-size\n");
+                }
+                if (inSize > UINT64_MAX) {
+                    FATAL("invalid value of verity-size\n");
+                }
+                calculate_size = (uint64_t)inSize;
+            }
             break;
         case '?':
             usage();
@@ -226,7 +239,7 @@
             verity_blocks += level_blocks;
         } while (level_blocks > 1);
 
-        printf("%zu\n", verity_blocks * block_size);
+        printf("%" PRIu64 "\n", (uint64_t)verity_blocks * block_size);
         return 0;
     }