diff options
author | rmacklem <rmacklem@FreeBSD.org> | 2013-05-01 22:07:55 +0000 |
---|---|---|
committer | rmacklem <rmacklem@FreeBSD.org> | 2013-05-01 22:07:55 +0000 |
commit | 69aa4ba12b52a30a0ece6e0a2db343b4f3f1a859 (patch) | |
tree | 54863bcd247a8d6c00e57f7fc1a99c3891dd5d79 /sys | |
parent | 66a7a3379b040dcee448883bd3fc0129ef755b43 (diff) | |
download | FreeBSD-src-69aa4ba12b52a30a0ece6e0a2db343b4f3f1a859.zip FreeBSD-src-69aa4ba12b52a30a0ece6e0a2db343b4f3f1a859.tar.gz |
Isilon reported that sec=krb5p NFS mounts had a problem when m_len == 0
for the last mbuf of the list with an encrypted message. This patch replaces
the KASSERT() with code that handles this case.
Reported by: john.gemignani@isilon.com
Reviewed by: jhb
MFC after: 2 weeks
Diffstat (limited to 'sys')
-rw-r--r-- | sys/kgssapi/krb5/krb5_mech.c | 24 |
1 files changed, 21 insertions, 3 deletions
diff --git a/sys/kgssapi/krb5/krb5_mech.c b/sys/kgssapi/krb5/krb5_mech.c index 71f804e..4cfea58 100644 --- a/sys/kgssapi/krb5/krb5_mech.c +++ b/sys/kgssapi/krb5/krb5_mech.c @@ -1585,6 +1585,8 @@ m_trim(struct mbuf *m, int len) struct mbuf *n; int off; + if (m == NULL) + return; n = m_getptr(m, len, &off); if (n) { n->m_len = off; @@ -1600,7 +1602,7 @@ krb5_unwrap_old(struct krb5_context *kc, struct mbuf **mp, int *conf_state, uint8_t sgn_alg[2], uint8_t seal_alg[2]) { OM_uint32 res; - struct mbuf *m, *mlast, *hm, *cm; + struct mbuf *m, *mlast, *hm, *cm, *n; uint8_t *p, dir; size_t mlen, tlen, elen, datalen, padlen; size_t cklen; @@ -1702,9 +1704,25 @@ krb5_unwrap_old(struct krb5_context *kc, struct mbuf **mp, int *conf_state, /* * Check the trailing pad bytes. + * RFC1964 specifies between 1<->8 bytes, each with a binary value + * equal to the number of bytes. */ - KASSERT(mlast->m_len > 0, ("Unexpected empty mbuf")); - padlen = mlast->m_data[mlast->m_len - 1]; + if (mlast->m_len > 0) + padlen = mlast->m_data[mlast->m_len - 1]; + else { + n = m_getptr(m, tlen + datalen - 1, &i); + /* + * When the position is exactly equal to the # of data bytes + * in the mbuf list, m_getptr() will return the last mbuf in + * the list and an off == m_len for that mbuf, so that case + * needs to be checked as well as a NULL return. + */ + if (n == NULL || n->m_len == i) + return (GSS_S_DEFECTIVE_TOKEN); + padlen = n->m_data[i]; + } + if (padlen < 1 || padlen > 8 || padlen > tlen + datalen) + return (GSS_S_DEFECTIVE_TOKEN); m_copydata(m, tlen + datalen - padlen, padlen, buf); for (i = 0; i < padlen; i++) { if (buf[i] != padlen) { |