Skip to content

Commit

Permalink
Add check for malloc failure in libpq calls
Browse files Browse the repository at this point in the history
The functions `PQconndefaults` and `PQmakeEmptyPGresult` calls
`malloc` and can return NULL if it fails to allocate memory for the
defaults and the empty result. It is checked with an `Assert`, but this
will be removed in production builds.

Replace the `Assert` with an checks to generate an error in production
builds rather than trying to de-reference the pointer and cause a
crash.
  • Loading branch information
mkindahl committed Mar 16, 2023
1 parent 790b322 commit 67ff84e
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ accidentally triggering the load of a previous DB version.**
* #5233 Out of on_proc_exit slots on guc license change
* #5427 Handle user-defined FDW options properly
* #5442 Decompression may have lost DEFAULT values
* #5446 Add checks for malloc failure in libpq calls

**Thanks**
* @nikolaps for reporting an issue with the COPY fetcher
Expand Down
8 changes: 8 additions & 0 deletions src/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@
/* find the length of a statically sized array */
#define TS_ARRAY_LEN(array) (sizeof(array) / sizeof(*array))

/* Use condition to check if out of memory */
#define TS_OOM_CHECK(COND, FMT, ...) \
do \
{ \
if (!(COND)) \
ereport(ERROR, (errcode(ERRCODE_OUT_OF_MEMORY), errmsg(FMT, ##__VA_ARGS__))); \
} while (0)

extern TSDLLEXPORT bool ts_type_is_int8_binary_compatible(Oid sourcetype);

typedef enum TimevalInfinity
Expand Down
5 changes: 3 additions & 2 deletions tsl/src/remote/connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -546,7 +546,7 @@ unset_libpq_envvar(void)
PQconninfoOption *lopt;
PQconninfoOption *options = PQconndefaults();

Assert(options != NULL);
TS_OOM_CHECK(options, "out of memory");

/* Explicitly unset all libpq environment variables.
*
Expand Down Expand Up @@ -1024,6 +1024,7 @@ remote_connection_get_result(const TSConnection *conn, TimestampTz endtime)
if (PQconsumeInput(conn->pg_conn) == 0)
{
pgres = PQmakeEmptyPGresult(conn->pg_conn, PGRES_FATAL_ERROR);
TS_OOM_CHECK(pgres, "out of memory");
PQfireResultCreateEvents(conn->pg_conn, pgres);
return pgres;
}
Expand Down Expand Up @@ -1102,6 +1103,7 @@ remote_connection_exec_timeout(TSConnection *conn, const char *cmd, TimestampTz
if (ret == 0)
{
res = PQmakeEmptyPGresult(conn->pg_conn, PGRES_FATAL_ERROR);
TS_OOM_CHECK(res, "out of memory");
PQfireResultCreateEvents(conn->pg_conn, res);
return res;
}
Expand Down Expand Up @@ -2522,7 +2524,6 @@ remote_connection_end_copy(TSConnection *conn, TSConnectionError *err)
}
}

Assert(res == NULL);
remote_connection_set_status(conn, CONN_IDLE);

return success;
Expand Down

0 comments on commit 67ff84e

Please sign in to comment.