Bug 24202 - m68k setjmp() saves incorrect 'a5' register in --enable-stack-protector=all
Summary: m68k setjmp() saves incorrect 'a5' register in --enable-stack-protector=all
Alias: None
Product: glibc
Classification: Unclassified
Component: libc (show other bugs)
Version: 2.29
: P2 normal
Target Milestone: 2.33
Assignee: Not yet assigned to anyone
Depends on:
Reported: 2019-02-10 23:16 UTC by Sergei Trofimovich
Modified: 2020-12-21 04:58 UTC (History)
5 users (show)

See Also:
Target: m68k-*
Last reconfirmed:
fweimer: security-

0001-m68k-fix-clobbering-a5-in-setjmp-BZ-24202.patch (787 bytes, patch)
2019-02-10 23:30 UTC, Sergei Trofimovich
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Sergei Trofimovich 2019-02-10 23:16:46 UTC
James Le Cuirot reports that glibc-2.28 for m68k-unknown-linux-gnu when built with --enable-stack-protector=all setjmp()/longjmp() breaks 'dash -c exit'.

Here is the minimal reproducer or a failure (dash's 'exit' uses 'longjmp'):

  // cat m68k-longjmp-bug.c 
  #include <setjmp.h>
  #include <stdio.h>

  int main() {
    jmp_buf jb;
    volatile register int r asm ("a2");
    r = 0x1234;
    if (setjmp(jb) == 0)
        longjmp(jb, 1);
    printf ("r = %x\n", r);

  $ m68k-unknown-linux-gnu-gcc m68k-longjmp-bug.c -fstack-protector-all -o a && ./a
  *** stack smashing detected ***: <unknown> terminated

The bug is very similar in nature to https://sourceware.org/PR22624 where setjmp() was written in C and inserted by compiler canary clobbered to-be-saved register.

This fix is enough to make the example work:

--- a/sysdeps/m68k/setjmp.c
+++ b/sysdeps/m68k/setjmp.c
@@ -17,10 +17,11 @@

 #include <setjmp.h>

 /* Save the current program position in ENV and return 0.  */
 #if defined BSD_SETJMP
 # undef setjmp
 # define savemask 1
 setjmp (jmp_buf env)
 #elif defined BSD__SETJMP
Comment 1 Sergei Trofimovich 2019-02-10 23:30:56 UTC
Created attachment 11602 [details]

Attached patch and sent to ML for review as:
Comment 2 Siddhesh Poyarekar 2020-12-21 04:58:00 UTC
Fixed in master:

commit 6eb7e1da0e805e2893a0b70a5813641529d8c7e2 (HEAD -> master)
Author: Sergei Trofimovich <slyfox@gentoo.org>
Date:   Mon Dec 21 10:24:34 2020 +0530

    m68k: fix clobbering a5 in setjmp() [BZ #24202]
    setjmp() uses C code to store current registers into jmp_buf
    environment. -fstack-protector-all places canary into setjmp()
    prologue and clobbers 'a5' before it gets saved.
    The change inhibits stack canary injection to avoid clobber.