MTE tags not checked properly for unaligned accesses at EL1
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
QEMU |
Fix Released
|
Undecided
|
Richard Henderson |
Bug Description
For kernel memory accesses that span across two memory granules, QEMU's MTE implementation only checks the tag of the first granule but not of the second one.
To reproduce this, build the Linux kernel with CONFIG_
diff --git a/sound/last.c b/sound/last.c
index f0bb98780e70.
--- a/sound/last.c
+++ b/sound/last.c
@@ -5,12 +5,18 @@
*/
#include <linux/init.h>
+#include <linux/slab.h>
#include <sound/core.h>
static int __init alsa_sound_
{
struct snd_card *card;
int idx, ok = 0;
+
+ char *ptr = kmalloc(128, GFP_KERNEL);
+ pr_err("KASAN report should follow:\n");
+ *(volatile unsigned long *)(ptr + 124);
+ kfree(ptr);
for (idx = 0; idx < SNDRV_CARDS; idx++) {
KASAN tags the 128 allocated bytes with the same tag as the returned pointer. The memory granule that follows the 128 allocated bytes has a different tag (with 1/15 probability).
Expected result: a tag fault is detected and a KASAN report is printed when accessing bytes [124, 130).
Observed result: no tag fault is detected and no KASAN report is printed.
Here are the flags that I use to run QEMU if they matter:
qemu-system-aarch64 -s -machine virt,mte=on -cpu max -m 2G -smp 2 -net user,host=
Changed in qemu: | |
status: | In Progress → Fix Committed |
I believe that you're correct, and that I mis-read the MTE specification.
I believed that exactly one mte tag check was made for any single memory functions/ memory/ Mem[].
access. But I missed that unaligned accesses are as-if a sequence of byte
accesses -- in the Arm ARM, see aarch64/
I'm still trying to verify this via the Arm FVP, but so far I've not
found the right incantation of parameters to properly enable MTE.
(I can enable the instructions, but a simple stg/ldg test suggests
that there is no tag storage enabled -- all tags read as 0.)