diff --git a/lightningd/dev_ping.c b/lightningd/dev_ping.c index 24b0cdfce..001f273dc 100644 --- a/lightningd/dev_ping.c +++ b/lightningd/dev_ping.c @@ -62,6 +62,26 @@ static void json_dev_ping(struct command *cmd, return; } + /* BOLT #1: + * + * 1. `type`: a 2-byte big-endian field indicating the type of message + * 2. `payload` + *... + * The size of the message is required by the transport layer to fit + * into a 2-byte unsigned int; therefore, the maximum possible size is + * 65535 bytes. + *... + * 1. type: 18 (`ping`) + * 2. data: + * * [`2`:`num_pong_bytes`] + * * [`2`:`byteslen`] + * * [`byteslen`:`ignored`] + */ + if (len > 65535 - 2 - 2 - 2) { + command_fail(cmd, "%u would result in oversize ping", len); + return; + } + if (!json_tok_number(buffer, pongbytestok, &pongbytes)) { command_fail(cmd, "'%.*s' is not a valid number", pongbytestok->end - pongbytestok->start, @@ -69,6 +89,12 @@ static void json_dev_ping(struct command *cmd, return; } + /* Note that > 65531 is valid: it means "no pong reply" */ + if (pongbytes > 65535) { + command_fail(cmd, "pongbytes %u > 65535", pongbytes); + return; + } + if (!json_tok_pubkey(buffer, idtok, &id)) { command_fail(cmd, "'%.*s' is not a valid pubkey", idtok->end - idtok->start, diff --git a/tests/test_lightningd.py b/tests/test_lightningd.py index f8f592fa4..520e41d11 100644 --- a/tests/test_lightningd.py +++ b/tests/test_lightningd.py @@ -1851,6 +1851,11 @@ class LightningDTests(BaseLightningDTests): ret = l1.rpc.dev_ping(l2.info['id'], 1000, s) assert ret['totlen'] == 0 + # 65535 - type(2 bytes) - num_pong_bytes(2 bytes) - byteslen(2 bytes) + # = 65529 max. + self.assertRaisesRegex(ValueError, r'oversize ping', + l1.rpc.dev_ping, l2.info['id'], 65530, 1) + @unittest.skipIf(not DEVELOPER, "needs DEVELOPER=1") def test_ping(self): l1,l2 = self.connect()