#731 Possible memory leak in do_pam_conversation
Closed: Fixed Opened by sgallagh.

  305static int do_pam_conversation(pam_handle_t *pamh, const int msg_style,
  306                               const char *msg,
  307                               const char *reenter_msg,
  308                               char **answer)
  309{
  310    int ret;
  311    int state = SSS_PAM_CONV_STD;
  312    struct pam_conv *conv;
  313    const struct pam_message *mesg[1];
  314    struct pam_message *pam_msg;
  315    struct pam_response *resp=NULL;
  316
At conditional (1): "msg_style == 4" taking the false branch.
At conditional (2): "msg_style == 3" taking the false branch.
  317    if ((msg_style == PAM_TEXT_INFO || msg_style == PAM_ERROR_MSG) &&
  318        msg == NULL) return PAM_SYSTEM_ERR;
  319
At conditional (3): "msg_style == 1" taking the true branch.
At conditional (4): "msg == NULL" taking the false branch.
At conditional (5): "answer == NULL" taking the false branch.
  320    if ((msg_style == PAM_PROMPT_ECHO_OFF ||
  321         msg_style == PAM_PROMPT_ECHO_ON) &&
  322        (msg == NULL || answer == NULL)) return PAM_SYSTEM_ERR;
  323
At conditional (6): "msg_style == 4" taking the false branch.
At conditional (7): "msg_style == 3" taking the false branch.
  324    if (msg_style == PAM_TEXT_INFO || msg_style == PAM_ERROR_MSG) {
  325        logger(pamh, LOG_INFO, "User %s message: %s",
  326                               msg_style == PAM_TEXT_INFO ? "info" : "error",
  327                               msg);
  328    }
  329
  330    ret=pam_get_item(pamh, PAM_CONV, (const void **) &conv);
At conditional (8): "ret != 0" taking the false branch.
  331    if (ret != PAM_SUCCESS) return ret;
  332
  333    do {
  334        pam_msg = malloc(sizeof(struct pam_message));
At conditional (9): "pam_msg == NULL" taking the false branch.
At conditional (23): "pam_msg == NULL" taking the false branch.
  335        if (pam_msg == NULL) {
  336            D(("Malloc failed."));
  337            return PAM_SYSTEM_ERR;
  338        }
  339
  340        pam_msg->msg_style = msg_style;
At conditional (10): "state == 2" taking the false branch.
At conditional (24): "state == 2" taking the true branch.
  341        if (state == SSS_PAM_CONV_REENTER) {
  342            pam_msg->msg = reenter_msg;
  343        } else {
  344            pam_msg->msg = msg;
  345        }
  346
  347        mesg[0] = (const struct pam_message *) pam_msg;
  348
  349        ret=conv->conv(1, mesg, &resp,
  350                       conv->appdata_ptr);
  351        free(pam_msg);
At conditional (11): "ret != 0" taking the false branch.
At conditional (25): "ret != 0" taking the true branch.
  352        if (ret != PAM_SUCCESS) {
  353            D(("Conversation failure: %s.",  pam_strerror(pamh,ret)));
  354            return ret;
  355        }
  356
At conditional (12): "msg_style == 1" taking the true branch.
  357        if (msg_style == PAM_PROMPT_ECHO_OFF ||
  358            msg_style == PAM_PROMPT_ECHO_ON) {
At conditional (13): "resp == NULL" taking the false branch.
  359            if (resp == NULL) {
  360                D(("response expected, but resp==NULL"));
  361                return PAM_SYSTEM_ERR;
  362            }
  363
At conditional (14): "state == 2" taking the false branch.
  364            if (state == SSS_PAM_CONV_REENTER) {
  365                if (null_strcmp(*answer, resp[0].resp) != 0) {
  366                    logger(pamh, LOG_NOTICE, "Passwords do not match.");
  367                    _pam_overwrite((void *)resp[0].resp);
  368                    free(resp[0].resp);
  369                    if (*answer != NULL) {
  370                        _pam_overwrite((void *)*answer);
  371                        free(*answer);
  372                        *answer = NULL;
  373                    }
  374                    ret = do_pam_conversation(pamh, PAM_ERROR_MSG,
  375                                              _("Passwords do not match"),
  376                                              NULL, NULL);
  377                    if (ret != PAM_SUCCESS) {
  378                        D(("do_pam_conversation failed."));
  379                        return PAM_SYSTEM_ERR;
  380                    }
  381                    return PAM_CRED_ERR;
  382                }
  383                _pam_overwrite((void *)resp[0].resp);
  384                free(resp[0].resp);
  385            } else {
At conditional (15): "(resp + 0)->resp == NULL" taking the false branch.
  386                if (resp[0].resp == NULL) {
  387                    D(("Empty password"));
  388                    *answer = NULL;
  389                } else {
Assigning: "*answer" = "strndup((resp + 0)->resp, 1048576UL)".
Storage is returned from allocation function "strndup".
  390                    *answer = strndup(resp[0].resp, MAX_AUTHTOK_SIZE);
At conditional (16): "__xx__ = (void *)(resp + 0)->resp" taking the true branch.
At conditional (17): "*__xx__" taking the true branch.
At conditional (18): "*__xx__" taking the false branch.
  391                    _pam_overwrite((void *)resp[0].resp);
  392                    free(resp[0].resp);
At conditional (19): "*answer == NULL" taking the false branch.
  393                    if(*answer == NULL) {
  394                        D(("strndup failed"));
  395                        return PAM_BUF_ERR;
  396                    }
  397                }
  398            }
  399            free(resp);
  400            resp = NULL;
  401        }
  402
At conditional (20): "reenter_msg != NULL" taking the true branch.
At conditional (21): "state == 1" taking the true branch.
  403        if (reenter_msg != NULL && state == SSS_PAM_CONV_STD) {
  404            state = SSS_PAM_CONV_REENTER;
  405        } else {
  406            state = SSS_PAM_CONV_DONE;
  407        }
At conditional (22): "state != 0" taking the true branch.
  408    } while (state != SSS_PAM_CONV_DONE);
  409
  410    return PAM_SUCCESS;
  411}

Fixed by ad6c0f29d78f2ce5d84d5e3d80e56152eac1b9d4

Fields changed

resolution: => fixed
status: new => closed

Fields changed

rhbz: => 0

Metadata Update from @sgallagh:
- Issue assigned to sbose
- Issue set to the milestone: SSSD 1.5.0

SSSD is moving from Pagure to Github. This means that new issues and pull requests
will be accepted only in SSSD's github repository.

This issue has been cloned to Github and is available here:
- https://github.com/SSSD/sssd/issues/1773

If you want to receive further updates on the issue, please navigate to the github issue
and click on subscribe button.

Thank you for understanding. We apologize for all inconvenience.

Metadata