Skip to content

[Bug] int-array typecaster stack buffer overflow on oversized array element (segfault) #1847

Description

@wildoranges

Summary

typecast_LONGINTEGER_cast (psycopg/typecast_basic.c) copies an integer-array element into a fixed 24-byte stack buffer with an unbounded strncpy. Any array element token longer than 24 bytes overflows the buffer and crashes the client process (SIGSEGV; reliably reproducible with tokens >= 64 bytes). typecast_INTEGER_cast / typecast_ROWID_cast are the same function.

A normal PostgreSQL server cannot produce such tokens (int8 maxes out at 19 digits), so this does not affect normal usage — it is a robustness gap: unexpected/malformed data reaching the array tokenizer crashes instead of failing cleanly.

Root cause

char buffer[24];
...
if (s[len] != '\0') {                    /* array tokens are not NUL-terminated */
    strncpy(buffer, s, (size_t) len);    /* len is not bounded */
    buffer[len] = '\0';
    s = buffer;
}

Array elements are sliced by typecast_array_tokenize() as substrings of the array literal (terminated by , / }), so s[len] != '\0' is always true and the copy branch runs with len unvalidated.

Repro

import psycopg2, psycopg2.extensions as e
conn = psycopg2.connect("dbname=test")
cur = conn.cursor()
e.LONGINTEGERARRAY(b"{" + b"9" * 1024 + b",1}", cur)   # segfault (exit 139)

Suggested fix

Bound the copy (or use a dynamic buffer as in typecast_DECIMAL_cast):

if (s[len] != '\0') {
    if (len >= (Py_ssize_t) sizeof(buffer)) {
        /* avoid stack overflow on oversized tokens */
        PyErr_SetString(PyExc_ValueError, "integer array element too long");
        return NULL;
    }
    strncpy(buffer, s, (size_t) len);
    buffer[len] = '\0';
    s = buffer;
}

Happy to open a PR if this looks right.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions