Null-terminate the output buffer of LZ4Stream_gets
authorTomas Vondra <[email protected]>
Wed, 17 May 2023 14:35:17 +0000 (16:35 +0200)
committerTomas Vondra <[email protected]>
Wed, 17 May 2023 14:35:30 +0000 (16:35 +0200)
LZ4Stream_gets did not null-terminate its output buffer. The callers expected
the buffer to be null-terminated and passed it around to functions such as
sscanf with unintended consequences.

Author: Georgios Kokolatos <[email protected]>
Reported-by: Alexander Lakhin <[email protected]>
Discussion: https://postgr.es/m/94ae9bca-5ebb-1e68-bb7b-4f32e89fefbe@gmail.com

src/bin/pg_dump/compress_lz4.c

index 423e1b7976f033282be47b81d75a0c3bc7f4ee6a..f97b7550d1c7edf18a80b637f43e4cc8e498ae46 100644 (file)
@@ -459,6 +459,10 @@ LZ4Stream_read_internal(LZ4State *state, void *ptr, int ptrsize, bool eol_flag)
        if (!LZ4Stream_init(state, size, false /* decompressing */ ))
                return -1;
 
+       /* No work needs to be done for a zero-sized output buffer */
+       if (size <= 0)
+               return 0;
+
        /* Verify that there is enough space in the outbuf */
        if (size > state->buflen)
        {
@@ -636,7 +640,7 @@ LZ4Stream_gets(char *ptr, int size, CompressFileHandle *CFH)
        LZ4State   *state = (LZ4State *) CFH->private_data;
        int                     ret;
 
-       ret = LZ4Stream_read_internal(state, ptr, size, true);
+       ret = LZ4Stream_read_internal(state, ptr, size - 1, true);
        if (ret < 0 || (ret == 0 && !LZ4Stream_eof(CFH)))
                pg_fatal("could not read from input file: %s", LZ4Stream_get_error(CFH));
 
@@ -644,6 +648,12 @@ LZ4Stream_gets(char *ptr, int size, CompressFileHandle *CFH)
        if (ret == 0)
                return NULL;
 
+       /*
+        * Our caller expects the return string to be NULL terminated
+        * and we know that ret is greater than zero.
+        */
+       ptr[ret - 1] = '\0';
+
        return ptr;
 }