diff --git a/ChangeLog b/ChangeLog index f7e74ea..8907658 100644 --- a/ChangeLog +++ b/ChangeLog @@ -113,6 +113,9 @@ compiler warning. 27. Minor code refactor to avoid "left shift of negative number" warning. +28. Add a bit more sanity checking to pcre2_serialize_decode() and document +that it expects trusted data. + Version 10.21 12-January-2016 ----------------------------- diff --git a/doc/pcre2serialize.3 b/doc/pcre2serialize.3 index 69bcb18..891f224 100644 --- a/doc/pcre2serialize.3 +++ b/doc/pcre2serialize.3 @@ -1,4 +1,4 @@ -.TH PCRE2SERIALIZE 3 "03 November 2015" "PCRE2 10.21" +.TH PCRE2SERIALIZE 3 "24 May 2016" "PCRE2 10.22" .SH NAME PCRE2 - Perl-compatible regular expressions (revised API) .SH "SAVING AND RE-USING PRECOMPILED PCRE2 PATTERNS" @@ -30,6 +30,16 @@ PCRE2's 16-bit library cannot be reloaded on a 64-bit system, nor can they be reloaded using the 8-bit library. . . +.SH "SECURITY CONCERNS" +.rs +.sp +The facility for saving and restoring compiled patterns is intended for use +within individual applications. As such, the data supplied to +\fBpcre2_serialize_decode()\fP is expected to be trusted data, not data from +arbitrary external sources. There is only some simple consistency checking, not +complete validation of what is being re-loaded. +. +. .SH "SAVING COMPILED PATTERNS" .rs .sp @@ -129,11 +139,12 @@ is filled with those that fit, and the remainder are ignored. The yield of the function is the number of decoded patterns, or one of the following negative error codes: .sp - PCRE2_ERROR_BADDATA second argument is zero or less - PCRE2_ERROR_BADMAGIC mismatch of id bytes in the data - PCRE2_ERROR_BADMODE mismatch of variable unit size or PCRE2 version - PCRE2_ERROR_MEMORY memory allocation failed - PCRE2_ERROR_NULL first or third argument is NULL + PCRE2_ERROR_BADDATA second argument is zero or less + PCRE2_ERROR_BADMAGIC mismatch of id bytes in the data + PCRE2_ERROR_BADMODE mismatch of code unit size or PCRE2 version + PCRE2_ERROR_BADSERIALIZEDDATA other sanity check failure + PCRE2_ERROR_MEMORY memory allocation failed + PCRE2_ERROR_NULL first or third argument is NULL .sp PCRE2_ERROR_BADMAGIC may mean that the data is corrupt, or that it was compiled on a system with different endianness. @@ -170,6 +181,6 @@ Cambridge, England. .rs .sp .nf -Last updated: 03 November 2015 -Copyright (c) 1997-2015 University of Cambridge. +Last updated: 24 May 2016 +Copyright (c) 1997-2016 University of Cambridge. .fi diff --git a/src/pcre2.h b/src/pcre2.h index b2153d9..f74765a 100644 --- a/src/pcre2.h +++ b/src/pcre2.h @@ -245,6 +245,7 @@ numbers must not be changed. */ #define PCRE2_ERROR_BADSUBSTITUTION (-59) #define PCRE2_ERROR_BADSUBSPATTERN (-60) #define PCRE2_ERROR_TOOMANYREPLACE (-61) +#define PCRE2_ERROR_BADSERIALIZEDDATA (-62) /* Request types for pcre2_pattern_info() */ diff --git a/src/pcre2.h.in b/src/pcre2.h.in index 56c9651..3e03be8 100644 --- a/src/pcre2.h.in +++ b/src/pcre2.h.in @@ -245,6 +245,7 @@ numbers must not be changed. */ #define PCRE2_ERROR_BADSUBSTITUTION (-59) #define PCRE2_ERROR_BADSUBSPATTERN (-60) #define PCRE2_ERROR_TOOMANYREPLACE (-61) +#define PCRE2_ERROR_BADSERIALIZEDDATA (-62) /* Request types for pcre2_pattern_info() */ diff --git a/src/pcre2_error.c b/src/pcre2_error.c index c0e5366..5f2f505 100644 --- a/src/pcre2_error.c +++ b/src/pcre2_error.c @@ -252,6 +252,7 @@ static const unsigned char match_error_texts[] = /* 60 */ "match with end before start is not supported\0" "too many replacements (more than INT_MAX)\0" + "bad serialized data\0" ; diff --git a/src/pcre2_serialize.c b/src/pcre2_serialize.c index 8c44acf..0af26d8 100644 --- a/src/pcre2_serialize.c +++ b/src/pcre2_serialize.c @@ -158,6 +158,7 @@ int32_t i, j; if (data == NULL || codes == NULL) return PCRE2_ERROR_NULL; if (number_of_codes <= 0) return PCRE2_ERROR_BADDATA; +if (data->number_of_codes <= 0) return PCRE2_ERROR_BADSERIALIZEDDATA; if (data->magic != SERIALIZED_DATA_MAGIC) return PCRE2_ERROR_BADMAGIC; if (data->version != SERIALIZED_DATA_VERSION) return PCRE2_ERROR_BADMODE; if (data->config != SERIALIZED_DATA_CONFIG) return PCRE2_ERROR_BADMODE; @@ -188,6 +189,8 @@ for (i = 0; i < number_of_codes; i++) CODE_BLOCKSIZE_TYPE blocksize; memcpy(&blocksize, src_bytes + offsetof(pcre2_real_code, blocksize), sizeof(CODE_BLOCKSIZE_TYPE)); + if (blocksize <= sizeof(pcre2_real_code)) + return PCRE2_ERROR_BADSERIALIZEDDATA; /* The allocator provided by gcontext replaces the original one. */ @@ -208,6 +211,10 @@ for (i = 0; i < number_of_codes; i++) memcpy(((uint8_t *)dst_re) + sizeof(pcre2_memctl), src_bytes + sizeof(pcre2_memctl), blocksize - sizeof(pcre2_memctl)); + if (dst_re->magic_number != MAGIC_NUMBER || + dst_re->name_entry_size > MAX_NAME_SIZE + IMM2_SIZE + 1 || + dst_re->name_count > MAX_NAME_COUNT) + return PCRE2_ERROR_BADSERIALIZEDDATA; /* At the moment only one table is supported. */