Skip to content

Reference leak of info dict in LDAPraise_for_message on control conversion failure #621

Description

@K-ANOY

LDAPraise_for_message() builds an info dictionary and, if the later LDAPControls_to_List() call fails, returns without releasing it. The error path frees the LDAP-owned resources but not the partially filled Python dict.

File: Modules/constants.c

Function: LDAPraise_for_message

Relevant code:

info = PyDict_New();
if (info == NULL) { ... }

/* ... info is populated with msgtype/msgid/result/desc/errno ... */

if (!(pyctrls = LDAPControls_to_List(serverctrls))) {
    int err = LDAP_NO_MEMORY;

    ldap_set_option(l, LDAP_OPT_ERROR_NUMBER, &err);
    ldap_memfree(matched);
    ldap_memfree(error);
    ldap_memvfree((void **)refs);
    ldap_controls_free(serverctrls);
    return PyErr_NoMemory();      /* info leaked */
}

info is a new reference from PyDict_New(). On the normal path it is consumed by PyErr_SetObject(errobj, info); Py_DECREF(info); at the end of the function. On the LDAPControls_to_List() failure path it is never released.

Suggested fix:

if (!(pyctrls = LDAPControls_to_List(serverctrls))) {
    int err = LDAP_NO_MEMORY;

    ldap_set_option(l, LDAP_OPT_ERROR_NUMBER, &err);
    Py_DECREF(info);
    ldap_memfree(matched);
    ldap_memfree(error);
    ldap_memvfree((void **)refs);
    ldap_controls_free(serverctrls);
    return PyErr_NoMemory();
}

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