postgresql-interfaces/psqlodbc GitHub issues and pull requests (mirror)  
help / color / mirror / Atom feed
From: jarvis24young (@jarvis24young) <[email protected]>
To: postgresql-interfaces/psqlodbc <[email protected]>
Subject: [postgresql-interfaces/psqlodbc] issue #177: OOM: SQLAllocHandle(SQL_HANDLE_STMT) can segfault if ARD_AllocBookmark malloc fails
Date: Sat, 25 Apr 2026 04:01:49 +0000
Message-ID: <[email protected]> (raw)

# OOM: SQLAllocHandle(SQL_HANDLE_STMT) can segfault if ARD_AllocBookmark malloc fails

## Summary

While doing defensive robustness testing of psqlODBC, I found a NULL-dereference crash on the statement allocation path when an internal bookmark allocation fails.

This is an OOM/robustness issue. I am not claiming a practical remote exploit; the reproducer uses malloc-failure injection to force the allocation failure deterministically. The expected behavior would be to return an ODBC error/diagnostic instead of crashing the hosting process.

## Affected path

`SQLAllocHandle(SQL_HANDLE_STMT, ...)` reaches `PGAPI_AllocStmt()`, which calls `ARD_AllocBookmark()`:

```c
BindInfoClass *
ARD_AllocBookmark(ARDFields *ardopts)
{
    if (!ardopts->bookmark)
    {
        ardopts->bookmark = (BindInfoClass *) malloc(sizeof(BindInfoClass));
        pg_memset(ardopts->bookmark, 0, sizeof(BindInfoClass));
    }
    return ardopts->bookmark;
}
```

If `malloc(sizeof(BindInfoClass))` returns `NULL`, `pg_memset()` is called with a NULL pointer.

Observed call chain:

```text
SQLAllocHandle(SQL_HANDLE_STMT)
  -> PGAPI_AllocStmt              statement.c:232
     -> ARD_AllocBookmark         descriptor.c:345
        -> malloc(sizeof(BindInfoClass)) returns NULL
        -> pg_memset(NULL, ...)
```

On my x86_64 Linux build, `sizeof(BindInfoClass)` was 40 bytes.

## Reproducer

Environment used:

- Linux under WSL2
- unixODBC
- PostgreSQL test database
- psqlODBC built with debug/gcov flags, no ASan for this OOM injection run

A minimal black-box test only uses public ODBC APIs:

```c
SQLDriverConnect(...);
SQLAllocHandle(SQL_HANDLE_STMT, conn, &hstmt);
```

I forced the relevant allocation to fail with an `LD_PRELOAD` malloc shim that returns `NULL` on the Nth 40-byte allocation:

```bash
PODBC_FAIL_MALLOC_SIZE=40 PODBC_FAIL_MALLOC_N=178 \
LD_PRELOAD=./exe/malloc_fail_shim.so \
ODBCSYSINI=. ODBCINSTINI=./odbcinst.ini ODBCINI=./odbc.ini \
  ./exe/ard-bookmark-oom-bugwatch-test
```

Observed output:

```text
connected
allocating statement handle through SQLAllocHandle(SQL_HANDLE_STMT)
malloc-fail-shim: failing malloc(40) occurrence 178
../.libs/psqlodbcw.so(+0x8f5e9)
../.libs/psqlodbcw.so(+0x7cea0)
../.libs/psqlodbcw.so(SQLAllocHandle+0x20e)
oom_rc=139
```

Address mapping:

```text
driver +0x8f5e9:
ARD_AllocBookmark
.../descriptor.c:345

driver +0x7cea0:
PGAPI_AllocStmt
.../statement.c:232
```

Normal run without malloc failure completes successfully:

```text
connected
allocating statement handle through SQLAllocHandle(SQL_HANDLE_STMT)
SQLAllocHandle stmt rc=0 hstmt=...
disconnecting
statement allocation completed without crashing
```

## Expected behavior

If bookmark allocation fails during statement allocation, the driver should return an ODBC error, ideally with a memory-allocation diagnostic, rather than dereferencing NULL and crashing.

## Suggested fix direction

`ARD_AllocBookmark()` could return `NULL` when allocation fails, and callers that require the bookmark should handle that by setting an appropriate diagnostic and returning `SQL_ERROR`.

Known direct callers worth checking:

- `statement.c::PGAPI_AllocStmt()`
- `bind.c::PGAPI_BindCol()`
- `descriptor.c::ARDFields_copy()`

I can provide the regression test and malloc-failure shim if that would be useful.


reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: github://postgresql-interfaces/psqlodbc
  Cc: [email protected], [email protected]
  Subject: Re: [postgresql-interfaces/psqlodbc] issue #177: OOM: SQLAllocHandle(SQL_HANDLE_STMT) can segfault if ARD_AllocBookmark malloc fails
  In-Reply-To: <<[email protected]>>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox