From 8ec00dc5cd70e0e579e9fbf8661bc46f5ccd8078 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Sat, 26 Jun 2021 14:20:17 -0400 Subject: [PATCH] Remove undesirable libpq dependency on stringinfo.c. Commit c0cb87fbb unwisely introduced a dependency on the StringInfo machinery in fe-connect.c. We must not use that in libpq, because it will do a summary exit(1) if it hits OOM, and that is not appropriate behavior for a general-purpose library. The goal of allowing arbitrary line lengths in service files doesn't seem like it's worth a lot of effort, so revert back to the previous method of using a stack-allocated buffer and failing on buffer overflow. This isn't an exact revert though. I kept that patch's refactoring to have a single exit path, as that seems cleaner than having each error path know what to do to clean up. Also, I made the fixed-size buffer 1024 bytes not 256, just to push off the need for an expandable buffer some more. There is more to do here; in particular the lack of any mechanical check for this type of mistake now seems pretty hazardous. But this fix gets us back to the level of robustness we had in v13, anyway. Discussion: https://postgr.es/m/daeb22ec6ca8ef61e94d766a9b35fb03cabed38e.camel@vmware.com --- src/interfaces/libpq/fe-connect.c | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c index 80703698b8..3faf05a7e7 100644 --- a/src/interfaces/libpq/fe-connect.c +++ b/src/interfaces/libpq/fe-connect.c @@ -28,7 +28,6 @@ #include "fe-auth.h" #include "libpq-fe.h" #include "libpq-int.h" -#include "lib/stringinfo.h" #include "mb/pg_wchar.h" #include "pg_config_paths.h" #include "port/pg_bswap.h" @@ -5163,7 +5162,7 @@ parseServiceFile(const char *serviceFile, i; FILE *f; char *line; - StringInfoData linebuf; + char buf[1024]; *group_found = false; @@ -5175,18 +5174,26 @@ parseServiceFile(const char *serviceFile, return 1; } - initStringInfo(&linebuf); - - while (pg_get_line_buf(f, &linebuf)) + while ((line = fgets(buf, sizeof(buf), f)) != NULL) { + int len; + linenr++; - /* ignore whitespace at end of line, especially the newline */ - while (linebuf.len > 0 && - isspace((unsigned char) linebuf.data[linebuf.len - 1])) - linebuf.data[--linebuf.len] = '\0'; + if (strlen(line) >= sizeof(buf) - 1) + { + appendPQExpBuffer(errorMessage, + libpq_gettext("line %d too long in service file \"%s\"\n"), + linenr, + serviceFile); + result = 2; + goto exit; + } - line = linebuf.data; + /* ignore whitespace at end of line, especially the newline */ + len = strlen(line); + while (len > 0 && isspace((unsigned char) line[len - 1])) + line[--len] = '\0'; /* ignore leading whitespace too */ while (*line && isspace((unsigned char) line[0])) @@ -5303,7 +5310,6 @@ parseServiceFile(const char *serviceFile, exit: fclose(f); - pfree(linebuf.data); return result; } -- 2.30.2