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 {
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to