[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-stable] [PATCH 10/53] target-arm: Avoid buffer overrun on UNPREDIC
From: |
Michael Roth |
Subject: |
[Qemu-stable] [PATCH 10/53] target-arm: Avoid buffer overrun on UNPREDICTABLE ldrd/strd |
Date: |
Thu, 30 Jul 2015 06:32:25 -0500 |
From: Peter Maydell <address@hidden>
A LDRD or STRD where rd is not an even number is UNPREDICTABLE.
We were letting this fall through, which is OK unless rd is 15,
in which case we would attempt to do a load_reg or store_reg
to a nonexistent r16 for the second half of the double-word.
Catch the odd-numbered-rd cases and UNDEF them instead.
To do this we rearrange the structure of the code a little
so we can put the UNDEF catches at the top before we've
allocated TCG temporaries.
Cc: address@hidden
Signed-off-by: Peter Maydell <address@hidden>
Message-id: address@hidden
(cherry picked from commit 3960c336ad96c2183549c8bf32bbff93ecda7ea4)
Signed-off-by: Michael Roth <address@hidden>
---
target-arm/translate.c | 56 ++++++++++++++++++++++++++++----------------------
1 file changed, 32 insertions(+), 24 deletions(-)
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 9116529..f8f72be 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -8423,34 +8423,30 @@ static void disas_arm_insn(DisasContext *s, unsigned
int insn)
}
} else {
int address_offset;
- int load;
+ bool load = insn & (1 << 20);
+ bool doubleword = false;
/* Misc load/store */
rn = (insn >> 16) & 0xf;
rd = (insn >> 12) & 0xf;
+
+ if (!load && (sh & 2)) {
+ /* doubleword */
+ ARCH(5TE);
+ if (rd & 1) {
+ /* UNPREDICTABLE; we choose to UNDEF */
+ goto illegal_op;
+ }
+ load = (sh & 1) == 0;
+ doubleword = true;
+ }
+
addr = load_reg(s, rn);
if (insn & (1 << 24))
gen_add_datah_offset(s, insn, 0, addr);
address_offset = 0;
- if (insn & (1 << 20)) {
- /* load */
- tmp = tcg_temp_new_i32();
- switch(sh) {
- case 1:
- gen_aa32_ld16u(tmp, addr, get_mem_index(s));
- break;
- case 2:
- gen_aa32_ld8s(tmp, addr, get_mem_index(s));
- break;
- default:
- case 3:
- gen_aa32_ld16s(tmp, addr, get_mem_index(s));
- break;
- }
- load = 1;
- } else if (sh & 2) {
- ARCH(5TE);
- /* doubleword */
- if (sh & 1) {
+
+ if (doubleword) {
+ if (!load) {
/* store */
tmp = load_reg(s, rd);
gen_aa32_st32(tmp, addr, get_mem_index(s));
@@ -8459,7 +8455,6 @@ static void disas_arm_insn(DisasContext *s, unsigned int
insn)
tmp = load_reg(s, rd + 1);
gen_aa32_st32(tmp, addr, get_mem_index(s));
tcg_temp_free_i32(tmp);
- load = 0;
} else {
/* load */
tmp = tcg_temp_new_i32();
@@ -8469,15 +8464,28 @@ static void disas_arm_insn(DisasContext *s, unsigned
int insn)
tmp = tcg_temp_new_i32();
gen_aa32_ld32u(tmp, addr, get_mem_index(s));
rd++;
- load = 1;
}
address_offset = -4;
+ } else if (load) {
+ /* load */
+ tmp = tcg_temp_new_i32();
+ switch (sh) {
+ case 1:
+ gen_aa32_ld16u(tmp, addr, get_mem_index(s));
+ break;
+ case 2:
+ gen_aa32_ld8s(tmp, addr, get_mem_index(s));
+ break;
+ default:
+ case 3:
+ gen_aa32_ld16s(tmp, addr, get_mem_index(s));
+ break;
+ }
} else {
/* store */
tmp = load_reg(s, rd);
gen_aa32_st16(tmp, addr, get_mem_index(s));
tcg_temp_free_i32(tmp);
- load = 0;
}
/* Perform base writeback before the loaded value to
ensure correct behavior with overlapping index registers.
--
1.9.1
- [Qemu-stable] Patch Round-up for stable 2.3.1, freeze on 2015-08-06, Michael Roth, 2015/07/30
- [Qemu-stable] [PATCH 09/53] virtio-net: fix the upper bound when trying to delete queues, Michael Roth, 2015/07/30
- [Qemu-stable] [PATCH 10/53] target-arm: Avoid buffer overrun on UNPREDICTABLE ldrd/strd,
Michael Roth <=
- [Qemu-stable] [PATCH 11/53] fdc: force the fifo access to be in bounds of the allocated buffer, Michael Roth, 2015/07/30
- [Qemu-stable] [PATCH 12/53] Revert "block: Fix unaligned zero write", Michael Roth, 2015/07/30
- [Qemu-stable] [PATCH 13/53] block: Fix NULL deference for unaligned write if qiov is NULL, Michael Roth, 2015/07/30
- [Qemu-stable] [PATCH 14/53] qemu-iotests: Test unaligned sub-block zero write, Michael Roth, 2015/07/30
- [Qemu-stable] [PATCH 15/53] hw/acpi/aml-build: Fix memory leak, Michael Roth, 2015/07/30
- [Qemu-stable] [PATCH 18/53] kbd: add brazil kbd keys to x11 evdev map, Michael Roth, 2015/07/30
- [Qemu-stable] [PATCH 20/53] iotests: qcow2 COW with minimal L2 cache size, Michael Roth, 2015/07/30
- [Qemu-stable] [PATCH 16/53] qga/commands-posix: Fix bug in guest-fstrim, Michael Roth, 2015/07/30
- [Qemu-stable] [PATCH 01/53] bt-sdp: fix broken uuids power-of-2 calculation, Michael Roth, 2015/07/30
- [Qemu-stable] [PATCH 17/53] kbd: add brazil kbd keys to qemu, Michael Roth, 2015/07/30