Skip to content

Commit c8000f2

Browse files
author
Chandra Pratap
committed
common/test: Add a test to trigger the bug
Add a test in `common/test/run-wireaddr.c` that reproduces the out-of-bounds error when the fix is not applied.
1 parent c425de3 commit c8000f2

File tree

2 files changed

+37
-63
lines changed

2 files changed

+37
-63
lines changed

common/test/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,4 +128,6 @@ common/test/run-htable: \
128128

129129
common/test/run-shutdown_scriptpubkey: wire/towire.o wire/fromwire.o
130130

131+
common/test/run-wireaddr: wire/towire.o wire/fromwire.o
132+
131133
check-units: $(COMMON_TEST_PROGRAMS:%=unittest/%)

common/test/run-wireaddr.c

Lines changed: 35 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -58,69 +58,6 @@ u8 *b32_decode(const tal_t *ctx UNNEEDED, const char *str UNNEEDED, size_t len U
5858
/* Generated stub for b32_encode */
5959
char *b32_encode(const tal_t *ctx UNNEEDED, const void *data UNNEEDED, size_t len UNNEEDED)
6060
{ fprintf(stderr, "b32_encode called!\n"); abort(); }
61-
/* Generated stub for fromwire */
62-
const u8 *fromwire(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, void *copy UNNEEDED, size_t n UNNEEDED)
63-
{ fprintf(stderr, "fromwire called!\n"); abort(); }
64-
/* Generated stub for fromwire_bool */
65-
bool fromwire_bool(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
66-
{ fprintf(stderr, "fromwire_bool called!\n"); abort(); }
67-
/* Generated stub for fromwire_fail */
68-
void *fromwire_fail(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
69-
{ fprintf(stderr, "fromwire_fail called!\n"); abort(); }
70-
/* Generated stub for fromwire_secp256k1_ecdsa_signature */
71-
void fromwire_secp256k1_ecdsa_signature(const u8 **cursor UNNEEDED, size_t *max UNNEEDED,
72-
secp256k1_ecdsa_signature *signature UNNEEDED)
73-
{ fprintf(stderr, "fromwire_secp256k1_ecdsa_signature called!\n"); abort(); }
74-
/* Generated stub for fromwire_sha256 */
75-
void fromwire_sha256(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, struct sha256 *sha256 UNNEEDED)
76-
{ fprintf(stderr, "fromwire_sha256 called!\n"); abort(); }
77-
/* Generated stub for fromwire_tal_arrn */
78-
u8 *fromwire_tal_arrn(const tal_t *ctx UNNEEDED,
79-
const u8 **cursor UNNEEDED, size_t *max UNNEEDED, size_t num UNNEEDED)
80-
{ fprintf(stderr, "fromwire_tal_arrn called!\n"); abort(); }
81-
/* Generated stub for fromwire_u16 */
82-
u16 fromwire_u16(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
83-
{ fprintf(stderr, "fromwire_u16 called!\n"); abort(); }
84-
/* Generated stub for fromwire_u32 */
85-
u32 fromwire_u32(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
86-
{ fprintf(stderr, "fromwire_u32 called!\n"); abort(); }
87-
/* Generated stub for fromwire_u64 */
88-
u64 fromwire_u64(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
89-
{ fprintf(stderr, "fromwire_u64 called!\n"); abort(); }
90-
/* Generated stub for fromwire_u8 */
91-
u8 fromwire_u8(const u8 **cursor UNNEEDED, size_t *max UNNEEDED)
92-
{ fprintf(stderr, "fromwire_u8 called!\n"); abort(); }
93-
/* Generated stub for fromwire_u8_array */
94-
void fromwire_u8_array(const u8 **cursor UNNEEDED, size_t *max UNNEEDED, u8 *arr UNNEEDED, size_t num UNNEEDED)
95-
{ fprintf(stderr, "fromwire_u8_array called!\n"); abort(); }
96-
/* Generated stub for towire */
97-
void towire(u8 **pptr UNNEEDED, const void *data UNNEEDED, size_t len UNNEEDED)
98-
{ fprintf(stderr, "towire called!\n"); abort(); }
99-
/* Generated stub for towire_bool */
100-
void towire_bool(u8 **pptr UNNEEDED, bool v UNNEEDED)
101-
{ fprintf(stderr, "towire_bool called!\n"); abort(); }
102-
/* Generated stub for towire_secp256k1_ecdsa_signature */
103-
void towire_secp256k1_ecdsa_signature(u8 **pptr UNNEEDED,
104-
const secp256k1_ecdsa_signature *signature UNNEEDED)
105-
{ fprintf(stderr, "towire_secp256k1_ecdsa_signature called!\n"); abort(); }
106-
/* Generated stub for towire_sha256 */
107-
void towire_sha256(u8 **pptr UNNEEDED, const struct sha256 *sha256 UNNEEDED)
108-
{ fprintf(stderr, "towire_sha256 called!\n"); abort(); }
109-
/* Generated stub for towire_u16 */
110-
void towire_u16(u8 **pptr UNNEEDED, u16 v UNNEEDED)
111-
{ fprintf(stderr, "towire_u16 called!\n"); abort(); }
112-
/* Generated stub for towire_u32 */
113-
void towire_u32(u8 **pptr UNNEEDED, u32 v UNNEEDED)
114-
{ fprintf(stderr, "towire_u32 called!\n"); abort(); }
115-
/* Generated stub for towire_u64 */
116-
void towire_u64(u8 **pptr UNNEEDED, u64 v UNNEEDED)
117-
{ fprintf(stderr, "towire_u64 called!\n"); abort(); }
118-
/* Generated stub for towire_u8 */
119-
void towire_u8(u8 **pptr UNNEEDED, u8 v UNNEEDED)
120-
{ fprintf(stderr, "towire_u8 called!\n"); abort(); }
121-
/* Generated stub for towire_u8_array */
122-
void towire_u8_array(u8 **pptr UNNEEDED, const u8 *arr UNNEEDED, size_t num UNNEEDED)
123-
{ fprintf(stderr, "towire_u8_array called!\n"); abort(); }
12461
/* AUTOGENERATED MOCKS END */
12562

12663
int main(int argc, char *argv[])
@@ -287,6 +224,41 @@ int main(int argc, char *argv[])
287224
expect->u.unresolved.port = 1234;
288225
assert(wireaddr_internal_eq(&addr, expect));
289226

227+
/*
228+
* Test for an out-of-bounds bug in fromwire_wireaddr().
229+
*
230+
* This test reproduces a bug that occurs when decoding a DNS wireaddr
231+
* of the maximum possible length (255 bytes). fromwire_wireaddr()
232+
* would correctly read the 255 bytes of the address, but then attempt
233+
* to write a null terminator at index 255, causing a one-byte
234+
* overflow on the 255-byte destination buffer.
235+
*
236+
* The expected UBSan error is:
237+
* common/wireaddr.c:51:3: runtime error: index 255 out of bounds for type 'u8[255]'
238+
*/
239+
240+
const char *dnsaddr =
241+
/* 63 'a' */ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."
242+
/* 63 'b' */ "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb."
243+
/* 63 'c' */ "ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc."
244+
/* 63 'd' */ "ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd";
245+
246+
struct wireaddr wa = {
247+
.type = ADDR_TYPE_DNS,
248+
.addrlen = 255,
249+
.port = DEFAULT_PORT
250+
};
251+
252+
memcpy(wa.addr, dnsaddr, wa.addrlen);
253+
254+
u8 *encoded_wa = tal_arr(tmpctx, u8, 0);
255+
towire_wireaddr(&encoded_wa, &wa);
256+
size_t encoded_wa_len = tal_bytelen(encoded_wa);
257+
258+
struct wireaddr decoded_wa;
259+
assert(fromwire_wireaddr((const u8 **) &encoded_wa, &encoded_wa_len, &decoded_wa));
260+
assert(wireaddr_eq(&wa, &decoded_wa));
261+
290262
tal_free(expect);
291263
common_shutdown();
292264
}

0 commit comments

Comments
 (0)