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
This commit is contained in:
Peter Collingbourne 2024-02-27 19:37:41 -08:00
parent d49456a11f
commit 4a57c8f4f2
4 changed files with 197 additions and 24 deletions

View file

@ -289,6 +289,9 @@
{
"name" : "fs_write_atomic_int"
},
{
"name" : "get_fs_config"
},
{
"name" : "hashmapCreate"
},
@ -1273,6 +1276,27 @@
"return_type" : "_ZTIi",
"source_file" : "system/core/libcutils/include/cutils/fs.h"
},
{
"function_name" : "get_fs_config",
"linker_set_key" : "get_fs_config",
"parameters" :
[
{
"referenced_type" : "_ZTIPKc"
},
{
"referenced_type" : "_ZTIb"
},
{
"referenced_type" : "_ZTIPKc"
},
{
"referenced_type" : "_ZTIP9fs_config"
}
],
"return_type" : "_ZTIb",
"source_file" : "system/core/libcutils/include/private/fs_config.h"
},
{
"function_name" : "hashmapCreate",
"linker_set_key" : "hashmapCreate",
@ -2390,6 +2414,15 @@
"size" : 8,
"source_file" : "system/core/libcutils/include/cutils/hashmap.h"
},
{
"alignment" : 8,
"linker_set_key" : "_ZTIP9fs_config",
"name" : "fs_config *",
"referenced_type" : "_ZTI9fs_config",
"self_type" : "_ZTIP9fs_config",
"size" : 8,
"source_file" : "system/core/libcutils/include/private/fs_config.h"
},
{
"alignment" : 8,
"linker_set_key" : "_ZTIP9str_parms",
@ -2684,6 +2717,37 @@
"self_type" : "_ZTI5cnode",
"size" : 40,
"source_file" : "system/core/libcutils/include/cutils/config_utils.h"
},
{
"alignment" : 8,
"fields" :
[
{
"field_name" : "uid",
"referenced_type" : "_ZTIj"
},
{
"field_name" : "gid",
"field_offset" : 32,
"referenced_type" : "_ZTIj"
},
{
"field_name" : "mode",
"field_offset" : 64,
"referenced_type" : "_ZTIj"
},
{
"field_name" : "capabilities",
"field_offset" : 128,
"referenced_type" : "_ZTIm"
}
],
"linker_set_key" : "_ZTI9fs_config",
"name" : "fs_config",
"referenced_type" : "_ZTI9fs_config",
"self_type" : "_ZTI9fs_config",
"size" : 24,
"source_file" : "system/core/libcutils/include/private/fs_config.h"
}
],
"rvalue_reference_types" : []

View file

@ -299,6 +299,9 @@
{
"name" : "fs_write_atomic_int"
},
{
"name" : "get_fs_config"
},
{
"name" : "hashmapCreate"
},
@ -1283,6 +1286,27 @@
"return_type" : "_ZTIi",
"source_file" : "system/core/libcutils/include/cutils/fs.h"
},
{
"function_name" : "get_fs_config",
"linker_set_key" : "get_fs_config",
"parameters" :
[
{
"referenced_type" : "_ZTIPKc"
},
{
"referenced_type" : "_ZTIb"
},
{
"referenced_type" : "_ZTIPKc"
},
{
"referenced_type" : "_ZTIP9fs_config"
}
],
"return_type" : "_ZTIb",
"source_file" : "system/core/libcutils/include/private/fs_config.h"
},
{
"function_name" : "hashmapCreate",
"linker_set_key" : "hashmapCreate",
@ -2400,6 +2424,15 @@
"size" : 4,
"source_file" : "system/core/libcutils/include/cutils/hashmap.h"
},
{
"alignment" : 4,
"linker_set_key" : "_ZTIP9fs_config",
"name" : "fs_config *",
"referenced_type" : "_ZTI9fs_config",
"self_type" : "_ZTIP9fs_config",
"size" : 4,
"source_file" : "system/core/libcutils/include/private/fs_config.h"
},
{
"alignment" : 4,
"linker_set_key" : "_ZTIP9str_parms",
@ -2694,6 +2727,37 @@
"self_type" : "_ZTI5cnode",
"size" : 20,
"source_file" : "system/core/libcutils/include/cutils/config_utils.h"
},
{
"alignment" : 8,
"fields" :
[
{
"field_name" : "uid",
"referenced_type" : "_ZTIj"
},
{
"field_name" : "gid",
"field_offset" : 32,
"referenced_type" : "_ZTIj"
},
{
"field_name" : "mode",
"field_offset" : 64,
"referenced_type" : "_ZTIt"
},
{
"field_name" : "capabilities",
"field_offset" : 128,
"referenced_type" : "_ZTIy"
}
],
"linker_set_key" : "_ZTI9fs_config",
"name" : "fs_config",
"referenced_type" : "_ZTI9fs_config",
"self_type" : "_ZTI9fs_config",
"size" : 24,
"source_file" : "system/core/libcutils/include/private/fs_config.h"
}
],
"rvalue_reference_types" : []

View file

@ -91,7 +91,7 @@ static const struct fs_path_config android_dirs[] = {
{ 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 @@ static const struct fs_path_config android_files[] = {
{ 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 @@ static bool fs_config_cmp(bool dir, const char* prefix, size_t len, const char*
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 @@ void fs_config(const char* path, int dir, const char* target_out_path, unsigned*
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 @@ void fs_config(const char* path, int dir, const char* target_out_path, unsigned*
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;
}
}

View file

@ -21,8 +21,11 @@
#pragma once
#include <fcntl.h>
#include <stdbool.h>
#include <stdint.h>
#include <sys/cdefs.h>
#include <unistd.h>
#include <linux/capability.h>
@ -30,17 +33,27 @@
__BEGIN_DECLS
/*
* Used in:
* build/tools/fs_config/fs_config.c
* build/tools/fs_get_stats/fs_get_stats.c
* system/extras/ext4_utils/make_ext4fs_main.c
* external/squashfs-tools/squashfs-tools/android.c
* system/core/cpio/mkbootfs.c
* system/core/adb/file_sync_service.cpp
* system/extras/ext4_utils/canned_fs_config.c
*/
/* This API is deprecated. New users should call get_fs_config. */
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 {
uid_t uid;
gid_t gid;
mode_t mode;
uint64_t capabilities;
};
/*
* If a file system configuration was found for the specified path, store it to *conf.
* Returns whether a file system configuration was found.
*
* dir: Whether path refers to a directory.
* target_out_path: Path to the base directory to read the file system configuration from, or a null
* pointer to use the root directory as the base. Host code should pass $ANDROID_PRODUCT_OUT or
* equivalent, and device code should pass a null pointer.
*/
bool get_fs_config(const char* path, bool dir, const char* target_out_path,
struct fs_config* conf);
__END_DECLS