Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 13 May 2016 08:25:06 +0000 (UTC)
From:      Garrett Cooper <ngie@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org
Subject:   svn commit: r299617 - in stable/10/sys/kgssapi: . krb5
Message-ID:  <201605130825.u4D8P6gr061940@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: ngie
Date: Fri May 13 08:25:06 2016
New Revision: 299617
URL: https://svnweb.freebsd.org/changeset/base/299617

Log:
  MFC r295134,r298338,r298655:
  
  r295134 (by cem):
  
  kcrypto_aes: Use separate sessions for AES and SHA1
  
  Some hardware supports AES acceleration but not SHA1, e.g., AES-NI
  extensions.  It is useful to have accelerated AES even if SHA1 must be
  software.
  
  Suggested by:	asomers
  
  r298338 (by cem):
  
  kgssapi(4): Don't allow user-provided arguments to overrun stack buffer
  
  An over-long path argument to gssd_syscall could overrun the stack sockaddr_un
  buffer.  Fix gssd_syscall to not permit that.
  
  If an over-long path is provided, gssd_syscall now returns EINVAL.
  
  It looks like PRIV_NFS_DAEMON isn't granted anywhere, so my best guess is that
  this is likely only triggerable by root.
  
  CID:		1006751
  
  r298655 (by cem):
  
  kgssapi: Don't leak memory in error cases
  
  CIDs:		1007046, 1007047, 1007048

Modified:
  stable/10/sys/kgssapi/gss_impl.c
  stable/10/sys/kgssapi/gssd_prot.c
  stable/10/sys/kgssapi/krb5/kcrypto_aes.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/kgssapi/gss_impl.c
==============================================================================
--- stable/10/sys/kgssapi/gss_impl.c	Fri May 13 08:17:42 2016	(r299616)
+++ stable/10/sys/kgssapi/gss_impl.c	Fri May 13 08:25:06 2016	(r299617)
@@ -104,10 +104,12 @@ sys_gssd_syscall(struct thread *td, stru
 	error = copyinstr(uap->path, path, sizeof(path), NULL);
 	if (error)
 		return (error);
+	if (strlen(path) + 1 > sizeof(sun.sun_path))
+		return (EINVAL);
 
 	if (path[0] != '\0') {
 		sun.sun_family = AF_LOCAL;
-		strcpy(sun.sun_path, path);
+		strlcpy(sun.sun_path, path, sizeof(sun.sun_path));
 		sun.sun_len = SUN_LEN(&sun);
 		
 		nconf = getnetconfigent("local");

Modified: stable/10/sys/kgssapi/gssd_prot.c
==============================================================================
--- stable/10/sys/kgssapi/gssd_prot.c	Fri May 13 08:17:42 2016	(r299616)
+++ stable/10/sys/kgssapi/gssd_prot.c	Fri May 13 08:25:06 2016	(r299617)
@@ -101,8 +101,10 @@ xdr_gss_OID(XDR *xdrs, gss_OID *oidp)
 		} else {
 			oid = mem_alloc(sizeof(gss_OID_desc));
 			memset(oid, 0, sizeof(*oid));
-			if (!xdr_gss_OID_desc(xdrs, oid))
+			if (!xdr_gss_OID_desc(xdrs, oid)) {
+				mem_free(oid, sizeof(gss_OID_desc));
 				return (FALSE);
+			}
 			*oidp = oid;
 		}
 		break;
@@ -164,8 +166,10 @@ xdr_gss_OID_set(XDR *xdrs, gss_OID_set *
 		} else {
 			set = mem_alloc(sizeof(gss_OID_set_desc));
 			memset(set, 0, sizeof(*set));
-			if (!xdr_gss_OID_set_desc(xdrs, set))
+			if (!xdr_gss_OID_set_desc(xdrs, set)) {
+				mem_free(set, sizeof(gss_OID_set_desc));
 				return (FALSE);
+			}
 			*setp = set;
 		}
 		break;
@@ -224,8 +228,10 @@ xdr_gss_channel_bindings_t(XDR *xdrs, gs
 			    || !xdr_gss_buffer_desc(xdrs,
 				&ch->acceptor_address)
 			    || !xdr_gss_buffer_desc(xdrs,
-				&ch->application_data))
+				&ch->application_data)) {
+				mem_free(ch, sizeof(*ch));
 				return (FALSE);
+			}
 			*chp = ch;
 		}
 		break;

Modified: stable/10/sys/kgssapi/krb5/kcrypto_aes.c
==============================================================================
--- stable/10/sys/kgssapi/krb5/kcrypto_aes.c	Fri May 13 08:17:42 2016	(r299616)
+++ stable/10/sys/kgssapi/krb5/kcrypto_aes.c	Fri May 13 08:25:06 2016	(r299617)
@@ -43,7 +43,8 @@ __FBSDID("$FreeBSD$");
 
 struct aes_state {
 	struct mtx	as_lock;
-	uint64_t	as_session;
+	uint64_t	as_session_aes;
+	uint64_t	as_session_sha1;
 };
 
 static void
@@ -61,8 +62,10 @@ aes_destroy(struct krb5_key_state *ks)
 {
 	struct aes_state *as = ks->ks_priv;
 
-	if (as->as_session)
-		crypto_freesession(as->as_session);
+	if (as->as_session_aes != 0)
+		crypto_freesession(as->as_session_aes);
+	if (as->as_session_sha1 != 0)
+		crypto_freesession(as->as_session_sha1);
 	mtx_destroy(&as->as_lock);
 	free(ks->ks_priv, M_GSSAPI);
 }
@@ -72,32 +75,35 @@ aes_set_key(struct krb5_key_state *ks, c
 {
 	void *kp = ks->ks_key;
 	struct aes_state *as = ks->ks_priv;
-	struct cryptoini cri[2];
+	struct cryptoini cri;
 
 	if (kp != in)
 		bcopy(in, kp, ks->ks_class->ec_keylen);
 
-	if (as->as_session)
-		crypto_freesession(as->as_session);
-
-	bzero(cri, sizeof(cri));
+	if (as->as_session_aes != 0)
+		crypto_freesession(as->as_session_aes);
+	if (as->as_session_sha1 != 0)
+		crypto_freesession(as->as_session_sha1);
 
 	/*
 	 * We only want the first 96 bits of the HMAC.
 	 */
-	cri[0].cri_alg = CRYPTO_SHA1_HMAC;
-	cri[0].cri_klen = ks->ks_class->ec_keybits;
-	cri[0].cri_mlen = 12;
-	cri[0].cri_key = ks->ks_key;
-	cri[0].cri_next = &cri[1];
-
-	cri[1].cri_alg = CRYPTO_AES_CBC;
-	cri[1].cri_klen = ks->ks_class->ec_keybits;
-	cri[1].cri_mlen = 0;
-	cri[1].cri_key = ks->ks_key;
-	cri[1].cri_next = NULL;
+	bzero(&cri, sizeof(cri));
+	cri.cri_alg = CRYPTO_SHA1_HMAC;
+	cri.cri_klen = ks->ks_class->ec_keybits;
+	cri.cri_mlen = 12;
+	cri.cri_key = ks->ks_key;
+	cri.cri_next = NULL;
+	crypto_newsession(&as->as_session_sha1, &cri,
+	    CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE);
 
-	crypto_newsession(&as->as_session, cri,
+	bzero(&cri, sizeof(cri));
+	cri.cri_alg = CRYPTO_AES_CBC;
+	cri.cri_klen = ks->ks_class->ec_keybits;
+	cri.cri_mlen = 0;
+	cri.cri_key = ks->ks_key;
+	cri.cri_next = NULL;
+	crypto_newsession(&as->as_session_aes, &cri,
 	    CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE);
 }
 
@@ -114,7 +120,7 @@ aes_crypto_cb(struct cryptop *crp)
 	int error;
 	struct aes_state *as = (struct aes_state *) crp->crp_opaque;
 	
-	if (CRYPTO_SESID2CAPS(as->as_session) & CRYPTOCAP_F_SYNC)
+	if (CRYPTO_SESID2CAPS(crp->crp_sid) & CRYPTOCAP_F_SYNC)
 		return (0);
 
 	error = crp->crp_etype;
@@ -151,7 +157,7 @@ aes_encrypt_1(const struct krb5_key_stat
 	crd->crd_next = NULL;
 	crd->crd_alg = CRYPTO_AES_CBC;
 
-	crp->crp_sid = as->as_session;
+	crp->crp_sid = as->as_session_aes;
 	crp->crp_flags = buftype | CRYPTO_F_CBIFSYNC;
 	crp->crp_buf = buf;
 	crp->crp_opaque = (void *) as;
@@ -159,7 +165,7 @@ aes_encrypt_1(const struct krb5_key_stat
 
 	error = crypto_dispatch(crp);
 
-	if ((CRYPTO_SESID2CAPS(as->as_session) & CRYPTOCAP_F_SYNC) == 0) {
+	if ((CRYPTO_SESID2CAPS(as->as_session_aes) & CRYPTOCAP_F_SYNC) == 0) {
 		mtx_lock(&as->as_lock);
 		if (!error && !(crp->crp_flags & CRYPTO_F_DONE))
 			error = msleep(crp, &as->as_lock, 0, "gssaes", 0);
@@ -326,7 +332,7 @@ aes_checksum(const struct krb5_key_state
 	crd->crd_next = NULL;
 	crd->crd_alg = CRYPTO_SHA1_HMAC;
 
-	crp->crp_sid = as->as_session;
+	crp->crp_sid = as->as_session_sha1;
 	crp->crp_ilen = inlen;
 	crp->crp_olen = 12;
 	crp->crp_etype = 0;
@@ -337,7 +343,7 @@ aes_checksum(const struct krb5_key_state
 
 	error = crypto_dispatch(crp);
 
-	if ((CRYPTO_SESID2CAPS(as->as_session) & CRYPTOCAP_F_SYNC) == 0) {
+	if ((CRYPTO_SESID2CAPS(as->as_session_sha1) & CRYPTOCAP_F_SYNC) == 0) {
 		mtx_lock(&as->as_lock);
 		if (!error && !(crp->crp_flags & CRYPTO_F_DONE))
 			error = msleep(crp, &as->as_lock, 0, "gssaes", 0);



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