svn commit: r275060 - head/lib/libc/net

Ed Maste emaste at FreeBSD.org
Tue Nov 25 18:39:38 UTC 2014


Author: emaste
Date: Tue Nov 25 18:39:37 2014
New Revision: 275060
URL: https://svnweb.freebsd.org/changeset/base/275060

Log:
  Fix b64_pton output buffer overrun test for exact-sized buffer
  
  b64_pton would sometimes erroneously fail to decode a base64 string into
  a precisely sized buffer. The overflow check was a little too greedy.
  
  Reported by:	Ted Unangst on freebsd-hackers@
  Reviewed by:	loos, trasz
  Obtained from:	OpenBSD
  MFC after:	1 week
  Sponsored by:	The FreeBSD Foundation
  Differential Revision: https://reviews.freebsd.org/D1218

Modified:
  head/lib/libc/net/base64.c

Modified: head/lib/libc/net/base64.c
==============================================================================
--- head/lib/libc/net/base64.c	Tue Nov 25 18:35:47 2014	(r275059)
+++ head/lib/libc/net/base64.c	Tue Nov 25 18:39:37 2014	(r275060)
@@ -199,6 +199,7 @@ b64_pton(src, target, targsize)
 	size_t targsize;
 {
 	int tarindex, state, ch;
+	u_char nextbyte;
 	char *pos;
 
 	state = 0;
@@ -226,22 +227,28 @@ b64_pton(src, target, targsize)
 			break;
 		case 1:
 			if (target) {
-				if ((size_t)tarindex + 1 >= targsize)
+				if ((size_t)tarindex >= targsize)
 					return (-1);
 				target[tarindex]   |=  (pos - Base64) >> 4;
-				target[tarindex+1]  = ((pos - Base64) & 0x0f)
-							<< 4 ;
+				nextbyte = ((pos - Base64) & 0x0f) << 4;
+				if ((size_t)tarindex + 1 < targsize)
+					target[tarindex + 1] = nextbyte;
+				else if (nextbyte)
+					return (-1);
 			}
 			tarindex++;
 			state = 2;
 			break;
 		case 2:
 			if (target) {
-				if ((size_t)tarindex + 1 >= targsize)
+				if ((size_t)tarindex >= targsize)
 					return (-1);
 				target[tarindex]   |=  (pos - Base64) >> 2;
-				target[tarindex+1]  = ((pos - Base64) & 0x03)
-							<< 6;
+				nextbyte = ((pos - Base64) & 0x03) << 6;
+				if ((size_t)tarindex + 1 < targsize)
+					target[tarindex + 1] = nextbyte;
+				else if (nextbyte)
+					return (-1);
 			}
 			tarindex++;
 			state = 3;
@@ -299,7 +306,8 @@ b64_pton(src, target, targsize)
 			 * zeros.  If we don't check them, they become a
 			 * subliminal channel.
 			 */
-			if (target && target[tarindex] != 0)
+			if (target && (size_t)tarindex < targsize &&
+			    target[tarindex] != 0)
 				return (-1);
 		}
 	} else {


More information about the svn-src-head mailing list