stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH RFC v2 1/8] m68k/mm: Adjust VM area to be unmapped by gap size for __iounmap()
       [not found] <20240205023236.9325-1-schmitzmic@gmail.com>
@ 2024-02-05  2:32 ` Michael Schmitz
  2024-02-05  2:32 ` [PATCH RFC v2 8/8] m68k: Move signal frame following exception on 68020/030 Michael Schmitz
       [not found] ` <20240205023236.9325-5-schmitzmic@gmail.com>
  2 siblings, 0 replies; 3+ messages in thread
From: Michael Schmitz @ 2024-02-05  2:32 UTC (permalink / raw)
  To: linux-m68k; +Cc: geert, uli, fthain, viro, Michael Schmitz, stable

If 020/030 support is enabled, get_io_area() leaves an IO_SIZE gap
between mappings which is added to the vm_struct representing the
mapping.  __ioremap() uses the actual requested size (after alignment),
while __iounmap() is passed the size from the vm_struct.

On 020/030, early termination descriptors are used to set up mappings of
extent 'size', which are validated on unmapping. The unmapped gap of
size IO_SIZE defeats the sanity check of the pmd tables, causing
__iounmap() to loop forever on 030.

On 040/060, unmapping of page table entries does not check for a valid
mapping, so the umapping loop always completes there.

Adjust size to be unmapped by the gap that had been added in the
vm_struct prior.

This fixes the hang in atari_platform_init() reported a long time ago,
and a similar one reported by Finn recently (addressed by removing
ioremap() use from the SWIM driver.

Tested on my Falcon in 030 mode - untested but should work the same on
040/060 (the extra page tables cleared there would never have been set
up anyway).

Signed-off-by: Michael Schmitz <schmitzmic@gmail.com>
[geert: Minor commit description improvements]
[geert: This was fixed in 2.4.23, but not in 2.5.x]
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
Cc: stable@vger.kernel.org
---
 arch/m68k/mm/kmap.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/m68k/mm/kmap.c b/arch/m68k/mm/kmap.c
index 6e4955bc542b..fcd52cefee29 100644
--- a/arch/m68k/mm/kmap.c
+++ b/arch/m68k/mm/kmap.c
@@ -88,7 +88,8 @@ static inline void free_io_area(void *addr)
 	for (p = &iolist ; (tmp = *p) ; p = &tmp->next) {
 		if (tmp->addr == addr) {
 			*p = tmp->next;
-			__iounmap(tmp->addr, tmp->size);
+			/* remove gap added in get_io_area() */
+			__iounmap(tmp->addr, tmp->size - IO_SIZE);
 			kfree(tmp);
 			return;
 		}
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [PATCH RFC v2 8/8] m68k: Move signal frame following exception on 68020/030
       [not found] <20240205023236.9325-1-schmitzmic@gmail.com>
  2024-02-05  2:32 ` [PATCH RFC v2 1/8] m68k/mm: Adjust VM area to be unmapped by gap size for __iounmap() Michael Schmitz
@ 2024-02-05  2:32 ` Michael Schmitz
       [not found] ` <20240205023236.9325-5-schmitzmic@gmail.com>
  2 siblings, 0 replies; 3+ messages in thread
From: Michael Schmitz @ 2024-02-05  2:32 UTC (permalink / raw)
  To: linux-m68k
  Cc: geert, uli, fthain, viro, Michael Schmitz, Andreas Schwab, stable

From: Finn Thain <fthain@linux-m68k.org>

On 68030/020, an instruction such as, moveml %a2-%a3/%a5,%sp@- may cause
a stack page fault during instruction execution (i.e. not at an
instruction boundary) and produce a format 0xB exception frame.

In this situation, the value of USP will be unreliable.  If a signal is
to be delivered following the exception, this USP value is used to
calculate the location for a signal frame.  This can result in a
corrupted user stack.

The corruption was detected in dash (actually in glibc) where it showed
up as an intermittent "stack smashing detected" message and crash
following signal delivery for SIGCHLD.

It was hard to reproduce that failure because delivery of the signal
raced with the page fault and because the kernel places an unpredictable
gap of up to 7 bytes between the USP and the signal frame.

A format 0xB exception frame can be produced by a bus error or an
address error.  The 68030 Users Manual says that address errors occur
immediately upon detection during instruction prefetch.  The instruction
pipeline allows prefetch to overlap with other instructions, which means
an address error can arise during the execution of a different
instruction.  So it seems likely that this patch may help in the address
error case also.

Reported-and-tested-by: Stan Johnson <userm57@yahoo.com>
Link: https://lore.kernel.org/all/CAMuHMdW3yD22_ApemzW_6me3adq6A458u1_F0v-1EYwK_62jPA@mail.gmail.com/
Cc: Michael Schmitz <schmitzmic@gmail.com>
Cc: Andreas Schwab <schwab@linux-m68k.org>
Cc: stable@vger.kernel.org
Co-developed-by: Michael Schmitz <schmitzmic@gmail.com>
Signed-off-by: Michael Schmitz <schmitzmic@gmail.com>
Signed-off-by: Finn Thain <fthain@linux-m68k.org>
Reviewed-by: Geert Uytterhoeven <geert@linux-m68k.org>
Link: https://lore.kernel.org/r/9e66262a754fcba50208aa424188896cc52a1dd1.1683365892.git.fthain@linux-m68k.org
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
---
 arch/m68k/kernel/signal.c | 14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
index 8fb8ee804b3a..de7c1bde62bc 100644
--- a/arch/m68k/kernel/signal.c
+++ b/arch/m68k/kernel/signal.c
@@ -808,11 +808,17 @@ static inline int rt_setup_ucontext(struct ucontext __user *uc, struct pt_regs *
 }
 
 static inline void __user *
-get_sigframe(struct ksignal *ksig, size_t frame_size)
+get_sigframe(struct ksignal *ksig, struct pt_regs *tregs, size_t frame_size)
 {
 	unsigned long usp = sigsp(rdusp(), ksig);
+	unsigned long gap = 0;
 
-	return (void __user *)((usp - frame_size) & -8UL);
+	if (CPU_IS_020_OR_030 && tregs->format == 0xb) {
+		/* USP is unreliable so use worst-case value */
+		gap = 256;
+	}
+
+	return (void __user *)((usp - gap - frame_size) & -8UL);
 }
 
 static int setup_frame(struct ksignal *ksig, sigset_t *set,
@@ -830,7 +836,7 @@ static int setup_frame(struct ksignal *ksig, sigset_t *set,
 		return -EFAULT;
 	}
 
-	frame = get_sigframe(ksig, sizeof(*frame) + fsize);
+	frame = get_sigframe(ksig, tregs, sizeof(*frame) + fsize);
 
 	if (fsize)
 		err |= copy_to_user (frame + 1, regs + 1, fsize);
@@ -903,7 +909,7 @@ static int setup_rt_frame(struct ksignal *ksig, sigset_t *set,
 		return -EFAULT;
 	}
 
-	frame = get_sigframe(ksig, sizeof(*frame));
+	frame = get_sigframe(ksig, tregs, sizeof(*frame));
 
 	if (fsize)
 		err |= copy_to_user (&frame->uc.uc_extra, regs + 1, fsize);
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH RFC v2 4/8] m68k: Handle arrivals of multiple signals correctly
       [not found]           ` <522961735.202648.1707732123771@webmail.strato.com>
@ 2024-02-13  5:05             ` Finn Thain
  0 siblings, 0 replies; 3+ messages in thread
From: Finn Thain @ 2024-02-13  5:05 UTC (permalink / raw)
  To: Ulrich Hecht
  Cc: Al Viro, Michael Schmitz, Geert Uytterhoeven, linux-m68k, stable

[Cc: stable]

On Mon, 12 Feb 2024, Ulrich Hecht wrote:

> 
> > On 02/08/2024 11:51 PM CET Finn Thain <fthain@linux-m68k.org> wrote:
> > Ulrich, I imagine that you would normally receive fixes via the 
> > corresponding -stable trees. If Michael's series went into 
> > stable/linux-4.19.y you could cherry-pick from there for your v4.4.y tree 
> > and maybe avoid some merge conflicts that way.
> 
> That would work for me.
> 

OK. Here's the relevant commit. It fixes bd6f56a75bb2 which first appeared 
in v2.6.38-rc1. I believe this can be cherry-picked without any conflicts.

50e43a573344 m68k: Update ->thread.esp0 before calling syscall_trace() in ret_from_signal

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2024-02-13  5:05 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20240205023236.9325-1-schmitzmic@gmail.com>
2024-02-05  2:32 ` [PATCH RFC v2 1/8] m68k/mm: Adjust VM area to be unmapped by gap size for __iounmap() Michael Schmitz
2024-02-05  2:32 ` [PATCH RFC v2 8/8] m68k: Move signal frame following exception on 68020/030 Michael Schmitz
     [not found] ` <20240205023236.9325-5-schmitzmic@gmail.com>
     [not found]   ` <CAMuHMdUMwQSEwDQ3tsmChutY3P0VQUA0A8jg63NxfyrmxfKWXQ@mail.gmail.com>
     [not found]     ` <401b6911-e6ed-3e9f-9dcc-d4f951c6beef@gmail.com>
     [not found]       ` <1501038841.1120470.1707393238298@webmail.strato.com>
     [not found]         ` <34d37f57-3146-8aa0-7828-2df2d1679ee4@linux-m68k.org>
     [not found]           ` <522961735.202648.1707732123771@webmail.strato.com>
2024-02-13  5:05             ` [PATCH RFC v2 4/8] m68k: Handle arrivals of multiple signals correctly Finn Thain

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).