diff options
author | Florian Mayer <fmayer@google.com> | 2022-09-21 12:55:33 -0700 |
---|---|---|
committer | Florian Mayer <fmayer@google.com> | 2022-09-28 10:31:17 -0700 |
commit | f6658f007ff2bb88bb0485c62e6ac749b5ac7d60 (patch) | |
tree | bb40f020b49ae3d2fc70d6e71766f28d46fb7a7a /mtectrl | |
parent | 78b1b1b752ad9d49b04b9f74aaac97fea977f2f1 (diff) | |
download | extras-f6658f007ff2bb88bb0485c62e6ac749b5ac7d60.tar.gz |
[MTE] Keep property and misc partition state synced
Bug: 245624194
Test: $ adb shell mtectrl memtag default
$ adb shell mtectrl -s sys.testprop
$ adb shell getprop sys.testprop
memtag
$ adb shell mtectrl memtag,memtag-kernel default
$ adb shell mtectrl -s sys.testprop
$ adb shell getprop sys.testprop
memtag,memtag-kernel
$ adb shell mtectrl -s sys.testprop memtag default
$ adb shell getprop sys.testprop
memtag
Test: boot and check arm64.memtag.bootctl
Test: flame:/ $ setprop arm64.memtag.bootctl memtag
flame:/ $ getprop arm64.memtag.bootctl
memtag
flame:/ $ setprop persist.device_config.memory_safety_native.bootloader_override force_off
flame:/ $ getprop arm64.memtag.bootctl
memtag-off
Change-Id: Iac5fb49a10631a7f3300bedc477a2cfc1f583639
Diffstat (limited to 'mtectrl')
-rw-r--r-- | mtectrl/mtectrl.cc | 131 | ||||
-rw-r--r-- | mtectrl/mtectrl.rc | 7 |
2 files changed, 105 insertions, 33 deletions
diff --git a/mtectrl/mtectrl.cc b/mtectrl/mtectrl.cc index eefc1588..dca37ca7 100644 --- a/mtectrl/mtectrl.cc +++ b/mtectrl/mtectrl.cc @@ -14,57 +14,125 @@ * limitations under the License. */ +#include <getopt.h> + #include <android-base/logging.h> +#include <android-base/properties.h> #include <android-base/strings.h> #include <bootloader_message/bootloader_message.h> #include <iostream> -int main(int argc, char** argv) { - if (argc != 2 && argc != 3) { - std::cerr << "Usage: " << argv[0] - << " none|memtag|memtag-once|memtag-kernel|memtag-kernel-once[,.." - ".] [default|force_on|force_off]\n"; - return 1; - } - std::string value = argv[1]; - misc_memtag_message m = {.version = MISC_MEMTAG_MESSAGE_VERSION, - .magic = MISC_MEMTAG_MAGIC_HEADER}; - bool valid_value = true; +void AddItem(std::string* s, const char* item) { + if (!s->empty()) + *s += ","; + *s += item; +} + +void UpdateProp(const char* prop_name, const misc_memtag_message& m) { + std::string prop_str; + if (m.memtag_mode & MISC_MEMTAG_MODE_MEMTAG) AddItem(&prop_str, "memtag"); + if (m.memtag_mode & MISC_MEMTAG_MODE_MEMTAG_ONCE) AddItem(&prop_str, "memtag-once"); + if (m.memtag_mode & MISC_MEMTAG_MODE_MEMTAG_KERNEL) AddItem(&prop_str, "memtag-kernel"); + if (m.memtag_mode & MISC_MEMTAG_MODE_MEMTAG_KERNEL_ONCE) AddItem(&prop_str, "memtag-kernel-once"); + if (m.memtag_mode & MISC_MEMTAG_MODE_MEMTAG_OFF) AddItem(&prop_str, "memtag-off"); + if (android::base::GetProperty(prop_name, "") != prop_str) + android::base::SetProperty(prop_name, prop_str); +} + +void PrintUsage(const char* progname) { + std::cerr << "Usage: " << progname + << " [-s PROPERTY_NAME] none|memtag|memtag-once|memtag-kernel|memtag-kernel-once[,.." + ".] [default|force_on|force_off]\n" + << " " << progname << " -s PROPERTY_NAME\n"; +} + +int StringToMode(const char* value) { + int memtag_mode = 0; for (const auto& field : android::base::Split(value, ",")) { if (field == "memtag") { - m.memtag_mode |= MISC_MEMTAG_MODE_MEMTAG; + memtag_mode |= MISC_MEMTAG_MODE_MEMTAG; } else if (field == "memtag-once") { - m.memtag_mode |= MISC_MEMTAG_MODE_MEMTAG_ONCE; + memtag_mode |= MISC_MEMTAG_MODE_MEMTAG_ONCE; } else if (field == "memtag-kernel") { - m.memtag_mode |= MISC_MEMTAG_MODE_MEMTAG_KERNEL; + memtag_mode |= MISC_MEMTAG_MODE_MEMTAG_KERNEL; } else if (field == "memtag-kernel-once") { - m.memtag_mode |= MISC_MEMTAG_MODE_MEMTAG_KERNEL_ONCE; + memtag_mode |= MISC_MEMTAG_MODE_MEMTAG_KERNEL_ONCE; } else if (field == "memtag-off") { - m.memtag_mode |= MISC_MEMTAG_MODE_MEMTAG_OFF; + memtag_mode |= MISC_MEMTAG_MODE_MEMTAG_OFF; } else if (field != "none") { LOG(ERROR) << "Unknown value for mode: " << field; - valid_value = false; - m = {.version = MISC_MEMTAG_MESSAGE_VERSION, .magic = MISC_MEMTAG_MAGIC_HEADER}; - break; + return -1; } } - bool valid_override = true; - std::string override_value; - if (argc == 3) { - override_value = argv[2]; - } + return memtag_mode; +} + +bool HandleOverride(const std::string& override_value, misc_memtag_message* m) { if (override_value == "force_off") { // If the force_off override is active, only allow MEMTAG_MODE_MEMTAG_ONCE. - m.memtag_mode |= MISC_MEMTAG_MODE_MEMTAG_OFF; - m.memtag_mode &= ~MISC_MEMTAG_MODE_MEMTAG; + m->memtag_mode |= MISC_MEMTAG_MODE_MEMTAG_OFF; + m->memtag_mode &= ~MISC_MEMTAG_MODE_MEMTAG; } else if (override_value == "force_on") { - m.memtag_mode |= MISC_MEMTAG_MODE_MEMTAG; - m.memtag_mode &= ~MISC_MEMTAG_MODE_MEMTAG_OFF; + m->memtag_mode |= MISC_MEMTAG_MODE_MEMTAG; + m->memtag_mode &= ~MISC_MEMTAG_MODE_MEMTAG_OFF; } else if (!override_value.empty() && override_value != "default") { - LOG(ERROR) << "Unknown value for override: " << override_value; - valid_override = false; + return false; } + return true; +} + +int main(int argc, char** argv) { + const char* set_prop = nullptr; + int opt; + while ((opt = getopt(argc, argv, "s:")) != -1) { + switch (opt) { + case 's': + set_prop = optarg; + break; + default: + PrintUsage(argv[0]); + return 1; + } + } + + const char* value = optind < argc ? argv[optind++] : nullptr; + const char* override_value = optind < argc ? argv[optind++] : nullptr; + + if (optind != argc) { // Unknown argument. + PrintUsage(argv[0]); + return 1; + } + + if (!value && set_prop) { + std::string err; + misc_memtag_message m = {}; + if (!ReadMiscMemtagMessage(&m, &err)) { + LOG(ERROR) << "Failed to read memtag message: " << err; + return 1; + } + if (m.magic != MISC_MEMTAG_MAGIC_HEADER || m.version != MISC_MEMTAG_MESSAGE_VERSION) { + UpdateProp(set_prop, {}); + return 0; + } + UpdateProp(set_prop, m); + return 0; + } + + if (!value) { + PrintUsage(argv[0]); + return 1; + } + + misc_memtag_message m = {.version = MISC_MEMTAG_MESSAGE_VERSION, + .magic = MISC_MEMTAG_MAGIC_HEADER}; + int memtag_mode = StringToMode(value); + bool valid_value = memtag_mode != -1; + m.memtag_mode = valid_value ? memtag_mode : 0; + + bool valid_override = true; + if (override_value) valid_override = HandleOverride(override_value, &m); + if (!valid_value && !valid_override) { return 1; } @@ -84,7 +152,8 @@ int main(int argc, char** argv) { verb = "Partially applied"; } LOG(INFO) << verb << " mode: " << value << ", " - << "override: " << override_value << parse_error; + << "override: " << (override_value ? override_value : "") << parse_error; + if (set_prop) UpdateProp(set_prop, m); return !valid_value || !valid_override; } } diff --git a/mtectrl/mtectrl.rc b/mtectrl/mtectrl.rc index 05bdaa23..7dfef007 100644 --- a/mtectrl/mtectrl.rc +++ b/mtectrl/mtectrl.rc @@ -13,7 +13,10 @@ # limitations under the License. on property:arm64.memtag.bootctl=* - exec -- /system/bin/mtectrl ${arm64.memtag.bootctl:-none} ${persist.device_config.memory_safety_native.bootloader_override:-default} + exec -- /system/bin/mtectrl -s arm64.memtag.bootctl ${arm64.memtag.bootctl:-none} ${persist.device_config.memory_safety_native.bootloader_override:-default} on property:persist.device_config.memory_safety_native.bootloader_override=* - exec -- /system/bin/mtectrl ${arm64.memtag.bootctl:-none} ${persist.device_config.memory_safety_native.bootloader_override:-default} + exec -- /system/bin/mtectrl -s arm64.memtag.bootctl ${arm64.memtag.bootctl:-none} ${persist.device_config.memory_safety_native.bootloader_override:-default} + +on init + exec -- /system/bin/mtectrl -s arm64.memtag.bootctl |