Merge lp:~tdaitx/whoopsie/lp-1850608-security-regression into lp:whoopsie

Proposed by Tiago Stürmer Daitx on 2019-11-20
Status: Merged
Merged at revision: 710
Proposed branch: lp:~tdaitx/whoopsie/lp-1850608-security-regression
Merge into: lp:whoopsie
Diff against target: 341 lines (+54/-41)
6 files modified
debian/changelog (+8/-0)
lib/bson/bson.c (+29/-24)
lib/bson/bson.h (+6/-6)
lib/bson/encoding.c (+6/-6)
lib/bson/encoding.h (+2/-2)
src/whoopsie.c (+3/-3)
To merge this branch: bzr merge lp:~tdaitx/whoopsie/lp-1850608-security-regression
Reviewer Review Type Date Requested Status
Brian Murray 2019-11-20 Approve on 2019-11-20
Review via email: mp+375788@code.launchpad.net

Description of the change

This merge request sync whoopsie with the latest release in Focal (0.2.69), fixing the last security update which introduced a bug for big endian archs - it is also a improved fix from the previous release (0.2.68).

Changelog:
* SECURITY REGRESSION: segfault when sending crash report (LP: #1850608)
  - use uint32_t instead of size_t and INT32_MAX instead of INT_MAX
    as bson expects variable sizes to be 32 bits long.

To post a comment you must log in.
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2019-10-30 17:55:35 +0000
3+++ debian/changelog 2019-11-20 20:32:05 +0000
4@@ -1,3 +1,11 @@
5+whoopsie (0.2.69) focal; urgency=medium
6+
7+ * SECURITY REGRESSION: segfault when sending crash report (LP: #1850608)
8+ - use uint32_t instead of size_t and INT32_MAX instead of INT_MAX
9+ as bson expects variable sizes to be 32 bits long.
10+
11+ -- Tiago Stürmer Daitx <tiago.daitx@ubuntu.com> Mon, 04 Nov 2019 23:33:08 +0000
12+
13 whoopsie (0.2.68) focal; urgency=medium
14
15 * lib/bson/bson.c: properly initialize bson_size variable.
16
17=== modified file 'lib/bson/bson.c'
18--- lib/bson/bson.c 2019-10-30 17:55:35 +0000
19+++ lib/bson/bson.c 2019-11-20 20:32:05 +0000
20@@ -24,7 +24,7 @@
21 #include "bson.h"
22 #include "encoding.h"
23
24-const size_t initialBufferSize = 128;
25+const uint32_t initialBufferSize = 128;
26
27 /* only need one of these */
28 static const int zero = 0;
29@@ -86,8 +86,8 @@
30 b->errstr = NULL;
31 }
32
33-size_t bson_size( const bson *b ) {
34- size_t i = 0;
35+uint32_t bson_size( const bson *b ) {
36+ uint32_t i;
37 if ( ! b || ! b->data )
38 return 0;
39 bson_little_endian32( &i, b->data );
40@@ -567,7 +567,7 @@
41 BUILDING
42 ------------------------------ */
43
44-static void _bson_init_size( bson *b, size_t size ) {
45+static void _bson_init_size( bson *b, uint32_t size ) {
46 if( size == 0 )
47 b->data = NULL;
48 else
49@@ -581,7 +581,7 @@
50 _bson_init_size( b, initialBufferSize );
51 }
52
53-void bson_init_size( bson *b, size_t size ) {
54+void bson_init_size( bson *b, uint32_t size ) {
55 _bson_init_size( b, size );
56 }
57
58@@ -590,7 +590,7 @@
59 b->cur++;
60 }
61
62-void bson_append( bson *b, const void *data, size_t len ) {
63+void bson_append( bson *b, const void *data, uint32_t len ) {
64 memcpy( b->cur , data , len );
65 b->cur += len;
66 }
67@@ -605,13 +605,13 @@
68 b->cur += 8;
69 }
70
71-int bson_ensure_space( bson *b, const size_t bytesNeeded ) {
72- size_t pos = b->cur - b->data;
73+int bson_ensure_space( bson *b, const uint32_t bytesNeeded ) {
74+ uint32_t pos = b->cur - b->data;
75 char *orig = b->data;
76- size_t new_size;
77+ uint32_t new_size;
78
79- if ( bytesNeeded > INT_MAX || pos > INT_MAX || b->dataSize > INT_MAX ||
80- ( INT_MAX - b->dataSize ) < bytesNeeded || ( INT_MAX - pos) < bytesNeeded ) {
81+ if ( bytesNeeded > INT32_MAX || pos > INT32_MAX || b->dataSize > INT32_MAX ||
82+ ( INT32_MAX - b->dataSize ) < bytesNeeded || ( INT32_MAX - pos) < bytesNeeded ) {
83 b->err = BSON_SIZE_OVERFLOW;
84 return BSON_ERROR;
85 }
86@@ -621,8 +621,8 @@
87
88 new_size = 1.5 * ( b->dataSize + bytesNeeded );
89
90- if ( new_size > INT_MAX)
91- new_size = INT_MAX;
92+ if ( new_size > INT32_MAX)
93+ new_size = INT32_MAX;
94
95 b->data = bson_realloc( b->data, new_size );
96 if ( !b->data )
97@@ -635,7 +635,7 @@
98 }
99
100 int bson_finish( bson *b ) {
101- size_t i;
102+ uint32_t i;
103
104 if( b->err & BSON_NOT_UTF8 )
105 return BSON_ERROR;
106@@ -659,8 +659,8 @@
107 b->finished = 1;
108 }
109
110-static int bson_append_estart( bson *b, int type, const char *name, const size_t dataSize ) {
111- const size_t len = strlen( name ) + 1;
112+static int bson_append_estart( bson *b, int type, const char *name, const uint32_t dataSize ) {
113+ const uint32_t len = strlen( name ) + 1;
114
115 if ( b->finished ) {
116 b->err |= BSON_ALREADY_FINISHED;
117@@ -726,9 +726,9 @@
118 }
119
120 int bson_append_string_base( bson *b, const char *name,
121- const char *value, size_t len, bson_type type ) {
122+ const char *value, uint32_t len, bson_type type ) {
123
124- size_t sl = len + 1;
125+ uint32_t sl = len + 1;
126 if ( bson_check_string( b, ( const char * )value, sl - 1 ) == BSON_ERROR )
127 return BSON_ERROR;
128 if ( bson_append_estart( b, type, name, 4 + sl ) == BSON_ERROR ) {
129@@ -741,7 +741,12 @@
130 }
131
132 int bson_append_string( bson *b, const char *name, const char *value ) {
133- return bson_append_string_base( b, name, value, strlen ( value ), BSON_STRING );
134+ size_t len = strlen ( value );
135+
136+ if ( len > INT32_MAX )
137+ return BSON_ERROR;
138+
139+ return bson_append_string_base( b, name, value, len, BSON_STRING );
140 }
141
142 int bson_append_symbol( bson *b, const char *name, const char *value ) {
143@@ -835,7 +840,7 @@
144
145 int bson_append_element( bson *b, const char *name_or_null, const bson_iterator *elem ) {
146 bson_iterator next = *elem;
147- size_t size;
148+ uint32_t size;
149
150 bson_iterator_next( &next );
151 size = next.cur - elem->cur;
152@@ -845,7 +850,7 @@
153 return BSON_ERROR;
154 bson_append( b, elem->cur, size );
155 } else {
156- size_t data_size = size - 2 - strlen( bson_iterator_key( elem ) );
157+ uint32_t data_size = size - 2 - strlen( bson_iterator_key( elem ) );
158 bson_append_estart( b, elem->cur[0], name_or_null, data_size );
159 bson_append( b, bson_iterator_value( elem ), data_size );
160 }
161@@ -888,7 +893,7 @@
162
163 int bson_append_finish_object( bson *b ) {
164 char *start;
165- size_t i;
166+ uint32_t i;
167 if ( bson_ensure_space( b, 1 ) == BSON_ERROR ) return BSON_ERROR;
168 bson_append_byte( b , 0 );
169
170@@ -914,14 +919,14 @@
171 return old;
172 }
173
174-void *bson_malloc( size_t size ) {
175+void *bson_malloc( uint32_t size ) {
176 void *p;
177 p = bson_malloc_func( size );
178 bson_fatal_msg( !!p, "malloc() failed" );
179 return p;
180 }
181
182-void *bson_realloc( void *ptr, size_t size ) {
183+void *bson_realloc( void *ptr, uint32_t size ) {
184 void *p;
185 p = bson_realloc_func( ptr, size );
186 bson_fatal_msg( !!p, "realloc() failed" );
187
188=== modified file 'lib/bson/bson.h'
189--- lib/bson/bson.h 2019-10-30 04:28:50 +0000
190+++ lib/bson/bson.h 2019-11-20 20:32:05 +0000
191@@ -86,7 +86,7 @@
192 typedef struct {
193 char *data;
194 char *cur;
195- size_t dataSize;
196+ uint32_t dataSize;
197 bson_bool_t finished;
198 int stack[32];
199 int stackPos;
200@@ -119,7 +119,7 @@
201 *
202 * @return the size.
203 */
204-size_t bson_size( const bson *b );
205+uint32_t bson_size( const bson *b );
206
207 /**
208 * Print a string representation of a BSON object.
209@@ -546,7 +546,7 @@
210 *
211 * @return BSON_OK or BSON_ERROR.
212 */
213-void bson_init_size( bson *b, size_t size );
214+void bson_init_size( bson *b, uint32_t size );
215
216 /**
217 * Grow a bson object.
218@@ -557,7 +557,7 @@
219 * @return BSON_OK or BSON_ERROR with the bson error object set.
220 * Exits if allocation fails.
221 */
222-int bson_ensure_space( bson *b, const size_t bytesNeeded );
223+int bson_ensure_space( bson *b, const uint32_t bytesNeeded );
224
225 /**
226 * Finalize a bson object.
227@@ -930,7 +930,7 @@
228 *
229 * @sa malloc(3)
230 */
231-void *bson_malloc( size_t size );
232+void *bson_malloc( uint32_t size );
233
234 /**
235 * Changes the size of allocated memory and checks return value,
236@@ -943,7 +943,7 @@
237 *
238 * @sa realloc()
239 */
240-void *bson_realloc( void *ptr, size_t size );
241+void *bson_realloc( void *ptr, uint32_t size );
242
243 /**
244 * Set a function for error handling.
245
246=== modified file 'lib/bson/encoding.c'
247--- lib/bson/encoding.c 2019-10-30 04:28:50 +0000
248+++ lib/bson/encoding.c 2019-11-20 20:32:05 +0000
249@@ -67,7 +67,7 @@
250 * If presented with a length > 4, this returns 0. The Unicode
251 * definition of UTF-8 goes up to 4-byte sequences.
252 */
253-static int isLegalUTF8( const unsigned char *source, size_t length ) {
254+static int isLegalUTF8( const unsigned char *source, uint32_t length ) {
255 unsigned char a;
256 const unsigned char *srcptr = source + length;
257 switch ( length ) {
258@@ -102,11 +102,11 @@
259 }
260
261 static int bson_validate_string( bson *b, const unsigned char *string,
262- const size_t length, const char check_utf8, const char check_dot,
263+ const uint32_t length, const char check_utf8, const char check_dot,
264 const char check_dollar ) {
265
266- size_t position = 0;
267- size_t sequence_length = 1;
268+ uint32_t position = 0;
269+ uint32_t sequence_length = 1;
270
271 if( check_dollar && string[0] == '$' ) {
272 b->err |= BSON_FIELD_INIT_DOLLAR;
273@@ -136,13 +136,13 @@
274
275
276 int bson_check_string( bson *b, const char *string,
277- const size_t length ) {
278+ const uint32_t length ) {
279
280 return bson_validate_string( b, ( const unsigned char * )string, length, 1, 0, 0 );
281 }
282
283 int bson_check_field_name( bson *b, const char *string,
284- const size_t length ) {
285+ const uint32_t length ) {
286
287 return bson_validate_string( b, ( const unsigned char * )string, length, 1, 1, 1 );
288 }
289
290=== modified file 'lib/bson/encoding.h'
291--- lib/bson/encoding.h 2019-10-30 04:28:50 +0000
292+++ lib/bson/encoding.h 2019-11-20 20:32:05 +0000
293@@ -35,7 +35,7 @@
294 * Set the value of b->err appropriately.
295 */
296 int bson_check_field_name( bson *b, const char *string,
297- const size_t length );
298+ const uint32_t length );
299
300 /**
301 * Check that a string is valid UTF8. Sets the buffer bit field appropriately.
302@@ -48,7 +48,7 @@
303 * Sets b->err on error.
304 */
305 bson_bool_t bson_check_string( bson *b, const char *string,
306- const size_t length );
307+ const uint32_t length );
308
309 MONGO_EXTERN_C_END
310 #endif
311
312=== modified file 'src/whoopsie.c'
313--- src/whoopsie.c 2019-10-30 04:28:50 +0000
314+++ src/whoopsie.c 2019-11-20 20:32:05 +0000
315@@ -261,7 +261,7 @@
316
317 gboolean
318 bsonify (GHashTable* report, bson* b, const char** bson_message,
319- size_t* bson_message_len)
320+ uint32_t* bson_message_len)
321 {
322 /* Attempt to convert a #GHashTable of the report into a BSON string.
323 * On error return %FALSE. */
324@@ -295,7 +295,7 @@
325 }
326
327 int
328-upload_report (const char* message_data, size_t message_len, GString *s)
329+upload_report (const char* message_data, uint32_t message_len, GString *s)
330 {
331 CURL* curl = NULL;
332 CURLcode result_code = 0;
333@@ -665,7 +665,7 @@
334 {
335 GHashTable* report = NULL;
336 gboolean success = FALSE;
337- size_t message_len = 0;
338+ uint32_t message_len = 0;
339 const char* message_data = NULL;
340 GError* error = NULL;
341 bson b[1];

Subscribers

People subscribed via source and target branches

to status/vote changes: