From 3c18d90f8907e53c3021fca13ad046133c480e4d Mon Sep 17 00:00:00 2001 From: Tomas Vondra Date: Wed, 17 May 2023 16:35:17 +0200 Subject: [PATCH] Null-terminate the output buffer of LZ4Stream_gets 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 Reported-by: Alexander Lakhin Discussion: https://postgr.es/m/94ae9bca-5ebb-1e68-bb7b-4f32e89fefbe@gmail.com --- src/bin/pg_dump/compress_lz4.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/bin/pg_dump/compress_lz4.c b/src/bin/pg_dump/compress_lz4.c index 423e1b7976..f97b7550d1 100644 --- a/src/bin/pg_dump/compress_lz4.c +++ b/src/bin/pg_dump/compress_lz4.c @@ -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; }