@@ -53,22 +53,81 @@ TEST(unistd, brk_ENOMEM) {
53
53
ASSERT_EQ (ENOMEM, errno);
54
54
}
55
55
56
+ #if defined(__GLIBC__)
57
+ #define SBRK_MIN (-2147483647 -1 )
58
+ #define SBRK_MAX (2147483647 )
59
+ #else
60
+ #define SBRK_MIN PTRDIFF_MIN
61
+ #define SBRK_MAX PTRDIFF_MAX
62
+ #endif
63
+
56
64
TEST (unistd, sbrk_ENOMEM) {
57
- intptr_t current_brk = reinterpret_cast <intptr_t >(get_brk ());
65
+ #if defined(__BIONIC__) && !defined(__LP64__)
66
+ // There is no way to guarantee that all overflow conditions can be tested
67
+ // without manipulating the underlying values of the current break.
68
+ extern void * __bionic_brk;
69
+
70
+ class ScopedBrk {
71
+ public:
72
+ ScopedBrk () : saved_brk_(__bionic_brk) {}
73
+ virtual ~ScopedBrk () { __bionic_brk = saved_brk_; }
74
+
75
+ private:
76
+ void * saved_brk_;
77
+ };
78
+
79
+ ScopedBrk scope_brk;
80
+
81
+ // Set the current break to a point that will cause an overflow.
82
+ __bionic_brk = reinterpret_cast <void *>(static_cast <uintptr_t >(PTRDIFF_MAX) + 2 );
58
83
59
- #if !defined(__GLIBC__)
60
84
// Can't increase by so much that we'd overflow.
61
85
ASSERT_EQ (reinterpret_cast <void *>(-1 ), sbrk (PTRDIFF_MAX));
62
86
ASSERT_EQ (ENOMEM, errno);
63
- #endif
64
87
65
- // Can't reduce by more than the current break.
66
- ASSERT_EQ (reinterpret_cast <void *>(-1 ), sbrk (-(current_brk + 1 )));
67
- ASSERT_EQ (ENOMEM, errno);
88
+ // Set the current break to a point that will cause an overflow.
89
+ __bionic_brk = reinterpret_cast <void *>(static_cast <uintptr_t >(PTRDIFF_MAX));
68
90
69
- #if !defined(__GLIBC__)
70
- // The maximum negative value is an interesting special case that glibc gets wrong.
71
91
ASSERT_EQ (reinterpret_cast <void *>(-1 ), sbrk (PTRDIFF_MIN));
72
92
ASSERT_EQ (ENOMEM, errno);
93
+
94
+ __bionic_brk = reinterpret_cast <void *>(static_cast <uintptr_t >(PTRDIFF_MAX) - 1 );
95
+
96
+ ASSERT_EQ (reinterpret_cast <void *>(-1 ), sbrk (PTRDIFF_MIN + 1 ));
97
+ ASSERT_EQ (ENOMEM, errno);
98
+ #else
99
+ class ScopedBrk {
100
+ public:
101
+ ScopedBrk () : saved_brk_(get_brk()) {}
102
+ virtual ~ScopedBrk () { brk (saved_brk_); }
103
+
104
+ private:
105
+ void * saved_brk_;
106
+ };
107
+
108
+ ScopedBrk scope_brk;
109
+
110
+ uintptr_t cur_brk = reinterpret_cast <uintptr_t >(get_brk ());
111
+ if (cur_brk < static_cast <uintptr_t >(-(SBRK_MIN+1 ))) {
112
+ // Do the overflow test for a max negative increment.
113
+ ASSERT_EQ (reinterpret_cast <void *>(-1 ), sbrk (SBRK_MIN));
114
+ #if defined(__BIONIC__)
115
+ // GLIBC does not set errno in overflow case.
116
+ ASSERT_EQ (ENOMEM, errno);
117
+ #endif
118
+ }
119
+
120
+ uintptr_t overflow_brk = static_cast <uintptr_t >(SBRK_MAX) + 2 ;
121
+ if (cur_brk < overflow_brk) {
122
+ // Try and move the value to PTRDIFF_MAX + 2.
123
+ cur_brk = reinterpret_cast <uintptr_t >(sbrk (overflow_brk));
124
+ }
125
+ if (cur_brk >= overflow_brk) {
126
+ ASSERT_EQ (reinterpret_cast <void *>(-1 ), sbrk (SBRK_MAX));
127
+ #if defined(__BIONIC__)
128
+ // GLIBC does not set errno in overflow case.
129
+ ASSERT_EQ (ENOMEM, errno);
130
+ #endif
131
+ }
73
132
#endif
74
133
}
0 commit comments