Author: rmacklem
Date: Wed May  1 22:07:55 2013
New Revision: 250157
URL: http://svnweb.freebsd.org/changeset/base/250157

Log:
  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.gemign...@isilon.com
  Reviewed by:  jhb
  MFC after:    2 weeks

Modified:
  head/sys/kgssapi/krb5/krb5_mech.c

Modified: head/sys/kgssapi/krb5/krb5_mech.c
==============================================================================
--- head/sys/kgssapi/krb5/krb5_mech.c   Wed May  1 21:53:38 2013        
(r250156)
+++ head/sys/kgssapi/krb5/krb5_mech.c   Wed May  1 22:07:55 2013        
(r250157)
@@ -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) {
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to