diff --git a/sys/net/gnrc/network_layer/icmpv6/echo/gnrc_icmpv6_echo.c b/sys/net/gnrc/network_layer/icmpv6/echo/gnrc_icmpv6_echo.c index a6b9003d662ea..6c6fe939d4888 100644 --- a/sys/net/gnrc/network_layer/icmpv6/echo/gnrc_icmpv6_echo.c +++ b/sys/net/gnrc/network_layer/icmpv6/echo/gnrc_icmpv6_echo.c @@ -150,6 +150,12 @@ int gnrc_icmpv6_echo_send(const gnrc_netif_t *netif, const ipv6_addr_t *addr, ipv6_hdr_t *ipv6; uint8_t *databuf; + /* max IPv6 payload 65535 minus 8 bytes of icmp header = 65527 */ + if (len > (UINT16_MAX - sizeof(icmpv6_hdr_t))) { + DEBUG("error: wrong icmpv6 packet length\n"); + return -EINVAL; + } + pkt = gnrc_icmpv6_echo_build(ICMPV6_ECHO_REQ, id, seq, NULL, len); if (pkt == NULL) { DEBUG("error: packet buffer full\n"); diff --git a/sys/shell/cmds/gnrc_icmpv6_echo.c b/sys/shell/cmds/gnrc_icmpv6_echo.c index 3c1c3776f68a1..acd0295ff762c 100644 --- a/sys/shell/cmds/gnrc_icmpv6_echo.c +++ b/sys/shell/cmds/gnrc_icmpv6_echo.c @@ -172,6 +172,7 @@ static int _configure(int argc, char **argv, _ping_data_t *data) { char *cmdname = argv[0]; int res = 1; + int value; /* parse command line arguments */ for (int i = 1; i < argc; i++) { @@ -207,7 +208,13 @@ static int _configure(int argc, char **argv, _ping_data_t *data) /* intentionally falls through */ case 's': if ((++i) < argc) { - data->datalen = atoi(argv[i]); + value = atoi(argv[i]); + + if ((value < 0) || ((unsigned)value > (UINT16_MAX - sizeof(icmpv6_hdr_t)))) { + printf("ICMPv6 datagram size should be in range 0-65527.\n"); + return -1; + } + data->datalen = value; continue; } /* intentionally falls through */