aboutsummaryrefslogtreecommitdiff
path: root/modules/pam_pwhistory/opasswd.c
diff options
context:
space:
mode:
authorMatt Cowell <matt.cowell@nokia.com>2019-08-29 16:36:35 -0500
committerTomáš Mráz <t8m@users.noreply.github.com>2019-09-02 11:28:31 +0200
commit9de67eee2cf8c3024f7bee7393ea762ac7bd09ab (patch)
tree442ba3e354bdb3bf070fc74908dd4262d48e0845 /modules/pam_pwhistory/opasswd.c
parent1b087edc7f05237bf5eccc405704cd82b848e761 (diff)
downloadpam-9de67eee2cf8c3024f7bee7393ea762ac7bd09ab.tar.gz
pam-9de67eee2cf8c3024f7bee7393ea762ac7bd09ab.tar.bz2
pam-9de67eee2cf8c3024f7bee7393ea762ac7bd09ab.zip
pwhistory: fix read of uninitialized data and memory leak when modifying opasswd
The glibc implementation of getline/getdelim does not guarantee a NUL terminator in lineptr if getline returns failure (-1). This occurs when the opasswd file exists but is empty. Since strdup is called immediately afterwards, this causes strdup to read uninitialized memory and possibly buffer overrun / crash. This also fixes a memory leak which always occurs when reading the last line of the opasswd file. Since the strdup is called before checking the return code from getline, getdelim, or fgets+strlen, it will duplicate and never free either: - The last successfully read line (for getline or getdelim) - Uninitialized data (if the file is empty) - A 0 byte string (for fgets+strlen) Fix by always checking the return code of getline, getdelim, or fgets+strlen before calling strdup.
Diffstat (limited to 'modules/pam_pwhistory/opasswd.c')
-rw-r--r--modules/pam_pwhistory/opasswd.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/modules/pam_pwhistory/opasswd.c b/modules/pam_pwhistory/opasswd.c
index e6cf3469..813f579c 100644
--- a/modules/pam_pwhistory/opasswd.c
+++ b/modules/pam_pwhistory/opasswd.c
@@ -326,6 +326,9 @@ save_old_pass (pam_handle_t *pamh, const char *user, uid_t uid,
n = strlen (buf);
#endif /* HAVE_GETLINE / HAVE_GETDELIM */
+ if (n < 1)
+ break;
+
cp = buf;
save = strdup (buf); /* Copy to write the original data back. */
if (save == NULL)
@@ -336,9 +339,6 @@ save_old_pass (pam_handle_t *pamh, const char *user, uid_t uid,
goto error_opasswd;
}
- if (n < 1)
- break;
-
tmp = strchr (cp, '#'); /* remove comments */
if (tmp)
*tmp = '\0';