plugins/core: clamp syscall arguments if target is 32-bit
Syscall arguments are abi_long in user code, and plugin syscall interface works with uint64_t only. According to C integer promotion rules, the value is sign extended before becoming unsigned, thus setting high bits when only 32-bit lower ones should have a significant value. As a result, we need to clamp values we receive from user-code accordingly. Reviewed-by: Alex Bennée <alex.bennee@linaro.org> Link: https://lore.kernel.org/qemu-devel/20260305-setpc-v5-v7-1-4c3adba52403@epfl.ch Signed-off-by: Pierrick Bouvier <pierrick.bouvier@linaro.org>
Pierrick Bouvier committed
Mar 5, 2026 at 11:05 UTC
2cc35f14ba9d3538aa091cdcf7aab7fdbd8ff0a8
1 file changed
+21
plugins/core.c
+21
@@ -513,6 +513,23 @@ void qemu_plugin_tb_trans_cb(CPUState *cpu, struct qemu_plugin_tb *tb)
513
}
514
}
515
516
+static void clamp_syscall_arguments(uint64_t *a1, uint64_t *a2, uint64_t *a3,
517
+ uint64_t *a4, uint64_t *a5, uint64_t *a6,
518
+ uint64_t *a7, uint64_t *a8)
519
+{
520
+ if (target_long_bits() == 32) {
521
+ const uint64_t mask = UINT32_MAX;
522
+ *a1 &= mask;
523
+ *a2 &= mask;
524
+ *a3 &= mask;
525
+ *a4 &= mask;
526
+ *a5 &= mask;
527
+ *a6 &= mask;
528
+ *a7 &= mask;
529
+ *a8 &= mask;
530
+ }
531
+}
532
+
533
/*
534
* Disable CFI checks.
535
* The callback function has been loaded from an external library so we do not
@@ -531,6 +548,8 @@ qemu_plugin_vcpu_syscall(CPUState *cpu, int64_t num, uint64_t a1, uint64_t a2,
548
return;
549
}
550
551
+ clamp_syscall_arguments(&a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8);
552
+
553
QLIST_FOREACH_SAFE_RCU(cb, &plugin.cb_lists[ev], entry, next) {
554
qemu_plugin_vcpu_syscall_cb_t func = cb->f.vcpu_syscall;
555
@@ -584,6 +603,8 @@ qemu_plugin_vcpu_syscall_filter(CPUState *cpu, int64_t num, uint64_t a1,
603
return false;
604
}
605
606
+ clamp_syscall_arguments(&a1, &a2, &a3, &a4, &a5, &a6, &a7, &a8);
607
+
608
qemu_plugin_set_cb_flags(cpu, QEMU_PLUGIN_CB_RW_REGS);
609
610
QLIST_FOREACH_SAFE_RCU(cb, &plugin.cb_lists[ev], entry, next) {