Skip to content

Commit 17b3fb5

Browse files
committed
common/bolt11: meet the new tighter parsing requirements.
These checks are a SHOULD, but implementing them helps avoid anyone making such weird things in future. Signed-off-by: Rusty Russell <[email protected]>
1 parent c0ff1b5 commit 17b3fb5

File tree

2 files changed

+39
-15
lines changed

2 files changed

+39
-15
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ CCANDIR := ccan
2626

2727
# Where we keep the BOLT RFCs
2828
BOLTDIR := ../bolts/
29-
DEFAULT_BOLTVERSION := 216914d492ecdf8a814bbab34fa9f6d31b394b98
29+
DEFAULT_BOLTVERSION := 011bf84d74d130c2972becca97c87f297b9d4a92
3030
# Can be overridden on cmdline.
3131
BOLTVERSION := $(DEFAULT_BOLTVERSION)
3232

common/bolt11.c

Lines changed: 38 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -64,15 +64,21 @@ static const char *pull_bits(struct hash_u5 *hu5,
6464

6565
/* Helper for pulling a variable-length big-endian int. */
6666
static const char *pull_uint(struct hash_u5 *hu5,
67-
const u5 **data, size_t *data_len,
68-
u64 *val, size_t databits)
67+
const u5 **data, size_t *data_len,
68+
u64 *val, size_t databits,
69+
bool must_be_minimal)
6970
{
7071
be64 be_val;
7172
const char *err;
7273

7374
/* Too big. */
7475
if (databits > sizeof(be_val) * CHAR_BIT)
7576
return "integer too large";
77+
if (must_be_minimal
78+
&& databits >= 5
79+
&& *data_len > 1
80+
&& (*data)[0] == 0)
81+
return "not a minimal value";
7682
err = pull_bits(hu5, data, data_len, &be_val, databits, true);
7783
if (err)
7884
return err;
@@ -262,8 +268,12 @@ static const char *decode_x(struct bolt11 *b11,
262268

263269
assert(!*have_x);
264270

265-
/* FIXME: Put upper limit in bolt 11 */
266-
err = pull_uint(hu5, data, field_len, &b11->expiry, *field_len * 5);
271+
/* BOLT #11:
272+
* - if a `c`, `x`, or `9` field is provided which has a non-minimal `data_length`
273+
* (i.e. begins with 0 field elements):
274+
* - SHOULD treat the invoice as invalid.
275+
*/
276+
err = pull_uint(hu5, data, field_len, &b11->expiry, *field_len * 5, true);
267277
if (err)
268278
return tal_fmt(b11, "x: %s", err);
269279

@@ -287,8 +297,12 @@ static const char *decode_c(struct bolt11 *b11,
287297

288298
assert(!*have_c);
289299

290-
/* FIXME: Put upper limit in bolt 11 */
291-
err = pull_uint(hu5, data, field_len, &c, *field_len * 5);
300+
/* BOLT #11:
301+
* - if a `c`, `x`, or `9` field is provided which has a non-minimal `data_length`
302+
* (i.e. begins with 0 field elements):
303+
* - SHOULD treat the invoice as invalid.
304+
*/
305+
err = pull_uint(hu5, data, field_len, &c, *field_len * 5, true);
292306
if (err)
293307
return tal_fmt(b11, "c: %s", err);
294308
b11->min_final_cltv_expiry = c;
@@ -375,7 +389,7 @@ static const char *decode_f(struct bolt11 *b11,
375389
size_t orig_len = *field_len;
376390
const char *err;
377391

378-
err = pull_uint(hu5, data, field_len, &version, 5);
392+
err = pull_uint(hu5, data, field_len, &version, 5, false);
379393
if (err)
380394
return tal_fmt(b11, "f: %s", err);
381395

@@ -550,6 +564,14 @@ static const char *decode_9(struct bolt11 *b11,
550564
if (!b11->features)
551565
return err;
552566

567+
/* BOLT #11:
568+
* - if a `c`, `x`, or `9` field is provided which has a non-minimal `data_length`
569+
* (i.e. begins with 0 field elements):
570+
* - SHOULD treat the invoice as invalid.
571+
*/
572+
if (tal_count(b11->features) > 0 && b11->features[0] == 0)
573+
return tal_fmt(b11, "9: non-minimal length (begins with 0)");
574+
553575
/* pull_bits pads with zero bits: we need to remove them. */
554576
shift_bitmap_down(b11->features,
555577
flen * 8 - databits);
@@ -847,7 +869,7 @@ struct bolt11 *bolt11_decode_nosig(const tal_t *ctx, const char *str,
847869
* 1. zero or more tagged parts
848870
* 1. `signature`: Bitcoin-style signature of above (520 bits)
849871
*/
850-
err = pull_uint(&hu5, &data, &data_len, &b11->timestamp, 35);
872+
err = pull_uint(&hu5, &data, &data_len, &b11->timestamp, 35, false);
851873
if (err)
852874
return decode_fail(b11, fail,
853875
"Can't get 35-bit timestamp: %s", err);
@@ -866,11 +888,11 @@ struct bolt11 *bolt11_decode_nosig(const tal_t *ctx, const char *str,
866888
* 1. `data_length` (10 bits, big-endian)
867889
* 1. `data` (`data_length` x 5 bits)
868890
*/
869-
err = pull_uint(&hu5, &data, &data_len, &type, 5);
891+
err = pull_uint(&hu5, &data, &data_len, &type, 5, false);
870892
if (err)
871893
return decode_fail(b11, fail,
872894
"Can't get tag: %s", err);
873-
err = pull_uint(&hu5, &data, &data_len, &field_len64, 10);
895+
err = pull_uint(&hu5, &data, &data_len, &field_len64, 10, false);
874896
if (err)
875897
return decode_fail(b11, fail,
876898
"Can't get length: %s", err);
@@ -1053,10 +1075,11 @@ static void push_field(u5 **data, char type, const void *src, size_t nbits)
10531075
/* BOLT #11:
10541076
*
10551077
* - if `x` is included:
1056-
* - SHOULD use the minimum `data_length` possible.
1078+
* - MUST use the minimum `data_length` possible, i.e. no leading 0 field-elements.
10571079
* - SHOULD include one `c` field (`min_final_cltv_expiry_delta`).
1058-
*...
1059-
* - SHOULD use the minimum `data_length` possible.
1080+
* - MUST set `c` to the minimum `cltv_expiry` it will accept for the last
1081+
* HTLC in the route.
1082+
* - MUST use the minimum `data_length` possible, i.e. no leading 0 field-elements.
10601083
*/
10611084
static void push_varlen_field(u5 **data, char type, u64 val)
10621085
{
@@ -1197,7 +1220,8 @@ static void maybe_encode_9(u5 **data, const u8 *features,
11971220
/* BOLT #11:
11981221
*
11991222
* - if `9` contains non-zero bits:
1200-
* - SHOULD use the minimum `data_length` possible.
1223+
* - MUST use the minimum `data_length` possible to encode the non-zero bits
1224+
* with no 0 field-elements at the start.
12011225
* - otherwise:
12021226
* - MUST omit the `9` field altogether.
12031227
*/

0 commit comments

Comments
 (0)