Skip to content

Reference leak of local rdnlist in l_ldap_str2dn on inner append failure #620

Description

@K-ANOY

In l_ldap_str2dn(), after rdnlist is appended to the parent list tmp, the local variable still holds its own reference. If a later PyList_Append(rdnlist, tuple) fails, the function jumps to failed without releasing that local reference, leaking one list per failure.

File: Modules/functions.c

Function: l_ldap_str2dn

Relevant code:

rdnlist = PyList_New(0);
if (!rdnlist)
    goto failed;
if (PyList_Append(tmp, rdnlist) == -1) {   /* on success, refcount is now 2 */
    Py_DECREF(rdnlist);
    goto failed;
}

for (j = 0; rdn[j]; j++) {
    ...
    tuple = Py_BuildValue(...);
    if (!tuple) {
        Py_DECREF(rdnlist);        /* this branch releases the local ref */
        goto failed;
    }

    if (PyList_Append(rdnlist, tuple) == -1) {
        Py_DECREF(tuple);
        goto failed;               /* BUG: local `rdnlist` ref not released */
    }
    Py_DECREF(tuple);
}
Py_DECREF(rdnlist);                /* normal path releases the local ref */

After PyList_Append(tmp, rdnlist) succeeds, rdnlist has refcount 2 (the parent list tmp plus the local). The failed: label only does
Py_XDECREF(tmp), which drops the parent's reference; the extra local reference survives, so rdnlist leaks. The sibling !tuple branch already does Py_DECREF(rdnlist) before goto failed, which is exactly the missing step in the append-failure branch.

Suggested fix:

if (PyList_Append(rdnlist, tuple) == -1) {
    Py_DECREF(tuple);
    Py_DECREF(rdnlist);
    goto failed;
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions