]> granicus.if.org Git - linux-pam/commitdiff
Relevant BUGIDs: 476983
authorAndrew G. Morgan <morgan@kernel.org>
Mon, 12 Nov 2001 02:23:28 +0000 (02:23 +0000)
committerAndrew G. Morgan <morgan@kernel.org>
Mon, 12 Nov 2001 02:23:28 +0000 (02:23 +0000)
Purpose of commit: bugfixes

Commit summary:
---------------
lots of segfault potential removed. Nalin found the biggies.

CHANGELOG
modules/pam_issue/pam_issue.c

index 3979c040e3a0ac283abac69c0ec7fc458efe2cea..d84253e56ccfda6465c928e6a923fa562fb53976 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -49,6 +49,9 @@ bug report - outstanding bugs are listed here:
 0.76: please submit patches for this section with actual code/doc
       patches!
 
+* pam_issue: Nalin found segfaulting problems if the PAM_USER_PROMPT
+  is unset, found some similar problems with assumptions about
+  realloc. (Bug 476983 - agmorgan)
 * pam_env: 'weichangyang of hotmail' pointed out a wild string with no
   valid '\0' was leading to problems with sshd and suggested fix (Bug
   473034 - agmorgan)
index c4f2c6a6d3fd15754cdda700c55f2b0d6a745ddc..1f4853dedc31c3b652bb5f1c8c11a592e6ce016a 100644 (file)
@@ -49,7 +49,8 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
     int retval = PAM_SUCCESS;
     FILE *fd;
     int parse_esc = 1;
-    char *prompt_tmp = NULL, *cur_prompt = NULL;
+    char *prompt_tmp = NULL;
+    const char *cur_prompt = NULL;
     struct stat st;
     char *issue_file = NULL;
 
@@ -83,23 +84,38 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
     if ((fd = fopen(issue_file, "r")) != NULL) {
        int tot_size = 0;
 
-       if (stat(issue_file, &st) < 0)
+       if (fstat(fileno(fd), &st) < 0)
            return PAM_IGNORE;
 
-       retval = pam_get_item(pamh, PAM_USER_PROMPT, (const void **) &cur_prompt);
-       if (retval != PAM_SUCCESS)
+       retval = pam_get_item(pamh, PAM_USER_PROMPT,
+                             (const void **) &cur_prompt);
+       if (retval != PAM_SUCCESS) {
            return PAM_IGNORE;
+       }
+       if (cur_prompt == NULL) {
+           cur_prompt = "";
+       }
 
-       /* first read in the issue file */
+       /* first read in the issue file */
 
-       if (parse_esc)
+       if (parse_esc) {
            prompt_tmp = do_prompt(fd);
-       else {
+           if (prompt_tmp == NULL) {
+               return PAM_IGNORE;
+           }
+       } else {
            int count = 0;
+
            prompt_tmp = malloc(st.st_size + 1);
-           if (prompt_tmp == NULL) return PAM_IGNORE;
+           if (prompt_tmp == NULL) {
+               return PAM_IGNORE;
+           }
            memset (prompt_tmp, '\0', st.st_size + 1);
            count = fread(prompt_tmp, sizeof(char *), st.st_size, fd);
+           if (count != st.st_size) {
+               free(prompt_tmp);
+               return PAM_IGNORE;
+           }
            prompt_tmp[st.st_size] = '\0';
        }
 
@@ -111,15 +127,28 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
        * alloc some extra space for the original prompt
        * and postpend it to the buffer
        */
-       prompt_tmp = realloc(prompt_tmp, tot_size);
+       {
+           char *prompt_tmp_tmp = prompt_tmp;
+
+           prompt_tmp = realloc(prompt_tmp, tot_size);
+           if (prompt_tmp == NULL) {
+               prompt_tmp = prompt_tmp_tmp;
+               retval = PAM_IGNORE;
+               goto cleanup;
+           }
+       }
+
        strcpy(prompt_tmp+strlen(prompt_tmp), cur_prompt);
 
        prompt_tmp[tot_size] = '\0';
 
-       retval = pam_set_item(pamh, PAM_USER_PROMPT, (const char *) prompt_tmp);
+       retval = pam_set_item(pamh, PAM_USER_PROMPT,
+                             (const char *) prompt_tmp);
 
+    cleanup:
        free(issue_file);
        free(prompt_tmp);
+
     } else {
        D(("could not open issue_file: %s", issue_file));
        return PAM_IGNORE;
@@ -231,19 +260,32 @@ char *do_prompt(FILE *fd)
                buf[0] = c; buf[1] = '\0';
            }
            if ((strlen(issue) + strlen(buf)) < size + 1) {
+               char *old_issue = issue;
+
                size += strlen(buf) + 1;
                issue = (char *) realloc (issue, size);
+               if (issue == NULL) {
+                   free(old_issue);
+                   return NULL;
+               }
            }
            strcat(issue, buf);
        } else {
            buf[0] = c; buf[1] = '\0';
            if ((strlen(issue) + strlen(buf)) < size + 1) {
+               char *old_issue = issue;
+
                size += strlen(buf) + 1;
                issue = (char *) realloc (issue, size);
+               if (issue == NULL) {
+                   free(old_issue);
+                   return NULL;
+               }
            }
            strcat(issue, buf);
        }
     }
+
     return issue;
 }