[PATCH] Turn ptr_to_globals and bb_errno to be non const

Khem Raj raj.khem at gmail.com
Sat Aug 10 00:29:41 UTC 2019


writing to a const variable is undefined behavior

This is undefined as per (C99 6.7.3 paragraph 5) see [1]

errno and ptr_to_globals is written to in code, this fails with
segfaults when compiled with clang

unsigned FAST_FUNC bb_strtou(const char *arg, char **endp, int base)
{
      unsigned long v;
      char *endptr;

      if (!endp) endp = &endptr;
      *endp = (char*) arg;

      if (!isalnum(arg[0])) return ret_ERANGE();
      errno = 0;
      v = strtoul(arg, endp, base);
      if (v > UINT_MAX) return ret_ERANGE();
      return handle_errors(v, endp);
  }

without 'const' ( working code )

Dump of assembler code for function bb_strtou:
   0x0000555555568298 <+0>:     push   %rbx
   0x0000555555568299 <+1>:     sub    $0x10,%rsp
   0x000055555556829d <+5>:     test   %rsi,%rsi
   0x00005555555682a0 <+8>:     lea    0x8(%rsp),%rbx
   0x00005555555682a5 <+13>:    cmovne %rsi,%rbx
   0x00005555555682a9 <+17>:    mov    %rdi,(%rbx)
   0x00005555555682ac <+20>:    mov    (%rdi),%al
   0x00005555555682ae <+22>:    lea    -0x30(%rax),%ecx
   0x00005555555682b1 <+25>:    cmp    $0xa,%cl
   0x00005555555682b4 <+28>:    jb     0x5555555682be <bb_strtou+38>
   0x00005555555682b6 <+30>:    or     $0x20,%al
   0x00005555555682b8 <+32>:    add    $0x9f,%al
   0x00005555555682ba <+34>:    cmp    $0x1a,%al
   0x00005555555682bc <+36>:    jae    0x5555555682dc <bb_strtou+68>
   0x00005555555682be <+38>:    mov    0x107da3(%rip),%rax        # 0x555555670068 <bb_errno>
=> 0x00005555555682c5 <+45>:    movl   $0x0,(%rax)
   0x00005555555682cb <+51>:    mov    %rbx,%rsi
   0x00005555555682ce <+54>:    callq  0x555555564310 <strtoul at plt>
   0x00005555555682d3 <+59>:    mov    %rax,%rcx
   0x00005555555682d6 <+62>:    shr    $0x20,%rcx
   0x00005555555682da <+66>:    je     0x5555555682f0 <bb_strtou+88>
   0x00005555555682dc <+68>:    mov    0x107d85(%rip),%rax        # 0x555555670068 <bb_errno>
   0x00005555555682e3 <+75>:    movl   $0x22,(%rax)
   0x00005555555682e9 <+81>:    mov    $0xffffffff,%eax
   0x00005555555682ee <+86>:    jmp    0x5555555682fb <bb_strtou+99>
   0x00005555555682f0 <+88>:    mov    %rax,%rdi
   0x00005555555682f3 <+91>:    mov    %rbx,%rsi
   0x00005555555682f6 <+94>:    callq  0x5555555681e8 <handle_errors>
   0x00005555555682fb <+99>:    add    $0x10,%rsp
   0x00005555555682ff <+103>:   pop    %rbx
   0x0000555555568300 <+104>:   retq

here address of bb_errno is valid rax = 0x7ffff7cac6c0

with 'const' ( non-working code )

Dump of assembler code for function bb_strtou:
   0x00005555555682a4 <+0>:     push   %r14
   0x00005555555682a6 <+2>:     push   %rbx
   0x00005555555682a7 <+3>:     push   %rax
   0x00005555555682a8 <+4>:     test   %rsi,%rsi
   0x00005555555682ab <+7>:     mov    %rsp,%rbx
   0x00005555555682ae <+10>:    cmovne %rsi,%rbx
   0x00005555555682b2 <+14>:    mov    %rdi,(%rbx)
   0x00005555555682b5 <+17>:    mov    (%rdi),%al
   0x00005555555682b7 <+19>:    lea    -0x30(%rax),%ecx
   0x00005555555682ba <+22>:    cmp    $0xa,%cl
   0x00005555555682bd <+25>:    jb     0x5555555682d6 <bb_strtou+50>
   0x00005555555682bf <+27>:    or     $0x20,%al
   0x00005555555682c1 <+29>:    add    $0x9f,%al
   0x00005555555682c3 <+31>:    cmp    $0x1a,%al
   0x00005555555682c5 <+33>:    jb     0x5555555682d6 <bb_strtou+50>
   0x00005555555682c7 <+35>:    mov    0x107d9a(%rip),%rax        # 0x555555670068 <bb_errno>
   0x00005555555682ce <+42>:    movl   $0x22,(%rax)
   0x00005555555682d4 <+48>:    jmp    0x5555555682fc <bb_strtou+88>
   0x00005555555682d6 <+50>:    mov    0x107d8b(%rip),%r14        # 0x555555670068 <bb_errno>
=> 0x00005555555682dd <+57>:    movl   $0x0,(%r14)
   0x00005555555682e4 <+64>:    mov    %rbx,%rsi
   0x00005555555682e7 <+67>:    callq  0x555555564300 <strtoul at plt>
   0x00005555555682ec <+72>:    mov    %rax,%rcx
   0x00005555555682ef <+75>:    shr    $0x20,%rcx
   0x00005555555682f3 <+79>:    je     0x555555568303 <bb_strtou+95>
   0x00005555555682f5 <+81>:    movl   $0x22,(%r14)
   0x00005555555682fc <+88>:    mov    $0xffffffff,%eax
   0x0000555555568301 <+93>:    jmp    0x55555556830e <bb_strtou+106>
   0x0000555555568303 <+95>:    mov    %rax,%rdi
   0x0000555555568306 <+98>:    mov    %rbx,%rsi
   0x0000555555568309 <+101>:   callq  0x5555555681f4 <handle_errors>
   0x000055555556830e <+106>:   add    $0x8,%rsp
   0x0000555555568312 <+110>:   pop    %rbx
   0x0000555555568313 <+111>:   pop    %r14
   0x0000555555568315 <+113>:   retq

r14 is 0x0 and writing to this ofcourse ends up in segfault

[1] https://bugs.llvm.org/show_bug.cgi?id=39919

Signed-off-by: Khem Raj <raj.khem at gmail.com>
---
 include/libbb.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/libbb.h b/include/libbb.h
index 111d1b790..a52265e77 100644
--- a/include/libbb.h
+++ b/include/libbb.h
@@ -341,7 +341,7 @@ struct BUG_off_t_size_is_misdetected {
 #if defined(__GLIBC__)
 /* glibc uses __errno_location() to get a ptr to errno */
 /* We can just memorize it once - no multithreading in busybox :) */
-extern int *const bb_errno;
+extern int *bb_errno;
 #undef errno
 #define errno (*bb_errno)
 #endif
@@ -2152,7 +2152,7 @@ struct globals;
 /* '*const' ptr makes gcc optimize code much better.
  * Magic prevents ptr_to_globals from going into rodata.
  * If you want to assign a value, use SET_PTR_TO_GLOBALS(x) */
-extern struct globals *const ptr_to_globals;
+extern struct globals *ptr_to_globals;
 /* At least gcc 3.4.6 on mipsel system needs optimization barrier */
 #define barrier() __asm__ __volatile__("":::"memory")
 #define SET_PTR_TO_GLOBALS(x) do { \
-- 
2.22.0



More information about the busybox mailing list