BUG #19612: SEGV in ParseConfigFp() in guc-file.l

Поиск
Список
Период
Сортировка
Искать
От
PG Bug reporting form
Тема
BUG #19612: SEGV in ParseConfigFp() in guc-file.l
Дата
в 16:32:09
Msg-id
19612-24ccb4fc6da7786f@postgresql.org
Список
Дерево обсуждения
BUG #19612: SEGV in ParseConfigFp() in guc-file.l PG Bug reporting form <noreply@postgresql.org>
Re: BUG #19612: SEGV in ParseConfigFp() in guc-file.l Andrey Rachitskiy <pl0h0yp1@gmail.com>
The following bug has been logged on the website:

Bug reference:      19612
Logged by:          Ilia Kashintsev
Email address:      ilia.kashintsev@gmail.com
PostgreSQL version: 19beta2
Operating system:   Ubuntu 24.04.4 LTS
Description:        

Hello maintainers!
I have found a SEGV on unknown address in ParseConfigFp().

The error itself is caused by passing a directory to the "include"
statement in the configuration file. The current checks do not account
for such error, so the first reading attempt occurring via
"while ((token = yylex(scanner)))" -> yy_get_next_buffer -> YY_INPUT
results in a fatal Flex error. After that execution goes to the
cleanup, and the state is not "sane enough for yy_delete_buffer()",
resulting in a crash on dereferences in YY_CURRENT_BUFFER.

Steps to reproduce:

1) Build the project with ASAN;
sudo mkdir -p /builds2
sudo chown "$(whoami)" /builds2

mkdir -p asan_build
cd asan_build
export CC=clang
export CXX=clang++
export CFLAGS="-O1 -g -fsanitize=address -fno-omit-frame-pointer"
export CXXFLAGS="-O1 -g -fsanitize=address -fno-omit-frame-pointer"
export LDFLAGS="-fsanitize=address"

../postgres/configure --prefix=/builds2/pg-asan
make -j
sudo make install

2) Run with the example config:

echo "include 'directory'" > error.conf
mkdir directory
/builds2/pg-asan/bin/postgres -c config_file=./error.conf

Sanitizer output:
2026-08-06 11:47:13.488 GMT [219826] LOG:  input in flex scanner failed at
file "/home/reproduce/asan_build/directory" line 1
AddressSanitizer:DEADLYSIGNAL
=================================================================
==219826==ERROR: AddressSanitizer: SEGV on unknown address (pc
0x62a2e32967a3 bp 0x7ffc3751ed70 sp 0x7ffc3751eb20 T0)
==219826==The signal is caused by a READ memory access.
==219826==Hint: this fault was caused by a dereference of a high value
address (see register values below).  Disassemble the provided pc to learn
which register was used.
    #0 0x62a2e32967a3 in GUC_yy_delete_buffer
/home/reproduce/asan_build/src/backend/utils/misc/guc-file.c:1631:12
    #1 0x62a2e32967a3 in ParseConfigFp
/home/reproduce/asan_build/../postgres/src/backend/utils/misc/guc-file.l:562:2
    #2 0x62a2e3294d6e in ParseConfigFile
/home/reproduce/asan_build/../postgres/src/backend/utils/misc/guc-file.l:263:7
    #3 0x62a2e3296463 in ParseConfigFp
/home/reproduce/asan_build/../postgres/src/backend/utils/misc/guc-file.l:473:9
    #4 0x62a2e3294d6e in ParseConfigFile
/home/reproduce/asan_build/../postgres/src/backend/utils/misc/guc-file.l:263:7
    #5 0x62a2e3277058 in ProcessConfigFileInternal
/home/reproduce/asan_build/../postgres/src/backend/utils/misc/guc.c:299:7
    #6 0x62a2e3294b16 in ProcessConfigFile
/home/reproduce/asan_build/../postgres/src/backend/utils/misc/guc-file.l:153:9
    #7 0x62a2e327b0f0 in SelectConfigFiles
/home/reproduce/asan_build/../postgres/src/backend/utils/misc/guc.c:1733:2
    #8 0x62a2e2ccebcc in PostmasterMain
/home/reproduce/asan_build/../postgres/src/backend/postmaster/postmaster.c:790:7
    #9 0x62a2e2a01831 in main
/home/reproduce/asan_build/../postgres/src/backend/main/main.c:231:4
    #10 0x73e7983d71c9 in __libc_start_call_main
csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #11 0x73e7983d728a in __libc_start_main csu/../csu/libc-start.c:360:3
    #12 0x62a2e22c9ef4 in _start (/builds2/pg-asan/bin/postgres+0x381ef4)
(BuildId: 8022979c2ccf668e43e16c68d221ad47bf314c32)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV
/home/reproduce/asan_build/src/backend/utils/misc/guc-file.c:1631:12 in
GUC_yy_delete_buffer
==219826==ABORTING

Suggested fix:
Probably could be done more elegantly,
but a check for a directory resolves the issue:

diff --git a/src/backend/utils/misc/guc-file.l
b/src/backend/utils/misc/guc-file.l
index 58669a6..e6c810a 100644
--- a/src/backend/utils/misc/guc-file.l
+++ b/src/backend/utils/misc/guc-file.l
@@ -10,6 +10,7 @@
 #include "postgres.h"

 #include 
+#include 
 #include 

 #include "common/file_utils.h"
@@ -237,6 +238,18 @@ ParseConfigFile(const char *config_file, bool strict,
        }

        fp = AllocateFile(abs_path, "r");
+       if (fp)
+       {
+               struct stat st;
+
+               if (fstat(fileno(fp), &st) == 0 && S_ISDIR(st.st_mode))
+               {
+                       FreeFile(fp);
+                       fp = NULL;
+                       errno = EISDIR;
+               }
+       }
+
        if (!fp)
        {
                if (strict)




В списке pgsql-bugs по дате отправления
От: Daria Shanina
Дата:
От: PG Bug reporting form
Дата:
FAQ