Skip to content

Commit 38a2c27

Browse files
committed
Merge tag 'parisc-for-6.18-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux
Pull parisc fix from Helge Deller: - fix crash triggered by unaligned access in parisc unwinder * tag 'parisc-for-6.18-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux: parisc: Avoid crash due to unaligned access in unwinder
2 parents a2e33fb + fd9f30d commit 38a2c27

1 file changed

Lines changed: 10 additions & 3 deletions

File tree

arch/parisc/kernel/unwind.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@
3535

3636
#define KERNEL_START (KERNEL_BINARY_TEXT_START)
3737

38+
#define ALIGNMENT_OK(ptr, type) (((ptr) & (sizeof(type) - 1)) == 0)
39+
3840
extern struct unwind_table_entry __start___unwind[];
3941
extern struct unwind_table_entry __stop___unwind[];
4042

@@ -257,12 +259,15 @@ static int unwind_special(struct unwind_frame_info *info, unsigned long pc, int
257259
if (pc_is_kernel_fn(pc, _switch_to) ||
258260
pc == (unsigned long)&_switch_to_ret) {
259261
info->prev_sp = info->sp - CALLEE_SAVE_FRAME_SIZE;
260-
info->prev_ip = *(unsigned long *)(info->prev_sp - RP_OFFSET);
262+
if (ALIGNMENT_OK(info->prev_sp, long))
263+
info->prev_ip = *(unsigned long *)(info->prev_sp - RP_OFFSET);
264+
else
265+
info->prev_ip = info->prev_sp = 0;
261266
return 1;
262267
}
263268

264269
#ifdef CONFIG_IRQSTACKS
265-
if (pc == (unsigned long)&_call_on_stack) {
270+
if (pc == (unsigned long)&_call_on_stack && ALIGNMENT_OK(info->sp, long)) {
266271
info->prev_sp = *(unsigned long *)(info->sp - FRAME_SIZE - REG_SZ);
267272
info->prev_ip = *(unsigned long *)(info->sp - FRAME_SIZE - RP_OFFSET);
268273
return 1;
@@ -370,8 +375,10 @@ static void unwind_frame_regs(struct unwind_frame_info *info)
370375
info->prev_sp = info->sp - frame_size;
371376
if (e->Millicode)
372377
info->rp = info->r31;
373-
else if (rpoffset)
378+
else if (rpoffset && ALIGNMENT_OK(info->prev_sp, long))
374379
info->rp = *(unsigned long *)(info->prev_sp - rpoffset);
380+
else
381+
info->rp = 0;
375382
info->prev_ip = info->rp;
376383
info->rp = 0;
377384
}

0 commit comments

Comments
 (0)