summaryrefslogtreecommitdiff
path: root/mtectrl
diff options
context:
space:
mode:
authorFlorian Mayer <fmayer@google.com>2022-09-21 12:55:33 -0700
committerFlorian Mayer <fmayer@google.com>2022-09-28 10:31:17 -0700
commitf6658f007ff2bb88bb0485c62e6ac749b5ac7d60 (patch)
treebb40f020b49ae3d2fc70d6e71766f28d46fb7a7a /mtectrl
parent78b1b1b752ad9d49b04b9f74aaac97fea977f2f1 (diff)
downloadextras-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.cc131
-rw-r--r--mtectrl/mtectrl.rc7
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