Skip to content

Commit a57c377

Browse files
committed
wire: use 26-bit lengths for inter-daemon messaging.
Fixes: ElementsProject#289 Signed-off-by: Rusty Russell <[email protected]>
1 parent 019bf9c commit a57c377

File tree

4 files changed

+37
-22
lines changed

4 files changed

+37
-22
lines changed

lightningd/peer_control.c

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2525,11 +2525,6 @@ void peer_fundee_open(struct peer *peer, const u8 *from_peer,
25252525
msg = towire_opening_fundee(peer, peer->minimum_depth,
25262526
7500, 150000, from_peer);
25272527

2528-
/* Careful here! Their message could push us overlength! */
2529-
if (tal_len(msg) >= 65536) {
2530-
peer_fail_permanent_str(peer, "Unacceptably long open_channel");
2531-
return;
2532-
}
25332528
subd_req(peer, peer->owner, take(msg), -1, 2,
25342529
opening_fundee_finished, peer);
25352530
}

wire/wire_io.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
#include <ccan/endian/endian.h>
21
/* FIXME: io_plan needs size_t */
32
#include <unistd.h>
43
#include <ccan/io/io_plan.h>
54
#include <ccan/mem/mem.h>
65
#include <ccan/short_types/short_types.h>
76
#include <ccan/take/take.h>
87
#include <ccan/tal/tal.h>
8+
#include <errno.h>
99
#include <wire/wire_io.h>
1010

1111
/*
@@ -14,11 +14,11 @@
1414
* scratch data, and it's almost enough for our purposes.
1515
*/
1616

17-
/* 2 bytes for the length header. */
18-
#define HEADER_LEN (sizeof(le16))
17+
/* 4 bytes for the length header. */
18+
#define HEADER_LEN (sizeof(wire_len_t))
1919

20-
/* Since length can only be 64k, this is an impossible value. */
21-
#define INSIDE_HEADER_BIT 0x80000000
20+
/* We carefully never allow sizes > 64M, so this is an impossible value. */
21+
#define INSIDE_HEADER_BIT WIRE_LEN_LIMIT
2222

2323
/* arg->u2.s contains length we've read, arg->u1.vp contains u8 **data. */
2424
static int do_read_wire_header(int fd, struct io_plan_arg *arg)
@@ -32,9 +32,13 @@ static int do_read_wire_header(int fd, struct io_plan_arg *arg)
3232
return -1;
3333
arg->u2.s += ret;
3434

35-
/* Both bytes read? Set up for normal read of data. */
35+
/* Length bytes read? Set up for normal read of data. */
3636
if (arg->u2.s == INSIDE_HEADER_BIT + HEADER_LEN) {
37-
arg->u2.s = be16_to_cpu(*(be16 *)p);
37+
arg->u2.s = *(wire_len_t *)p;
38+
if (arg->u2.s >= INSIDE_HEADER_BIT) {
39+
errno = E2BIG;
40+
return -1;
41+
}
3842
/* A type-only message is not unheard of, so optimize a little */
3943
if (arg->u2.s != HEADER_LEN)
4044
tal_resize((u8 **)arg->u1.vp, arg->u2.s);
@@ -84,7 +88,7 @@ static int do_write_wire_header(int fd, struct io_plan_arg *arg)
8488
{
8589
ssize_t ret;
8690
size_t len = arg->u2.s & ~INSIDE_HEADER_BIT;
87-
be16 hdr = cpu_to_be16(tal_count(arg->u1.const_vp));
91+
wire_len_t hdr = tal_count(arg->u1.const_vp);
8892

8993
ret = write(fd, (char *)&hdr + len, HEADER_LEN - len);
9094
if (ret <= 0)
@@ -128,6 +132,11 @@ struct io_plan *io_write_wire_(struct io_conn *conn,
128132
{
129133
struct io_plan_arg *arg = io_plan_arg(conn, IO_OUT);
130134

135+
if (tal_len(data) >= INSIDE_HEADER_BIT) {
136+
errno = E2BIG;
137+
return io_close(conn);
138+
}
139+
131140
arg->u1.const_vp = tal_dup_arr(conn, u8, memcheck(data, tal_len(data)),
132141
tal_len(data), 0);
133142

wire/wire_io.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
#include <ccan/io/io.h>
55
#include <ccan/short_types/short_types.h>
66

7+
/* We don't allow > 64M msgs: enough for 483 64k failure msgs. */
8+
#define WIRE_LEN_LIMIT (1 << 26)
9+
10+
typedef u32 wire_len_t;
11+
712
/* Read message into *data, allocating off ctx. */
813
struct io_plan *io_read_wire_(struct io_conn *conn,
914
const tal_t *ctx,

wire/wire_sync.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1-
#include "wire/wire_sync.h"
21
#include <assert.h>
32
#include <ccan/endian/endian.h>
43
#include <ccan/read_write_all/read_write_all.h>
4+
#include <errno.h>
5+
#include <wire/wire_io.h>
6+
#include <wire/wire_sync.h>
57

68
bool wire_sync_write(int fd, const void *msg TAKES)
79
{
8-
be16 be_len = cpu_to_be16(tal_count(msg));
10+
wire_len_t len = tal_len(msg);
911
bool ret;
1012

11-
assert(be16_to_cpu(be_len) == tal_count(msg));
12-
ret = write_all(fd, &be_len, sizeof(be_len))
13-
&& write_all(fd, msg, tal_count(msg));
13+
assert(tal_len(msg) < WIRE_LEN_LIMIT);
14+
ret = write_all(fd, &len, sizeof(len))
15+
&& write_all(fd, msg, len);
1416

1517
if (taken(msg))
1618
tal_free(msg);
@@ -19,13 +21,17 @@ bool wire_sync_write(int fd, const void *msg TAKES)
1921

2022
u8 *wire_sync_read(const tal_t *ctx, int fd)
2123
{
22-
be16 be_len;
24+
wire_len_t len;
2325
u8 *msg;
2426

25-
if (!read_all(fd, &be_len, sizeof(be_len)))
27+
if (!read_all(fd, &len, sizeof(len)))
2628
return NULL;
27-
msg = tal_arr(ctx, u8, be16_to_cpu(be_len));
28-
if (!read_all(fd, msg, be16_to_cpu(be_len)))
29+
if (len >= WIRE_LEN_LIMIT) {
30+
errno = E2BIG;
31+
return NULL;
32+
}
33+
msg = tal_arr(ctx, u8, len);
34+
if (!read_all(fd, msg, len))
2935
return tal_free(msg);
3036
return msg;
3137
}

0 commit comments

Comments
 (0)