summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorHans Jerry Illikainen <hji@dyntopia.com>2016-12-11 20:17:49 +0000
committerNick Mathewson <nickm@torproject.org>2016-12-23 09:47:09 -0500
commita23fd1578612051a3ac804c12a629f6a5cfa296e (patch)
tree7b64f7ab79efaf2469efefbe60bbcec46f5aed59 /src/common
parentf3da62dbdfb2057a7c8d5d46367e9d41bdd5b9ec (diff)
downloadtor-a23fd1578612051a3ac804c12a629f6a5cfa296e.tar.gz
tor-a23fd1578612051a3ac804c12a629f6a5cfa296e.zip
Fix unreachable heap corruption in base64_decode()
Give size_mul_check() external linkage and use it in base64_decode() to avoid a potential integer wrap. Closes #19222
Diffstat (limited to 'src/common')
-rw-r--r--src/common/util.c11
-rw-r--r--src/common/util.h4
-rw-r--r--src/common/util_format.c2
3 files changed, 3 insertions, 14 deletions
diff --git a/src/common/util.c b/src/common/util.c
index 9d134c1bb2..d02eb664d7 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -188,7 +188,7 @@ tor_malloc_zero_(size_t size DMALLOC_PARAMS)
#define SQRT_SIZE_MAX_P1 (((size_t)1) << (sizeof(size_t)*4))
/** Return non-zero if and only if the product of the arguments is exact. */
-static inline int
+inline int
size_mul_check(const size_t x, const size_t y)
{
/* This first check is equivalent to
@@ -202,15 +202,6 @@ size_mul_check(const size_t x, const size_t y)
x <= SIZE_MAX / y);
}
-#ifdef TOR_UNIT_TESTS
-/** Exposed for unit tests only */
-int
-size_mul_check__(const size_t x, const size_t y)
-{
- return size_mul_check(x,y);
-}
-#endif
-
/** Allocate a chunk of <b>nmemb</b>*<b>size</b> bytes of memory, fill
* the memory with zero bytes, and return a pointer to the result.
* Log and terminate the process on error. (Same as
diff --git a/src/common/util.h b/src/common/util.h
index 2b3e48ea8e..ff566151cb 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -553,9 +553,7 @@ STATIC int format_helper_exit_status(unsigned char child_state,
#endif
-#ifdef TOR_UNIT_TESTS
-int size_mul_check__(const size_t x, const size_t y);
-#endif
+int size_mul_check(const size_t x, const size_t y);
#define ARRAY_LENGTH(x) ((sizeof(x)) / sizeof(x[0]))
diff --git a/src/common/util_format.c b/src/common/util_format.c
index aef9db85c8..6e0a04586a 100644
--- a/src/common/util_format.c
+++ b/src/common/util_format.c
@@ -398,7 +398,7 @@ base64_decode(char *dest, size_t destlen, const char *src, size_t srclen)
* Number of bytes required to hold all bits == (srclen*6)/8.
* Yes, we want to round down: anything that hangs over the end of a
* byte is padding. */
- if (destlen < (srclen*3)/4)
+ if (!size_mul_check(srclen, 3) || destlen < (srclen*3)/4)
return -1;
if (destlen > SIZE_T_CEILING)
return -1;