Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 15 May 2013 01:37:00 +0000 (UTC)
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org
Subject:   svn commit: r250652 - stable/9/sys/kgssapi/krb5
Message-ID:  <201305150137.r4F1b0md091461@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Wed May 15 01:36:59 2013
New Revision: 250652
URL: http://svnweb.freebsd.org/changeset/base/250652

Log:
  MFC: r250157
  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.

Modified:
  stable/9/sys/kgssapi/krb5/krb5_mech.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/kgssapi/krb5/krb5_mech.c
==============================================================================
--- stable/9/sys/kgssapi/krb5/krb5_mech.c	Wed May 15 01:22:55 2013	(r250651)
+++ stable/9/sys/kgssapi/krb5/krb5_mech.c	Wed May 15 01:36:59 2013	(r250652)
@@ -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,
     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,
 
 	/*
 	 * 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) {



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201305150137.r4F1b0md091461>