initdb SegFault

Started by vignesh Calmost 7 years ago5 messageshackersbugs
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.

won't retrysuccessCI 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:t41537
psql -h localhost -U postgres

Built from patchset v1 (message #1), July 28, 2026 at 03:29 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 t41537_1 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 t41537_1 && git checkout t41537_1

Patchset v1 (message #1) is on t41537_1

Jump to latest
#1vignesh C
vignesh21@gmail.com
hackersbugs

Hi,

While checking initdb code, I found one segmentation fault, stack
trace for the same is:
Core was generated by `./initdb -D data6'.
Program terminated with signal 11, Segmentation fault.
#0 0x000000000040ea22 in main (argc=3, argv=0x7ffc82237308) at initdb.c:3340
3340 printf(_("\nSuccess. You can now start the database server
using:\n\n"

Analysis for the same is given below:
createPQExpBuffer allocates memory and returns the pointer, there is a
possibility that createPQExpBuffer can return NULL pointer in case of
malloc failiure, but initdb's main function does not check this
condition. During malloc failure when pointer is accessed it results
in segmentation fault. Made changes to check and exit if
createPQExpBuffer return's NULL pointer. Patch for the same is
attached.

Let me know your thoughts for the same. Similar issue exists in few
other places, if changes are ok, I can check and fix the issue in
other places also.

Regards,
Vignesh
EnterpriseDB: http://www.enterprisedb.com

Attachments:

t41537_1
0001-initdb-crash-fix-when-createPQExpBuffer-returns-NULL.patchtext/x-patch; charset=US-ASCII; name=0001-initdb-crash-fix-when-createPQExpBuffer-returns-NULL.patchDownload+5-1
#2Tom Lane
tgl@sss.pgh.pa.us
In reply to: vignesh C (#1)
hackersbugs
Re: initdb SegFault

vignesh C <vignesh21@gmail.com> writes:

createPQExpBuffer allocates memory and returns the pointer, there is a
possibility that createPQExpBuffer can return NULL pointer in case of
malloc failiure, but initdb's main function does not check this
condition. During malloc failure when pointer is accessed it results
in segmentation fault. Made changes to check and exit if
createPQExpBuffer return's NULL pointer. Patch for the same is
attached.

I can't get excited about this, for several reasons.

1) The probability of it happening in the field is not
distinguishable from zero, surely. I imagine you forced this
failure by making a debugging malloc fail occasionally.

2) If we really are out of memory at this point, we'd have just as good
odds that some allocation request inside pg_log_error() would fail.
There's no practical way to ensure that that code path remains free
of malloc attempts. (Not to mention cleanup_directories_atexit().)

3) In the end, an initdb failure is an initdb failure. This change
doesn't improve robustness by any useful metric, it just adds an
untestable code path. If we could recover somehow, it'd be more
interesting to spend time on.

BTW, looking at the small minority of places that bother to test
for createPQExpBuffer failure, the correct test for that seems
to be PQExpBufferBroken().

regards, tom lane

#3Andres Freund
andres@anarazel.de
In reply to: Tom Lane (#2)
hackersbugs
Re: initdb SegFault

Hi,

On 2019-11-19 10:16:02 -0500, Tom Lane wrote:

vignesh C <vignesh21@gmail.com> writes:

createPQExpBuffer allocates memory and returns the pointer, there is a
possibility that createPQExpBuffer can return NULL pointer in case of
malloc failiure, but initdb's main function does not check this
condition. During malloc failure when pointer is accessed it results
in segmentation fault. Made changes to check and exit if
createPQExpBuffer return's NULL pointer. Patch for the same is
attached.

I can't get excited about this, for several reasons.

1) The probability of it happening in the field is not
distinguishable from zero, surely. I imagine you forced this
failure by making a debugging malloc fail occasionally.

Agreed wrt this specific failure scenario. It does however seem not
great that callsites for PQExpBuffer ought to check every call for
allocation failures, in the general case.

I do think it'd be reasonable to move the cases where "graceful" dealing
with OOM isn't necessary ought to really use an interface that
internally errors out on memory allocation failures. Kinda thinking we
ought to slowly move such paths towards stringinfo...

2) If we really are out of memory at this point, we'd have just as good
odds that some allocation request inside pg_log_error() would fail.
There's no practical way to ensure that that code path remains free
of malloc attempts. (Not to mention cleanup_directories_atexit().)

I wonder if, for frontend paths, a simplified error handling path would
be worthwhile for OOM paths. Doing only a write() or such to print an
error message.

Greetings,

Andres Freund

#4Tom Lane
tgl@sss.pgh.pa.us
In reply to: Andres Freund (#3)
hackersbugs
Re: initdb SegFault

Andres Freund <andres@anarazel.de> writes:

Agreed wrt this specific failure scenario. It does however seem not
great that callsites for PQExpBuffer ought to check every call for
allocation failures, in the general case.

It is possible to check just once at the end, using the PQExpBufferBroken
API, and I believe that libpq for instance is fairly careful about that.

I agree that programs that just need to print something and exit could
perhaps ask pqexpbuffer.c to handle that for them. (But initdb still
doesn't fall in that category, because of its very nontrivial atexit
handler :-(.)

I wonder if, for frontend paths, a simplified error handling path would
be worthwhile for OOM paths. Doing only a write() or such to print an
error message.

Perhaps. You wouldn't get any translation --- but then, gettext is
probably going to fail anyway under such conditions.

regards, tom lane

#5Kyotaro Horiguchi
horikyota.ntt@gmail.com
In reply to: Tom Lane (#4)
hackersbugs
Re: initdb SegFault

At Tue, 19 Nov 2019 12:06:50 -0500, Tom Lane <tgl@sss.pgh.pa.us> wrote in

Andres Freund <andres@anarazel.de> writes:

Agreed wrt this specific failure scenario. It does however seem not
great that callsites for PQExpBuffer ought to check every call for
allocation failures, in the general case.

It is possible to check just once at the end, using the PQExpBufferBroken
API, and I believe that libpq for instance is fairly careful about that.

FWIW, I looked though the callers of PQExpBuffer.

pqGetErrorNotice3 seems ingoring OOM on message buffer when !isError,
then sets NULL to res->errMsg. getParameterStatus doesn't check that
before use, too.

Most of the callers of PQExpBufferDataBroken use libpq_gettext("out of
memory"). And some of them do strdup(libpq_gettext()).

Not restricting to libpq functions,

dblink_connstr_check complains as "password is required" when
PQconninfoParse hits OOM.

libpqrcv_check_conninfo() will show '(null)' or maybe get SEGV on some
platforms when PQconninfoParse() hits OOM, since it uses err without
null checking. pg_basebackup, pg_dumpall and pg_isready is doing the
same thing.

I agree that programs that just need to print something and exit could
perhaps ask pqexpbuffer.c to handle that for them. (But initdb still
doesn't fall in that category, because of its very nontrivial atexit
handler :-(.)

I wonder if, for frontend paths, a simplified error handling path would
be worthwhile for OOM paths. Doing only a write() or such to print an
error message.

Perhaps. You wouldn't get any translation --- but then, gettext is
probably going to fail anyway under such conditions.

I think we should refrain from translating in the cases.

regards.

--
Kyotaro Horiguchi
NTT Open Source Software Center