summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authoremaste <emaste@FreeBSD.org>2014-11-25 18:39:37 +0000
committeremaste <emaste@FreeBSD.org>2014-11-25 18:39:37 +0000
commite206a51e9e281c23bf431f6771b382b03e355070 (patch)
tree0b396e542d418494c490b615cff5a603fdbfa5ac /lib
parent776a1c3a81015f1d99c7e23d699dffff8a9f6760 (diff)
downloadFreeBSD-src-e206a51e9e281c23bf431f6771b382b03e355070.zip
FreeBSD-src-e206a51e9e281c23bf431f6771b382b03e355070.tar.gz
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
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