[PATCH v3 3/5] plugins: prohibit writing to read-only registers

Florian Hofhammer posted 5 patches 2 weeks, 5 days ago
Maintainers: Laurent Vivier <laurent@vivier.eu>, Brian Cain <brian.cain@oss.qualcomm.com>, "Alex Bennée" <alex.bennee@linaro.org>, Alexandre Iooss <erdnaxe@crans.org>, Mahmoud Mandour <ma.mandourr@gmail.com>, Pierrick Bouvier <pierrick.bouvier@linaro.org>, Peter Maydell <peter.maydell@linaro.org>, "Philippe Mathieu-Daudé" <philmd@linaro.org>, Aurelien Jarno <aurelien@aurel32.net>, Jiaxun Yang <jiaxun.yang@flygoat.com>, Aleksandar Rikalo <arikalo@gmail.com>, Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>, Artyom Tarasenko <atar4qemu@gmail.com>
[PATCH v3 3/5] plugins: prohibit writing to read-only registers
Posted by Florian Hofhammer 2 weeks, 5 days ago
The opaque register handle encodes whether a register is read-only in
the lowest bit and prevents writing to the register via the plugin API
in this case.

Signed-off-by: Florian Hofhammer <florian.hofhammer@epfl.ch>
---
 plugins/api.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/plugins/api.c b/plugins/api.c
index de8c32db50..4555f048a1 100644
--- a/plugins/api.c
+++ b/plugins/api.c
@@ -425,7 +425,6 @@ static GArray *create_register_handles(GArray *gdbstub_regs)
 
         gint plugin_ro_bit = 0;
         /* Create a record for the plugin */
-        desc.handle = GINT_TO_POINTER(grd->gdb_reg + 1);
         desc.name = g_intern_string(grd->name);
         if (!strcmp(desc.name, pc_str)
             || !strcmp(desc.name, eip_str)
@@ -436,6 +435,7 @@ static GArray *create_register_handles(GArray *gdbstub_regs)
            ) {
             plugin_ro_bit = 1;
         }
+        desc.handle = GINT_TO_POINTER((grd->gdb_reg << 1) | plugin_ro_bit);
         desc.is_readonly = plugin_ro_bit == 1 ? true : false;
         desc.feature = g_intern_string(grd->feature_name);
         g_array_append_val(find_data, desc);
@@ -460,7 +460,7 @@ int qemu_plugin_read_register(struct qemu_plugin_register *reg, GByteArray *buf)
         return -1;
     }
 
-    return gdb_read_register(current_cpu, buf, GPOINTER_TO_INT(reg) - 1);
+    return gdb_read_register(current_cpu, buf, GPOINTER_TO_INT(reg) >> 1);
 }
 
 int qemu_plugin_write_register(struct qemu_plugin_register *reg,
@@ -470,11 +470,12 @@ int qemu_plugin_write_register(struct qemu_plugin_register *reg,
 
     if (buf->len == 0 || (
                 qemu_plugin_get_cb_flags() != QEMU_PLUGIN_CB_RW_REGS
-                && qemu_plugin_get_cb_flags() != QEMU_PLUGIN_CB_RW_REGS_PC)) {
+                && qemu_plugin_get_cb_flags() != QEMU_PLUGIN_CB_RW_REGS_PC)
+            || (GPOINTER_TO_INT(reg) & 1)) {
         return -1;
     }
 
-    return gdb_write_register(current_cpu, buf->data, GPOINTER_TO_INT(reg) - 1);
+    return gdb_write_register(current_cpu, buf->data, GPOINTER_TO_INT(reg) >> 1);
 }
 
 void qemu_plugin_set_pc(uint64_t vaddr)
-- 
2.52.0