From: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
To: Tiezhu Yang <yangtiezhu@loongson.cn>
Cc: Xuefeng Li <lixuefeng@loongson.cn>,
linux-mips@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v2 1/3] MIPS: signal: Protect against sigaltstack wraparound
Date: Sun, 2 Jan 2022 14:31:09 +0100 [thread overview]
Message-ID: <20220102133109.GF3468@alpha.franken.de> (raw)
In-Reply-To: <1639974460-3278-2-git-send-email-yangtiezhu@loongson.cn>
On Mon, Dec 20, 2021 at 12:27:38PM +0800, Tiezhu Yang wrote:
> If a process uses alternative signal stack by using sigaltstack(),
> then that stack overflows and stack wraparound occurs.
>
> Simple Explanation:
> The accurate sp order is A,B,C,D,...
> But now the sp points to A,B,C and A,B,C again.
>
> This problem can reproduce by the following code:
>
> $ cat test_sigaltstack.c
> #include <stdio.h>
> #include <signal.h>
> #include <stdlib.h>
> #include <string.h>
>
> volatile int counter = 0;
>
> void print_sp()
> {
> unsigned long sp;
>
> __asm__ __volatile__("move %0, $sp" : "=r" (sp));
> printf("sp = 0x%08lx\n", sp);
> }
>
> void segv_handler()
> {
> int *c = NULL;
>
> print_sp();
> counter++;
> printf("%d\n", counter);
>
> if (counter == 23)
> abort();
>
> *c = 1; // SEGV
> }
>
> int main()
> {
> int *c = NULL;
> char *s = malloc(SIGSTKSZ);
> stack_t stack;
> struct sigaction action;
>
> memset(s, 0, SIGSTKSZ);
> stack.ss_sp = s;
> stack.ss_flags = 0;
> stack.ss_size = SIGSTKSZ;
> if (sigaltstack(&stack, NULL)) {
> printf("Failed to use sigaltstack!\n");
> return -1;
> }
>
> memset(&action, 0, sizeof(action));
> action.sa_handler = segv_handler;
> action.sa_flags = SA_ONSTACK | SA_NODEFER;
> sigemptyset(&action.sa_mask);
> sigaction(SIGSEGV, &action, NULL);
>
> *c = 0; //SEGV
>
> if (!s)
> free(s);
>
> return 0;
> }
> $ gcc test_sigaltstack.c -o test_sigaltstack
> $ ./test_sigaltstack
> sp = 0x120015c80
> 1
> sp = 0x120015900
> 2
> sp = 0x120015580
> 3
> sp = 0x120015200
> 4
> sp = 0x120014e80
> 5
> sp = 0x120014b00
> 6
> sp = 0x120014780
> 7
> sp = 0x120014400
> 8
> sp = 0x120014080
> 9
> sp = 0x120013d00
> 10
> sp = 0x120015c80
> 11 # wraparound occurs! the 11nd output is same as 1st.
> sp = 0x120015900
> 12
> sp = 0x120015580
> 13
> sp = 0x120015200
> 14
> sp = 0x120014e80
> 15
> sp = 0x120014b00
> 16
> sp = 0x120014780
> 17
> sp = 0x120014400
> 18
> sp = 0x120014080
> 19
> sp = 0x120013d00
> 20
> sp = 0x120015c80
> 21 # wraparound occurs! the 21nd output is same as 1st.
> sp = 0x120015900
> 22
> sp = 0x120015580
> 23
> Aborted
>
> With this patch:
>
> $ ./test_sigaltstack
> sp = 0x120015c80
> 1
> sp = 0x120015900
> 2
> sp = 0x120015580
> 3
> sp = 0x120015200
> 4
> sp = 0x120014e80
> 5
> sp = 0x120014b00
> 6
> sp = 0x120014780
> 7
> sp = 0x120014400
> 8
> sp = 0x120014080
> 9
> Segmentation fault
>
> If we are on the alternate signal stack and would overflow it, don't.
> Return an always-bogus address instead so we will die with SIGSEGV.
>
> This patch is similar with commit 83bd01024b1f ("x86: protect against
> sigaltstack wraparound").
>
> Signed-off-by: Tiezhu Yang <yangtiezhu@loongson.cn>
> ---
> arch/mips/kernel/signal.c | 7 +++++++
> 1 file changed, 7 insertions(+)
>
> diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
> index c9b2a75..c1632e8 100644
> --- a/arch/mips/kernel/signal.c
> +++ b/arch/mips/kernel/signal.c
> @@ -563,6 +563,13 @@ void __user *get_sigframe(struct ksignal *ksig, struct pt_regs *regs,
> sp = regs->regs[29];
>
> /*
> + * If we are on the alternate signal stack and would overflow it, don't.
> + * Return an always-bogus address instead so we will die with SIGSEGV.
> + */
> + if (on_sig_stack(sp) && !likely(on_sig_stack(sp - frame_size)))
> + return (void __user __force *)(-1UL);
> +
> + /*
> * FPU emulator may have it's own trampoline active just
> * above the user stack, 16-bytes before the next lowest
> * 16 byte boundary. Try to avoid trashing it.
> --
> 2.1.0
applied to mips-next.
Thomas.
--
Crap can work. Given enough thrust pigs will fly, but it's not necessarily a
good idea. [ RFC1925, 2.3 ]
next prev parent reply other threads:[~2022-01-02 13:32 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-12-20 4:27 [PATCH v2 0/3] MIPS: signal: Modify some code Tiezhu Yang
2021-12-20 4:27 ` [PATCH v2 1/3] MIPS: signal: Protect against sigaltstack wraparound Tiezhu Yang
2022-01-02 13:31 ` Thomas Bogendoerfer [this message]
2021-12-20 4:27 ` [PATCH v2 2/3] MIPS: signal: Return immediately if call fails Tiezhu Yang
2022-01-02 13:31 ` Thomas Bogendoerfer
2021-12-20 4:27 ` [PATCH v2 3/3] MIPS: signal: Remove unnecessary DEBUG_SIG related code Tiezhu Yang
2022-01-02 13:32 ` Thomas Bogendoerfer
2022-01-18 16:01 ` Maciej W. Rozycki
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=20220102133109.GF3468@alpha.franken.de \
--to=tsbogend@alpha.franken.de \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mips@vger.kernel.org \
--cc=lixuefeng@loongson.cn \
--cc=yangtiezhu@loongson.cn \
/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.