Skip to content

Commit

Permalink
ping: Limit -s max. value
Browse files Browse the repository at this point in the history
Max value for ping -s option cannot be higher than maximum IPv4/v6
packet size, which is 65535. More precisely, the value should respect
maximum IPv4/v6 ICMP data length.

Use the higher value unless user chose the protocol.

Fixes: iputils#542
Reported-by: mimicria
Signed-off-by: Petr Vorel <[email protected]>
  • Loading branch information
pevik committed Aug 9, 2024
1 parent 1e65aee commit 3258f8e
Showing 1 changed file with 24 additions and 1 deletion.
25 changes: 24 additions & 1 deletion ping/ping.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
#include <ifaddrs.h>
#include <math.h>
#include <locale.h>
#include <sys/param.h>

/* FIXME: global_rts will be removed in future */
struct ping_rts *global_rts;
Expand All @@ -84,6 +85,12 @@ ping_func_set_st ping4_func_set = {
#define NROUTES 9 /* number of record route slots */
#define TOS_MAX 255 /* 8-bit TOS field */

/* max. IPv4 packet size - IPv4 header size - ICMP header size */
#define ICMP_MAX_DATALEN (65535 - IPV4_HEADER_MINLEN - ICMP_HEADER_MINLEN)

/* max. IPv6 payload size) - ICMPv6 Echo Reply Header */
#define ICMPV6_MAX_DATALEN (65535 - sizeof (struct icmp6_hdr))

#define CASE_TYPE(x) case x: return #x;

static char *str_family(int family)
Expand Down Expand Up @@ -338,6 +345,9 @@ main(int argc, char **argv)
.ni.query = -1,
.ni.subject_type = -1,
};

size_t max_s = MAX(ICMP_MAX_DATALEN, ICMPV6_MAX_DATALEN);

/* FIXME: global_rts will be removed in future */
global_rts = &rts;

Expand Down Expand Up @@ -531,7 +541,7 @@ main(int argc, char **argv)
rts.opt_so_dontroute = 1;
break;
case 's':
rts.datalen = strtol_or_err(optarg, _("invalid argument"), 0, INT_MAX);
rts.datalen = strtol_or_err(optarg, _("invalid argument"), 0, max_s);
break;
case 'S':
rts.sndbuf = strtol_or_err(optarg, _("invalid argument"), 1, INT_MAX);
Expand Down Expand Up @@ -626,6 +636,19 @@ main(int argc, char **argv)
hints.ai_family = AF_INET;
}

switch (hints.ai_family) {
case AF_INET:
max_s = ICMP_MAX_DATALEN;
break;
case AF_INET6:
max_s = ICMPV6_MAX_DATALEN;
break;
}

if (rts.datalen > max_s)
error(EXIT_FAILURE, 0, "invalid -s value: '%ld': out of range: %d <= value <= %ld",
rts.datalen, 0, max_s);

if (rts.opt_verbose)
error(0, 0, "sock4.fd: %d (socktype: %s), sock6.fd: %d (socktype: %s),"
" hints.ai_family: %s\n",
Expand Down

0 comments on commit 3258f8e

Please sign in to comment.