Fix PGTYPESdate_fmt_asc overflow when a year does not fit "yyyy"

Started by Andrey Rachitskiy13 days ago4 messageshackers
Beta feature

Hackorum builds and tests every patch posted to the lists, not only commitfest submissions. This is Hackorum's own CI rather than the PostgreSQL project's, and it is still under testing - please report anything that looks wrong.

appliessuccessCI history

You can run a PostgreSQL built from this patch straight from Docker, with no checkout and no build:

docker run --rm -p 5432:5432 ghcr.io/hackorum-dev/postgres-patch:t253376
psql -h localhost -U postgres

Built from patchset v4 (message #4), August 23, 2026 at 07:24 AM.

Every patchset is also pushed to a branch of our PostgreSQL fork, so you can check out the same tree CI built. Without a PostgreSQL checkout:

git clone --branch t253376_4 https://github.com/hackorum-dev/postgres.git

In a checkout you already have, add the fork once:

git remote add hackorum https://github.com/hackorum-dev/postgres.git

then, for this patchset and every later one:

git fetch hackorum t253376_4 && git checkout t253376_4

Patchset v4 (message #4) is on t253376_4

Jump to latest
#1Andrey Rachitskiy
pl0h0yp1@gmail.com

Hi, Hackers!

PGTYPESdate_fmt_asc() replaces fixed-width tokens in place. "yyyy"
is four characters. Callers typically size outbuf as
strlen(fmtstring)+1, as dt_test does.

For year >= 10000, "%04u" produces five or more digits. memcpy()
over the "yyyy" span overruns that token and clobbers the trailing
NUL in a strlen(fmt)+1 buffer. ASan reports a heap-buffer-overflow
on the next strstr() in the token loop.
```
const char *fmt = "yyyy";
date d = PGTYPESdate_from_asc("10000-01-01", NULL);
char *out = malloc(strlen(fmt) + 1);

PGTYPESdate_fmt_asc(d, fmt, out);
```
The attached patch rejects a replacement longer than the token and
sets errno to PGTYPES_DATE_BAD_DATE. A dt_test case is included.

--
Regards,
Rachitskiy Andrey

Attachments:

t253376_1
0001-ecpg-date-fmt-asc-year-overflow.patchtext/x-patch; charset=US-ASCII; name=0001-ecpg-date-fmt-asc-year-overflow.patchDownload+66-29
#2Andrey Rachitskiy
pl0h0yp1@gmail.com
In reply to: Andrey Rachitskiy (#1)
Re: Fix PGTYPESdate_fmt_asc overflow when a year does not fit "yyyy"

вт, 11 авг. 2026 г. в 19:31, Andrey Rachitskiy <pl0h0yp1@gmail.com>:

Hi, Hackers!

PGTYPESdate_fmt_asc() replaces fixed-width tokens in place. "yyyy"
is four characters. Callers typically size outbuf as
strlen(fmtstring)+1, as dt_test does.

For year >= 10000, "%04u" produces five or more digits. memcpy()
over the "yyyy" span overruns that token and clobbers the trailing
NUL in a strlen(fmt)+1 buffer. ASan reports a heap-buffer-overflow
on the next strstr() in the token loop.
```
const char *fmt = "yyyy";
date d = PGTYPESdate_from_asc("10000-01-01", NULL);
char *out = malloc(strlen(fmt) + 1);

PGTYPESdate_fmt_asc(d, fmt, out);
```
The attached patch rejects a replacement longer than the token and
sets errno to PGTYPES_DATE_BAD_DATE. A dt_test case is included.

Hi, All!

Maybe someone will have some free time to do a review. Thanks a lot in
advance.

--
Regards,
Rachitskiy Andrey

#3Zsolt Parragi
zsolt.parragi@percona.com
In reply to: Andrey Rachitskiy (#2)
Re: Fix PGTYPESdate_fmt_asc overflow when a year does not fit "yyyy"

Hello!

-[NO_PID]: ECPGtrans on line 393: action "rollback"; connection "ecpg1_regression"
+[NO_PID]: ECPGtrans on line 412: action "rollback"; connection "ecpg1_regression"

The modified test is failing in my run, it seems this should be 409?

#4Andrey Rachitskiy
pl0h0yp1@gmail.com
In reply to: Zsolt Parragi (#3)
Re: Fix PGTYPESdate_fmt_asc overflow when a year does not fit "yyyy"

чт, 20 авг. 2026 г. в 03:17, Zsolt Parragi <zsolt.parragi@percona.com>:

Hello!

-[NO_PID]: ECPGtrans on line 393: action "rollback"; connection
"ecpg1_regression"
+[NO_PID]: ECPGtrans on line 412: action "rollback"; connection
"ecpg1_regression"

The modified test is failing in my run, it seems this should be 409?

Dear Zsolt,

Thanks for the review.

After shortening the test comment I updated the expected .c #line
markers but forgot the matching stderr line number. Fixed in the
attached v2.

--
Regards,
Rachitskiy Andrey

Attachments:

t253376_4
v2-0001-ecpg-date-fmt-asc-year-overflow.patchtext/x-patch; charset=US-ASCII; name=v2-0001-ecpg-date-fmt-asc-year-overflow.patchDownload+66-29