diff -Nru whoopsie-0.2.68/debian/changelog whoopsie-0.2.69/debian/changelog --- whoopsie-0.2.68/debian/changelog 2019-10-30 13:36:27.000000000 +0000 +++ whoopsie-0.2.69/debian/changelog 2019-11-04 23:33:08.000000000 +0000 @@ -1,3 +1,11 @@ +whoopsie (0.2.69) focal; urgency=medium + + * 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. + + -- Tiago Stürmer Daitx Mon, 04 Nov 2019 23:33:08 +0000 + whoopsie (0.2.68) focal; urgency=medium * lib/bson/bson.c: properly initialize bson_size variable. diff -Nru whoopsie-0.2.68/lib/bson/bson.c whoopsie-0.2.69/lib/bson/bson.c --- whoopsie-0.2.68/lib/bson/bson.c 2019-10-30 04:35:17.000000000 +0000 +++ whoopsie-0.2.69/lib/bson/bson.c 2019-10-31 21:01:10.000000000 +0000 @@ -24,7 +24,7 @@ #include "bson.h" #include "encoding.h" -const size_t initialBufferSize = 128; +const uint32_t initialBufferSize = 128; /* only need one of these */ static const int zero = 0; @@ -86,8 +86,8 @@ b->errstr = NULL; } -size_t bson_size( const bson *b ) { - size_t i; +uint32_t bson_size( const bson *b ) { + uint32_t i; if ( ! b || ! b->data ) return 0; bson_little_endian32( &i, b->data ); @@ -567,7 +567,7 @@ BUILDING ------------------------------ */ -static void _bson_init_size( bson *b, size_t size ) { +static void _bson_init_size( bson *b, uint32_t size ) { if( size == 0 ) b->data = NULL; else @@ -581,7 +581,7 @@ _bson_init_size( b, initialBufferSize ); } -void bson_init_size( bson *b, size_t size ) { +void bson_init_size( bson *b, uint32_t size ) { _bson_init_size( b, size ); } @@ -590,7 +590,7 @@ b->cur++; } -void bson_append( bson *b, const void *data, size_t len ) { +void bson_append( bson *b, const void *data, uint32_t len ) { memcpy( b->cur , data , len ); b->cur += len; } @@ -605,13 +605,13 @@ b->cur += 8; } -int bson_ensure_space( bson *b, const size_t bytesNeeded ) { - size_t pos = b->cur - b->data; +int bson_ensure_space( bson *b, const uint32_t bytesNeeded ) { + uint32_t pos = b->cur - b->data; char *orig = b->data; - size_t new_size; + uint32_t new_size; - if ( bytesNeeded > INT_MAX || pos > INT_MAX || b->dataSize > INT_MAX || - ( INT_MAX - b->dataSize ) < bytesNeeded || ( INT_MAX - pos) < bytesNeeded ) { + if ( bytesNeeded > INT32_MAX || pos > INT32_MAX || b->dataSize > INT32_MAX || + ( INT32_MAX - b->dataSize ) < bytesNeeded || ( INT32_MAX - pos) < bytesNeeded ) { b->err = BSON_SIZE_OVERFLOW; return BSON_ERROR; } @@ -621,8 +621,8 @@ new_size = 1.5 * ( b->dataSize + bytesNeeded ); - if ( new_size > INT_MAX) - new_size = INT_MAX; + if ( new_size > INT32_MAX) + new_size = INT32_MAX; b->data = bson_realloc( b->data, new_size ); if ( !b->data ) @@ -635,7 +635,7 @@ } int bson_finish( bson *b ) { - size_t i; + uint32_t i; if( b->err & BSON_NOT_UTF8 ) return BSON_ERROR; @@ -659,8 +659,8 @@ b->finished = 1; } -static int bson_append_estart( bson *b, int type, const char *name, const size_t dataSize ) { - const size_t len = strlen( name ) + 1; +static int bson_append_estart( bson *b, int type, const char *name, const uint32_t dataSize ) { + const uint32_t len = strlen( name ) + 1; if ( b->finished ) { b->err |= BSON_ALREADY_FINISHED; @@ -726,9 +726,9 @@ } int bson_append_string_base( bson *b, const char *name, - const char *value, size_t len, bson_type type ) { + const char *value, uint32_t len, bson_type type ) { - size_t sl = len + 1; + uint32_t sl = len + 1; if ( bson_check_string( b, ( const char * )value, sl - 1 ) == BSON_ERROR ) return BSON_ERROR; if ( bson_append_estart( b, type, name, 4 + sl ) == BSON_ERROR ) { @@ -741,7 +741,12 @@ } int bson_append_string( bson *b, const char *name, const char *value ) { - return bson_append_string_base( b, name, value, strlen ( value ), BSON_STRING ); + size_t len = strlen ( value ); + + if ( len > INT32_MAX ) + return BSON_ERROR; + + return bson_append_string_base( b, name, value, len, BSON_STRING ); } int bson_append_symbol( bson *b, const char *name, const char *value ) { @@ -835,7 +840,7 @@ int bson_append_element( bson *b, const char *name_or_null, const bson_iterator *elem ) { bson_iterator next = *elem; - size_t size; + uint32_t size; bson_iterator_next( &next ); size = next.cur - elem->cur; @@ -845,7 +850,7 @@ return BSON_ERROR; bson_append( b, elem->cur, size ); } else { - size_t data_size = size - 2 - strlen( bson_iterator_key( elem ) ); + uint32_t data_size = size - 2 - strlen( bson_iterator_key( elem ) ); bson_append_estart( b, elem->cur[0], name_or_null, data_size ); bson_append( b, bson_iterator_value( elem ), data_size ); } @@ -888,7 +893,7 @@ int bson_append_finish_object( bson *b ) { char *start; - size_t i; + uint32_t i; if ( bson_ensure_space( b, 1 ) == BSON_ERROR ) return BSON_ERROR; bson_append_byte( b , 0 ); @@ -914,14 +919,14 @@ return old; } -void *bson_malloc( size_t size ) { +void *bson_malloc( uint32_t size ) { void *p; p = bson_malloc_func( size ); bson_fatal_msg( !!p, "malloc() failed" ); return p; } -void *bson_realloc( void *ptr, size_t size ) { +void *bson_realloc( void *ptr, uint32_t size ) { void *p; p = bson_realloc_func( ptr, size ); bson_fatal_msg( !!p, "realloc() failed" ); diff -Nru whoopsie-0.2.68/lib/bson/bson.h whoopsie-0.2.69/lib/bson/bson.h --- whoopsie-0.2.68/lib/bson/bson.h 2019-10-30 04:35:17.000000000 +0000 +++ whoopsie-0.2.69/lib/bson/bson.h 2019-10-31 20:56:38.000000000 +0000 @@ -86,7 +86,7 @@ typedef struct { char *data; char *cur; - size_t dataSize; + uint32_t dataSize; bson_bool_t finished; int stack[32]; int stackPos; @@ -119,7 +119,7 @@ * * @return the size. */ -size_t bson_size( const bson *b ); +uint32_t bson_size( const bson *b ); /** * Print a string representation of a BSON object. @@ -546,7 +546,7 @@ * * @return BSON_OK or BSON_ERROR. */ -void bson_init_size( bson *b, size_t size ); +void bson_init_size( bson *b, uint32_t size ); /** * Grow a bson object. @@ -557,7 +557,7 @@ * @return BSON_OK or BSON_ERROR with the bson error object set. * Exits if allocation fails. */ -int bson_ensure_space( bson *b, const size_t bytesNeeded ); +int bson_ensure_space( bson *b, const uint32_t bytesNeeded ); /** * Finalize a bson object. @@ -930,7 +930,7 @@ * * @sa malloc(3) */ -void *bson_malloc( size_t size ); +void *bson_malloc( uint32_t size ); /** * Changes the size of allocated memory and checks return value, @@ -943,7 +943,7 @@ * * @sa realloc() */ -void *bson_realloc( void *ptr, size_t size ); +void *bson_realloc( void *ptr, uint32_t size ); /** * Set a function for error handling. diff -Nru whoopsie-0.2.68/lib/bson/encoding.c whoopsie-0.2.69/lib/bson/encoding.c --- whoopsie-0.2.68/lib/bson/encoding.c 2019-10-30 04:35:17.000000000 +0000 +++ whoopsie-0.2.69/lib/bson/encoding.c 2019-10-31 20:58:17.000000000 +0000 @@ -67,7 +67,7 @@ * If presented with a length > 4, this returns 0. The Unicode * definition of UTF-8 goes up to 4-byte sequences. */ -static int isLegalUTF8( const unsigned char *source, size_t length ) { +static int isLegalUTF8( const unsigned char *source, uint32_t length ) { unsigned char a; const unsigned char *srcptr = source + length; switch ( length ) { @@ -102,11 +102,11 @@ } static int bson_validate_string( bson *b, const unsigned char *string, - const size_t length, const char check_utf8, const char check_dot, + const uint32_t length, const char check_utf8, const char check_dot, const char check_dollar ) { - size_t position = 0; - size_t sequence_length = 1; + uint32_t position = 0; + uint32_t sequence_length = 1; if( check_dollar && string[0] == '$' ) { b->err |= BSON_FIELD_INIT_DOLLAR; @@ -136,13 +136,13 @@ int bson_check_string( bson *b, const char *string, - const size_t length ) { + const uint32_t length ) { return bson_validate_string( b, ( const unsigned char * )string, length, 1, 0, 0 ); } int bson_check_field_name( bson *b, const char *string, - const size_t length ) { + const uint32_t length ) { return bson_validate_string( b, ( const unsigned char * )string, length, 1, 1, 1 ); } diff -Nru whoopsie-0.2.68/lib/bson/encoding.h whoopsie-0.2.69/lib/bson/encoding.h --- whoopsie-0.2.68/lib/bson/encoding.h 2019-10-30 04:35:17.000000000 +0000 +++ whoopsie-0.2.69/lib/bson/encoding.h 2019-10-31 20:58:47.000000000 +0000 @@ -35,7 +35,7 @@ * Set the value of b->err appropriately. */ int bson_check_field_name( bson *b, const char *string, - const size_t length ); + const uint32_t length ); /** * Check that a string is valid UTF8. Sets the buffer bit field appropriately. @@ -48,7 +48,7 @@ * Sets b->err on error. */ bson_bool_t bson_check_string( bson *b, const char *string, - const size_t length ); + const uint32_t length ); MONGO_EXTERN_C_END #endif diff -Nru whoopsie-0.2.68/src/whoopsie.c whoopsie-0.2.69/src/whoopsie.c --- whoopsie-0.2.68/src/whoopsie.c 2019-10-30 04:35:17.000000000 +0000 +++ whoopsie-0.2.69/src/whoopsie.c 2019-10-31 21:01:10.000000000 +0000 @@ -261,7 +261,7 @@ gboolean bsonify (GHashTable* report, bson* b, const char** bson_message, - size_t* bson_message_len) + uint32_t* bson_message_len) { /* Attempt to convert a #GHashTable of the report into a BSON string. * On error return %FALSE. */ @@ -295,7 +295,7 @@ } int -upload_report (const char* message_data, size_t message_len, GString *s) +upload_report (const char* message_data, uint32_t message_len, GString *s) { CURL* curl = NULL; CURLcode result_code = 0; @@ -665,7 +665,7 @@ { GHashTable* report = NULL; gboolean success = FALSE; - size_t message_len = 0; + uint32_t message_len = 0; const char* message_data = NULL; GError* error = NULL; bson b[1];