summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authoremaste <emaste@FreeBSD.org>2015-03-23 20:50:28 +0000
committeremaste <emaste@FreeBSD.org>2015-03-23 20:50:28 +0000
commit2c2450125c1aac8fb110c1cf19a9dd7bfe1434b5 (patch)
treedd5b9f7f5a1e02f917f4a53372fdbb04744e857e /lib
parentd201e39fd34bb07644b00c9902c809c1d06618d3 (diff)
downloadFreeBSD-src-2c2450125c1aac8fb110c1cf19a9dd7bfe1434b5.zip
FreeBSD-src-2c2450125c1aac8fb110c1cf19a9dd7bfe1434b5.tar.gz
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.
Diffstat (limited to 'lib')
-rw-r--r--lib/libc/net/base64.c22
1 files changed, 15 insertions, 7 deletions
diff --git a/lib/libc/net/base64.c b/lib/libc/net/base64.c
index 4335030..6737c18 100644
--- a/lib/libc/net/base64.c
+++ b/lib/libc/net/base64.c
@@ -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 {
OpenPOWER on IntegriCloud