Skip to content

Commit c79eb6f

Browse files
committed
Add fix and test for bech32 bad input
Thanks to Christian Reitter and Dr. Jochen Hoenicke for finding the issue.
1 parent 34bac73 commit c79eb6f

7 files changed

Lines changed: 56 additions & 2 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ src/stamp-h1
3939
src/test/Makefile
4040
src/test/Makefile.in
4141
src/wallycore.pc
42+
src/test_bech32*
4243
src/test_clear*
4344
src/test_tx*
4445
src/test_elements_tx*

CHANGES.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,11 @@
22

33
## Version 0.6.5
44

5+
- Invalid bech32 addresses may have caused an out of bounds read. Thanks to
6+
Christian Reitter and Dr. Jochen Hoenicke for finding and reporting this
7+
issue. All users are advised to upgrade as soon as possible to minimise
8+
any potential impact.
9+
510
- BIP38_KEY_TESTNET was changed to reflect the testnet network version. BIP38 testnet keys
611
created with older versions of wally were not valid for testnet.
712

src/Makefile.am

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,11 @@ SUBDIRS = secp256k1
194194
TESTS =
195195
noinst_PROGRAMS =
196196
if RUN_TESTS
197+
TESTS += test_bech32
198+
noinst_PROGRAMS += test_bech32
199+
test_bech32_SOURCES = ctest/test_bech32.c
200+
test_bech32_CFLAGS = -I$(top_srcdir)/include $(AM_CFLAGS)
201+
test_bech32_LDADD = $(lib_LTLIBRARIES) @CTEST_EXTRA_STATIC@
197202
if USE_PTHREAD
198203
TESTS += test_clear
199204
noinst_PROGRAMS += test_clear

src/bech32.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,10 +99,10 @@ static int bech32_decode(char *hrp, uint8_t *data, size_t *data_len, const char
9999
while (*data_len < input_len && input[(input_len - 1) - *data_len] != '1') {
100100
++(*data_len);
101101
}
102-
hrp_len = input_len - (1 + *data_len);
103-
if (hrp_len < 1 || *data_len < 6) {
102+
if (1 + *data_len >= input_len || *data_len < 6) {
104103
return 0;
105104
}
105+
hrp_len = input_len - (1 + *data_len);
106106
*(data_len) -= 6;
107107
for (i = 0; i < hrp_len; ++i) {
108108
int ch = input[i];

src/ctest/test_bech32.c

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#include "config.h"
2+
3+
#include <wally_core.h>
4+
#include <wally_address.h>
5+
#include <stdio.h>
6+
#include <stdbool.h>
7+
8+
static const char *invalid = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg";
9+
10+
static bool check_segwit_to_bytes()
11+
{
12+
unsigned char *mem = calloc(90, sizeof(unsigned char));
13+
size_t written;
14+
int ret;
15+
16+
if (!mem)
17+
return false;
18+
19+
ret = wally_addr_segwit_to_bytes(invalid, "tb", 0, mem, 90, &written);
20+
21+
if (ret != WALLY_EINVAL)
22+
return false;
23+
24+
return true;
25+
}
26+
27+
int main(void)
28+
{
29+
bool tests_ok = true;
30+
31+
if (!check_segwit_to_bytes()) {
32+
printf("check_segwit_to_bytes test failed!\n");
33+
tests_ok = false;
34+
}
35+
36+
return tests_ok ? 0 : 1;
37+
}

src/test/test_bech32.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ def test_segwit_address(self):
6666
ret, result_script_hex = self.decode(addr, family)
6767
self.assertEqual(ret, WALLY_EINVAL)
6868

69+
out, out_len = make_cbuffer('00' * (32 + 2))
70+
bad = 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefg'
71+
ret, written = wally_addr_segwit_to_bytes(utf8(bad), utf8('tb'), 0, out, out_len)
72+
self.assertEqual((ret, written), (WALLY_EINVAL, 0))
73+
6974

7075
if __name__ == '__main__':
7176
unittest.main()

tools/cleanup.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ rm -f src/*pyc
2323
rm -f src/test/*pyc
2424
rm -f src/config.h.in
2525
rm -rf src/lcov*
26+
rm -f src/test_bech32*
2627
rm -f src/test_clear*
2728
rm -f src/test_tx*
2829
rm -f src/test-suite.log

0 commit comments

Comments
 (0)