krb5 commit: Fix null deref on some invalid PKINIT identities
Greg Hudson
ghudson at mit.edu
Wed Sep 26 15:20:50 EDT 2018
https://github.com/krb5/krb5/commit/23cd8e41d335027ff2e2a586345a570f97a926d4
commit 23cd8e41d335027ff2e2a586345a570f97a926d4
Author: Greg Hudson <ghudson at mit.edu>
Date: Thu Sep 6 11:47:56 2018 -0400
Fix null deref on some invalid PKINIT identities
pkinit_identity.c:parse_fs_options() could crash if the first
strtok_r() call returns NULL, which happens when the residual string
begins with ','. Fix this bug by checking for a leading comma and
checking the strtok_r() result, and add a test case. Reported by Bean
Zhang.
Also return EINVAL rather than 0 on invalid input, and don't leave an
allocated value in idopts->cert_filename if we fail to copy the key
filename.
ticket: 8726
src/plugins/preauth/pkinit/pkinit_identity.c | 21 +++++++++++++++------
src/tests/t_pkinit.py | 5 +++++
2 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/src/plugins/preauth/pkinit/pkinit_identity.c b/src/plugins/preauth/pkinit/pkinit_identity.c
index fa754e3..8cd3fc6 100644
--- a/src/plugins/preauth/pkinit/pkinit_identity.c
+++ b/src/plugins/preauth/pkinit/pkinit_identity.c
@@ -317,29 +317,38 @@ parse_fs_options(krb5_context context,
const char *residual)
{
char *certname, *keyname, *save;
+ char *cert_filename = NULL, *key_filename = NULL;
krb5_error_code retval = ENOMEM;
- if (residual == NULL || residual[0] == '\0')
- return 0;
+ if (residual == NULL || residual[0] == '\0' || residual[0] == ',')
+ return EINVAL;
certname = strdup(residual);
if (certname == NULL)
goto cleanup;
certname = strtok_r(certname, ",", &save);
+ if (certname == NULL)
+ goto cleanup;
keyname = strtok_r(NULL, ",", &save);
- idopts->cert_filename = strdup(certname);
- if (idopts->cert_filename == NULL)
+ cert_filename = strdup(certname);
+ if (cert_filename == NULL)
goto cleanup;
- idopts->key_filename = strdup(keyname ? keyname : certname);
- if (idopts->key_filename == NULL)
+ key_filename = strdup((keyname != NULL) ? keyname : certname);
+ if (key_filename == NULL)
goto cleanup;
+ idopts->cert_filename = cert_filename;
+ idopts->key_filename = key_filename;
+ cert_filename = key_filename = NULL;
retval = 0;
+
cleanup:
free(certname);
+ free(cert_filename);
+ free(key_filename);
return retval;
}
diff --git a/src/tests/t_pkinit.py b/src/tests/t_pkinit.py
index 6ea294c..1dadb1b 100755
--- a/src/tests/t_pkinit.py
+++ b/src/tests/t_pkinit.py
@@ -393,6 +393,11 @@ realm.kinit(realm.user_princ,
flags=['-X', 'X509_user_identity=%s' % p12_generic_identity])
realm.klist(realm.user_princ)
+# Regression test for #8726: null deref when parsing a FILE residual
+# beginning with a comma.
+realm.kinit(realm.user_princ, flags=['-X', 'X509_user_identity=,'],
+ expected_code=1, expected_msg='Preauthentication failed while')
+
if not have_soft_pkcs11:
skip_rest('PKINIT PKCS11 tests', 'soft-pkcs11.so not found')
More information about the cvs-krb5
mailing list