| From: | Andrey Rachitskiy <pl0h0yp1(at)gmail(dot)com> |
|---|---|
| To: | ilia(dot)kashintsev(at)gmail(dot)com, pgsql-bugs(at)lists(dot)postgresql(dot)org |
| Subject: | Re: BUG #19612: SEGV in ParseConfigFp() in guc-file.l |
| Date: | 2026-08-11 06:30:03 |
| Message-ID: | CAB8bMivnXcb7RRd=EKdY_nBOqR=6iJPwZx1oEGz+ayfqzj9HVQ@mail.gmail.com |
| Views: | Whole Thread | Raw Message | Download mbox | Resend email |
| Thread: | |
| Lists: | pgsql-bugs |
Hi, Ilia!
Thanks for the report.
fopen() of a directory can succeed. Flex then fails with "input in
flex scanner failed". GUC_flex_fatal() longjmps to ParseConfigFp()
cleanup, which calls yy_delete_buffer()/yylex_destroy() and crashes.
Commit 4b496a3583e already marked the YY_BUFFER_STATE local volatile
for that longjmp path. Commit d663f150b5e made the scanner reentrant
and added a yyscan_t local used in the same cleanup. That local is
written after sigsetjmp and read after siglongjmp, but was not
volatile, so its value is indeterminate after the jump.
вт, 11 авг. 2026 г. в 09:55, PG Bug reporting form <noreply(at)postgresql(dot)org>:
> The following bug has been logged on the website:
>
> Bug reference: 19612
> Logged by: Ilia Kashintsev
> Email address: ilia(dot)kashintsev(at)gmail(dot)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 <ctype.h>
> +#include <sys/stat.h>
> #include <unistd.h>
>
> #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)
>
>
>
>
>
--
Regards,
Rachitskiy Andrey
| Attachment | Content-Type | Size |
|---|---|---|
| 0001-Fix-SEGV-after-flex-fatal-in-ParseConfigFp.patch | text/x-patch | 1.5 KB |
| From | Date | Subject | |
|---|---|---|---|
| Next Message | Andrey Rachitskiy | 2026-08-11 07:05:53 | Re: BUG #19613: pg_restore: several SEGVs in ReadToc() in pg_backup_archiver.c |
| Previous Message | PG Bug reporting form | 2026-08-11 02:34:38 | BUG #19615: COVAR_POP / COVAR_SAMP / REGR_SXY return 0.0 instead of NaN |