adb: Do not use fs_config unless we are root (try 3).

This enables fs_config for /data when pushing files as root. Also,
without this, adb push to /tmp fails as the shell user.

When pushing to a directory that does not have an explicit
fs_config, such as /data/local/tmp or /tmp, use the original
file mode. Because adb copies u permissions into g and o
(and in general because the umask on the host may have
made these files world writable), this requires adding more
fs_config entries to cover directories that may contain dex files
i.e. /{odm,product,system,system_ext,vendor}/{framework,app,priv-app}
to avoid hitting a SecurityException caused by writable dex files, e.g.

04-01 21:22:16.980 10110  4815  4815 E AndroidRuntime: FATAL EXCEPTION: main
04-01 21:22:16.980 10110  4815  4815 E AndroidRuntime: Process: android.test.app.system_priv, PID: 4815
04-01 21:22:16.980 10110  4815  4815 E AndroidRuntime: java.lang.SecurityException: Writable dex file '/system/priv-app/loadlibrarytest_system_priv_app/loadlibrarytest_system_priv_app.apk' is not allowed.
04-01 21:22:16.980 10110  4815  4815 E AndroidRuntime:  at dalvik.system.DexFile.openDexFileNative(Native Method)
04-01 21:22:16.980 10110  4815  4815 E AndroidRuntime:  at dalvik.system.DexFile.openDexFile(DexFile.java:406)

Bug: 171233429
Bug: 311263616
Change-Id: I18f70095c793d08a25ff59e1851f6dc7648ce4dc
diff --git a/libcutils/fs_config.cpp b/libcutils/fs_config.cpp
index 919be2f..5efe209 100644
--- a/libcutils/fs_config.cpp
+++ b/libcutils/fs_config.cpp
@@ -91,7 +91,7 @@
     { 00751, AID_ROOT,         AID_SHELL,        0, "vendor/bin" },
     { 00751, AID_ROOT,         AID_SHELL,        0, "vendor/apex/*/bin" },
     { 00755, AID_ROOT,         AID_SHELL,        0, "vendor" },
-    { 00755, AID_ROOT,         AID_ROOT,         0, 0 },
+    {},
         // clang-format on
 };
 #ifndef __ANDROID_VNDK__
@@ -218,17 +218,32 @@
     { 00640, AID_ROOT,      AID_SHELL,     0, "fstab.*" },
     { 00750, AID_ROOT,      AID_SHELL,     0, "init*" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "odm/bin/*" },
+    { 00644, AID_ROOT,      AID_ROOT,      0, "odm/framework/*" },
+    { 00644, AID_ROOT,      AID_ROOT,      0, "odm/app/*" },
+    { 00644, AID_ROOT,      AID_ROOT,      0, "odm/priv-app/*" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "product/bin/*" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "product/apex/*bin/*" },
+    { 00644, AID_ROOT,      AID_ROOT,      0, "product/framework/*" },
+    { 00644, AID_ROOT,      AID_ROOT,      0, "product/app/*" },
+    { 00644, AID_ROOT,      AID_ROOT,      0, "product/priv-app/*" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "system/bin/*" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "system/xbin/*" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "system/apex/*/bin/*" },
+    { 00644, AID_ROOT,      AID_ROOT,      0, "system/framework/*" },
+    { 00644, AID_ROOT,      AID_ROOT,      0, "system/app/*" },
+    { 00644, AID_ROOT,      AID_ROOT,      0, "system/priv-app/*" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "system_ext/bin/*" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "system_ext/apex/*/bin/*" },
+    { 00644, AID_ROOT,      AID_ROOT,      0, "system_ext/framework/*" },
+    { 00644, AID_ROOT,      AID_ROOT,      0, "system_ext/app/*" },
+    { 00644, AID_ROOT,      AID_ROOT,      0, "system_ext/priv-app/*" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "vendor/bin/*" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "vendor/apex/*bin/*" },
     { 00755, AID_ROOT,      AID_SHELL,     0, "vendor/xbin/*" },
-    { 00644, AID_ROOT,      AID_ROOT,      0, 0 },
+    { 00644, AID_ROOT,      AID_ROOT,      0, "vendor/framework/*" },
+    { 00644, AID_ROOT,      AID_ROOT,      0, "vendor/app/*" },
+    { 00644, AID_ROOT,      AID_ROOT,      0, "vendor/priv-app/*" },
+    {},
         // clang-format on
 };
 #ifndef __ANDROID_VNDK__
@@ -318,8 +333,8 @@
 auto __for_testing_only__fs_config_cmp = fs_config_cmp;
 #endif
 
-void fs_config(const char* path, int dir, const char* target_out_path, unsigned* uid, unsigned* gid,
-               unsigned* mode, uint64_t* capabilities) {
+bool get_fs_config(const char* path, bool dir, const char* target_out_path,
+                   struct fs_config* fs_conf) {
     const struct fs_path_config* pc;
     size_t which, plen;
 
@@ -362,11 +377,11 @@
             if (fs_config_cmp(dir, prefix, len, path, plen)) {
                 free(prefix);
                 close(fd);
-                *uid = header.uid;
-                *gid = header.gid;
-                *mode = (*mode & (~07777)) | header.mode;
-                *capabilities = header.capabilities;
-                return;
+                fs_conf->uid = header.uid;
+                fs_conf->gid = header.gid;
+                fs_conf->mode = header.mode;
+                fs_conf->capabilities = header.capabilities;
+                return true;
             }
             free(prefix);
         }
@@ -375,11 +390,28 @@
 
     for (pc = dir ? android_dirs : android_files; pc->prefix; pc++) {
         if (fs_config_cmp(dir, pc->prefix, strlen(pc->prefix), path, plen)) {
-            break;
+            fs_conf->uid = pc->uid;
+            fs_conf->gid = pc->gid;
+            fs_conf->mode = pc->mode;
+            fs_conf->capabilities = pc->capabilities;
+            return true;
         }
     }
-    *uid = pc->uid;
-    *gid = pc->gid;
-    *mode = (*mode & (~07777)) | pc->mode;
-    *capabilities = pc->capabilities;
+    return false;
+}
+
+void fs_config(const char* path, int dir, const char* target_out_path, unsigned* uid, unsigned* gid,
+               unsigned* mode, uint64_t* capabilities) {
+    struct fs_config conf;
+    if (get_fs_config(path, dir, target_out_path, &conf)) {
+        *uid = conf.uid;
+        *gid = conf.gid;
+        *mode = (*mode & S_IFMT) | conf.mode;
+        *capabilities = conf.capabilities;
+    } else {
+        *uid = AID_ROOT;
+        *gid = AID_ROOT;
+        *mode = (*mode & S_IFMT) | (dir ? 0755 : 0644);
+        *capabilities = 0;
+    }
 }