summaryrefslogtreecommitdiffstats
path: root/recipes-core/busybox/busybox/0001-Turn-ptr_to_globals-and-bb_errno-to-be-non-const.patch
blob: 481b125394f2cec5ed7afbfc6f435f46d4cee2bc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
From c7580fdb4be69a872291ccf22334091cace749fc Mon Sep 17 00:00:00 2001
From: Khem Raj <raj.khem@gmail.com>
Date: Wed, 16 Jan 2019 22:39:24 -0800
Subject: [PATCH] Turn ptr_to_globals and bb_errno to be non const

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@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@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@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