The branch, master has been updated
       via  a97c78fb221 lzxpress: add bounds checking to lzxpress_decompress()
      from  f50987df038 winbind: directly use 
dcerpc_binding_handle_is_connected() in reset_connection_on_error() SAMR code

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit a97c78fb221a2f1aaca2effdb44c51e4f78ddd93
Author: Stefan Metzmacher <me...@samba.org>
Date:   Thu Nov 7 10:03:36 2019 +0100

    lzxpress: add bounds checking to lzxpress_decompress()
    
    lzxpress_decompress() would wander past the end of the array in
    numerous locations.
    
    Credit to OSS-Fuzz.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14190
    REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=19382
    REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=20083
    REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=22485
    REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=22667
    
    Signed-off-by: Stefan Metzmacher <me...@samba.org>
    Reviewed-by: Douglas Bagnall <douglas.bagn...@catalyst.net.nz>
    
    Autobuild-User(master): Douglas Bagnall <dbagn...@samba.org>
    Autobuild-Date(master): Sun Aug  9 00:30:26 UTC 2020 on sn-devel-184

-----------------------------------------------------------------------

Summary of changes:
 lib/compression/lzxpress.c | 32 ++++++++++++++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/compression/lzxpress.c b/lib/compression/lzxpress.c
index 024aba4c2ce..d8326304455 100644
--- a/lib/compression/lzxpress.c
+++ b/lib/compression/lzxpress.c
@@ -252,8 +252,24 @@ ssize_t lzxpress_decompress(const uint8_t *input,
        offset = 0;
        nibble_index = 0;
 
+#define __CHECK_BYTES(__size, __index, __needed) do { \
+       if (unlikely(__index >= __size)) { \
+               return -1; \
+       } else { \
+               uint32_t __avail = __size - __index; \
+               if (unlikely(__needed > __avail)) { \
+                       return -1; \
+               } \
+       } \
+} while(0)
+#define CHECK_INPUT_BYTES(__needed) \
+       __CHECK_BYTES(input_size, input_index, __needed)
+#define CHECK_OUTPUT_BYTES(__needed) \
+       __CHECK_BYTES(max_output_size, output_index, __needed)
+
        do {
                if (indicator_bit == 0) {
+                       CHECK_INPUT_BYTES(4);
                        indicator = PULL_LE_UINT32(input, input_index);
                        input_index += sizeof(uint32_t);
                        indicator_bit = 32;
@@ -266,10 +282,13 @@ ssize_t lzxpress_decompress(const uint8_t *input,
                 * check whether the 4th bit of the value in indicator is set
                 */
                if (((indicator >> indicator_bit) & 1) == 0) {
+                       CHECK_INPUT_BYTES(1);
+                       CHECK_OUTPUT_BYTES(1);
                        output[output_index] = input[input_index];
                        input_index += sizeof(uint8_t);
                        output_index += sizeof(uint8_t);
                } else {
+                       CHECK_INPUT_BYTES(2);
                        length = PULL_LE_UINT16(input, input_index);
                        input_index += sizeof(uint16_t);
                        offset = length / 8;
@@ -277,6 +296,7 @@ ssize_t lzxpress_decompress(const uint8_t *input,
 
                        if (length == 7) {
                                if (nibble_index == 0) {
+                                       CHECK_INPUT_BYTES(1);
                                        nibble_index = input_index;
                                        length = input[input_index] % 16;
                                        input_index += sizeof(uint8_t);
@@ -286,9 +306,11 @@ ssize_t lzxpress_decompress(const uint8_t *input,
                                }
 
                                if (length == 15) {
+                                       CHECK_INPUT_BYTES(1);
                                        length = input[input_index];
                                        input_index += sizeof(uint8_t);
                                        if (length == 255) {
+                                               CHECK_INPUT_BYTES(2);
                                                length = PULL_LE_UINT16(input, 
input_index);
                                                input_index += sizeof(uint16_t);
                                                length -= (15 + 7);
@@ -299,10 +321,16 @@ ssize_t lzxpress_decompress(const uint8_t *input,
                        }
 
                        length += 3;
+                       if (length == 0) {
+                               return -1;
+                       }
 
-                       do {
-                               if ((output_index >= max_output_size) || 
((offset + 1) > output_index)) break;
+                       if (offset >= output_index) {
+                               return -1;
+                       }
+                       CHECK_OUTPUT_BYTES(length);
 
+                       do {
                                output[output_index] = output[output_index - 
offset - 1];
 
                                output_index += sizeof(uint8_t);


-- 
Samba Shared Repository

Reply via email to