From: <gregkh@linuxfoundation.org>
To: paul.burton@imgtec.com, gregkh@linuxfoundation.org,
leonid.yegoshin@imgtec.com, ralf@linux-mips.org
Cc: <stable@vger.kernel.org>, <stable-commits@vger.kernel.org>
Subject: Patch "MIPS: Prevent unaligned accesses during stack unwinding" has been added to the 4.9-stable tree
Date: Wed, 08 Mar 2017 08:00:11 +0100 [thread overview]
Message-ID: <14889564115647@kroah.com> (raw)
This is a note to let you know that I've just added the patch titled
MIPS: Prevent unaligned accesses during stack unwinding
to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary
The filename of the patch is:
mips-prevent-unaligned-accesses-during-stack-unwinding.patch
and it can be found in the queue-4.9 subdirectory.
If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@vger.kernel.org> know about it.
>From a3552dace7d1d0cabf573e88fc3025cb90c4a601 Mon Sep 17 00:00:00 2001
From: Paul Burton <paul.burton@imgtec.com>
Date: Mon, 7 Nov 2016 15:07:03 +0000
Subject: MIPS: Prevent unaligned accesses during stack unwinding
From: Paul Burton <paul.burton@imgtec.com>
commit a3552dace7d1d0cabf573e88fc3025cb90c4a601 upstream.
During stack unwinding we call a number of functions to determine what
type of instruction we're looking at. The union mips_instruction pointer
provided to them may be pointing at a 2 byte, but not 4 byte, aligned
address & we thus cannot directly access the 4 byte wide members of the
union mips_instruction. To avoid this is_ra_save_ins() copies the
required half-words of the microMIPS instruction to a correctly aligned
union mips_instruction on the stack, which it can then access safely.
The is_jump_ins() & is_sp_move_ins() functions do not correctly perform
this temporary copy, and instead attempt to directly dereference 4 byte
fields which may be misaligned and lead to an address exception.
Fix this by copying the instruction halfwords to a temporary union
mips_instruction in get_frame_info() such that we can provide a 4 byte
aligned union mips_instruction to the is_*_ins() functions and they do
not need to deal with misalignment themselves.
Signed-off-by: Paul Burton <paul.burton@imgtec.com>
Fixes: 34c2f668d0f6 ("MIPS: microMIPS: Add unaligned access support.")
Cc: Leonid Yegoshin <leonid.yegoshin@imgtec.com>
Cc: linux-mips@linux-mips.org
Patchwork: https://patchwork.linux-mips.org/patch/14529/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/mips/kernel/process.c | 70 ++++++++++++++++++++++-----------------------
1 file changed, 35 insertions(+), 35 deletions(-)
--- a/arch/mips/kernel/process.c
+++ b/arch/mips/kernel/process.c
@@ -198,8 +198,6 @@ struct mips_frame_info {
static inline int is_ra_save_ins(union mips_instruction *ip)
{
#ifdef CONFIG_CPU_MICROMIPS
- union mips_instruction mmi;
-
/*
* swsp ra,offset
* swm16 reglist,offset(sp)
@@ -209,23 +207,20 @@ static inline int is_ra_save_ins(union m
*
* microMIPS is way more fun...
*/
- if (mm_insn_16bit(ip->halfword[0])) {
- mmi.word = (ip->halfword[0] << 16);
- return (mmi.mm16_r5_format.opcode == mm_swsp16_op &&
- mmi.mm16_r5_format.rt == 31) ||
- (mmi.mm16_m_format.opcode == mm_pool16c_op &&
- mmi.mm16_m_format.func == mm_swm16_op);
+ if (mm_insn_16bit(ip->halfword[1])) {
+ return (ip->mm16_r5_format.opcode == mm_swsp16_op &&
+ ip->mm16_r5_format.rt == 31) ||
+ (ip->mm16_m_format.opcode == mm_pool16c_op &&
+ ip->mm16_m_format.func == mm_swm16_op);
}
else {
- mmi.halfword[0] = ip->halfword[1];
- mmi.halfword[1] = ip->halfword[0];
- return (mmi.mm_m_format.opcode == mm_pool32b_op &&
- mmi.mm_m_format.rd > 9 &&
- mmi.mm_m_format.base == 29 &&
- mmi.mm_m_format.func == mm_swm32_func) ||
- (mmi.i_format.opcode == mm_sw32_op &&
- mmi.i_format.rs == 29 &&
- mmi.i_format.rt == 31);
+ return (ip->mm_m_format.opcode == mm_pool32b_op &&
+ ip->mm_m_format.rd > 9 &&
+ ip->mm_m_format.base == 29 &&
+ ip->mm_m_format.func == mm_swm32_func) ||
+ (ip->i_format.opcode == mm_sw32_op &&
+ ip->i_format.rs == 29 &&
+ ip->i_format.rt == 31);
}
#else
/* sw / sd $ra, offset($sp) */
@@ -246,12 +241,8 @@ static inline int is_jump_ins(union mips
*
* microMIPS is kind of more fun...
*/
- union mips_instruction mmi;
-
- mmi.word = (ip->halfword[0] << 16);
-
- if ((mmi.mm16_r5_format.opcode == mm_pool16c_op &&
- (mmi.mm16_r5_format.rt & mm_jr16_op) == mm_jr16_op) ||
+ if ((ip->mm16_r5_format.opcode == mm_pool16c_op &&
+ (ip->mm16_r5_format.rt & mm_jr16_op) == mm_jr16_op) ||
ip->j_format.opcode == mm_jal32_op)
return 1;
if (ip->r_format.opcode != mm_pool32a_op ||
@@ -280,15 +271,13 @@ static inline int is_sp_move_ins(union m
*
* microMIPS is not more fun...
*/
- if (mm_insn_16bit(ip->halfword[0])) {
- union mips_instruction mmi;
-
- mmi.word = (ip->halfword[0] << 16);
- return (mmi.mm16_r3_format.opcode == mm_pool16d_op &&
- mmi.mm16_r3_format.simmediate && mm_addiusp_func) ||
- (mmi.mm16_r5_format.opcode == mm_pool16d_op &&
- mmi.mm16_r5_format.rt == 29);
+ if (mm_insn_16bit(ip->halfword[1])) {
+ return (ip->mm16_r3_format.opcode == mm_pool16d_op &&
+ ip->mm16_r3_format.simmediate && mm_addiusp_func) ||
+ (ip->mm16_r5_format.opcode == mm_pool16d_op &&
+ ip->mm16_r5_format.rt == 29);
}
+
return ip->mm_i_format.opcode == mm_addiu32_op &&
ip->mm_i_format.rt == 29 && ip->mm_i_format.rs == 29;
#else
@@ -303,7 +292,8 @@ static inline int is_sp_move_ins(union m
static int get_frame_info(struct mips_frame_info *info)
{
- union mips_instruction *ip;
+ bool is_mmips = IS_ENABLED(CONFIG_CPU_MICROMIPS);
+ union mips_instruction insn, *ip;
unsigned max_insns = info->func_size / sizeof(union mips_instruction);
unsigned i;
@@ -319,11 +309,21 @@ static int get_frame_info(struct mips_fr
max_insns = min(128U, max_insns);
for (i = 0; i < max_insns; i++, ip++) {
+ if (is_mmips && mm_insn_16bit(ip->halfword[0])) {
+ insn.halfword[0] = 0;
+ insn.halfword[1] = ip->halfword[0];
+ } else if (is_mmips) {
+ insn.halfword[0] = ip->halfword[1];
+ insn.halfword[1] = ip->halfword[0];
+ } else {
+ insn.word = ip->word;
+ }
- if (is_jump_ins(ip))
+ if (is_jump_ins(&insn))
break;
+
if (!info->frame_size) {
- if (is_sp_move_ins(ip))
+ if (is_sp_move_ins(&insn))
{
#ifdef CONFIG_CPU_MICROMIPS
if (mm_insn_16bit(ip->halfword[0]))
@@ -346,7 +346,7 @@ static int get_frame_info(struct mips_fr
}
continue;
}
- if (info->pc_offset == -1 && is_ra_save_ins(ip)) {
+ if (info->pc_offset == -1 && is_ra_save_ins(&insn)) {
info->pc_offset =
ip->i_format.simmediate / sizeof(long);
break;
Patches currently in stable-queue which might be from paul.burton@imgtec.com are
queue-4.9/mips-calculate-micromips-ra-properly-when-unwinding-the-stack.patch
queue-4.9/mips-fix-get_frame_info-handling-of-micromips-function-size.patch
queue-4.9/mips-handle-micromips-jumps-in-the-same-way-as-mips32-mips64-jumps.patch
queue-4.9/mips-fix-is_jump_ins-handling-of-16b-micromips-instructions.patch
queue-4.9/mips-clear-isa-bit-correctly-in-get_frame_info.patch
queue-4.9/mips-prevent-unaligned-accesses-during-stack-unwinding.patch
reply other threads:[~2017-03-08 7:05 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=14889564115647@kroah.com \
--to=gregkh@linuxfoundation.org \
--cc=leonid.yegoshin@imgtec.com \
--cc=paul.burton@imgtec.com \
--cc=ralf@linux-mips.org \
--cc=stable-commits@vger.kernel.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.