Author: emaste
Date: Mon Mar 23 20:50:28 2015
New Revision: 280398
URL: https://svnweb.freebsd.org/changeset/base/280398

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

Modified:
  stable/10/lib/libc/net/base64.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/lib/libc/net/base64.c
==============================================================================
--- stable/10/lib/libc/net/base64.c     Mon Mar 23 20:02:16 2015        
(r280397)
+++ stable/10/lib/libc/net/base64.c     Mon Mar 23 20:50:28 2015        
(r280398)
@@ -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-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to