summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSami Kerola <kerolasa@iki.fi>2019-02-03 12:20:47 +0000
committerSami Kerola <kerolasa@iki.fi>2019-02-03 14:59:27 +0000
commit1571497b3de5ff9771f43a218528dc6ad7441cdc (patch)
tree75bf4adb2db69898562611190881c3a61431a3f4
parenta6b97ab399bf9b7e676c9c0dfc2fd1861557aa69 (diff)
downloadiputils-1571497b3de5ff9771f43a218528dc6ad7441cdc.tar.gz
various: be careful with numeric inputs
Former atoi() did not convert partial numeric strings reasonable way. For example atoi("123x456") will return 123, and ignore characters after invalid first non-digit character. That can cause very weird user experience. It is much better to fail and report if anything in input is even a bit wrong. Secondly unify bounds checks error messaging, and be a lot more explicit what range is expected. Signed-off-by: Sami Kerola <kerolasa@iki.fi>
-rw-r--r--arping.c6
-rw-r--r--ping.c35
-rw-r--r--tracepath.c15
-rw-r--r--traceroute6.c21
4 files changed, 23 insertions, 54 deletions
diff --git a/arping.c b/arping.c
index e369faa..cb1bf70 100644
--- a/arping.c
+++ b/arping.c
@@ -852,13 +852,13 @@ int main(int argc, char **argv)
ctl.quiet = 1;
break;
case 'c':
- ctl.count = atoi(optarg);
+ ctl.count = strtol_or_err(optarg, _("invalid argument"), 1, INT_MAX);
break;
case 'w':
- ctl.timeout = atoi(optarg);
+ ctl.timeout = strtol_or_err(optarg, _("invalid argument"), 0, INT_MAX);
break;
case 'i':
- ctl.interval = (unsigned int)atoi(optarg);
+ ctl.interval = strtol_or_err(optarg, _("invalid argument"), 0, INT_MAX);
break;
case 'I':
ctl.device.name = optarg;
diff --git a/ping.c b/ping.c
index 307a28e..9b2ec80 100644
--- a/ping.c
+++ b/ping.c
@@ -304,9 +304,7 @@ main(int argc, char **argv)
options |= F_STRICTSOURCE;
break;
case 'c':
- npackets = atoi(optarg);
- if (npackets <= 0)
- error(2, 0, _("bad number of packets to transmit: %ld"), npackets);
+ npackets = strtol_or_err(optarg, _("invalid argument"), 1, LONG_MAX);
break;
case 'd':
options |= F_SO_DEBUG;
@@ -352,11 +350,7 @@ main(int argc, char **argv)
}
break;
case 'l':
- preload = atoi(optarg);
- if (preload <= 0)
- error(2, 0, _("bad preload value: %s, should be 1..%d"), optarg, MAX_DUP_CHK);
- if (preload > MAX_DUP_CHK)
- preload = MAX_DUP_CHK;
+ preload = strtol_or_err(optarg, _("invalid argument"), 1, MAX_DUP_CHK);
if (uid && preload > 3)
error(2, 0, _("cannot set preload to value greater than 3: %d"), preload);
break;
@@ -364,14 +358,9 @@ main(int argc, char **argv)
options |= F_NOLOOP;
break;
case 'm':
- {
- char *endp;
- mark = (int)strtoul(optarg, &endp, 10);
- if (mark < 0 || *endp != '\0')
- error(2, 0, _("mark cannot be negative: %s"), optarg);
+ mark = strtol_or_err(optarg, _("invalid argument"), 0, INT_MAX);
options |= F_MARK;
break;
- }
case 'M':
if (strcmp(optarg, "do") == 0)
pmtudisc = IP_PMTUDISC_DO;
@@ -408,22 +397,14 @@ main(int argc, char **argv)
options |= F_SO_DONTROUTE;
break;
case 's':
- datalen = atoi(optarg);
- if (datalen < 0)
- error(2, 0, _("illegal packet size: %d"), datalen);
- if (datalen > MAXPACKET - 8)
- error(2, 0, _("packet size too large: %d"), datalen);
+ datalen = strtol_or_err(optarg, _("invalid argument"), 0, MAXPACKET - 8);
break;
case 'S':
- sndbuf = atoi(optarg);
- if (sndbuf <= 0)
- error(2, 0, _("bad sndbuf value: %s"), optarg);
+ sndbuf = strtol_or_err(optarg, _("invalid argument"), 1, INT_MAX);
break;
case 't':
+ ttl = strtol_or_err(optarg, _("invalid argument"), 0, 255);
options |= F_TTL;
- ttl = atoi(optarg);
- if (ttl < 0 || ttl > 255)
- error(2, 0, _("ttl out of range: %s"), optarg);
break;
case 'U':
options |= F_LATENCY;
@@ -435,9 +416,7 @@ main(int argc, char **argv)
printf(IPUTILS_VERSION("ping"));
exit(0);
case 'w':
- deadline = atoi(optarg);
- if (deadline < 0)
- error(2, 0, _("bad wait time: %s"), optarg);
+ deadline = strtol_or_err(optarg, _("invalid argument"), 0, INT_MAX);
break;
case 'W':
{
diff --git a/tracepath.c b/tracepath.c
index adce499..6095c6a 100644
--- a/tracepath.c
+++ b/tracepath.c
@@ -479,18 +479,13 @@ int main(int argc, char **argv)
ctl.show_both = 1;
break;
case 'l':
- if ((ctl.mtu = atoi(optarg)) <= ctl.overhead)
- error(1, 0, _("pktlen must be > %d and <= %d"),
- ctl.overhead, INT_MAX);
+ ctl.mtu = strtol_or_err(optarg, _("invalid argument"), ctl.overhead, INT_MAX);
break;
case 'm':
- ctl.max_hops = atoi(optarg);
- if (ctl.max_hops < 0 || ctl.max_hops > MAX_HOPS_LIMIT)
- error(1, 0, _("max hops must be 0 .. %d (inclusive)"),
- MAX_HOPS_LIMIT);
+ ctl.max_hops = strtol_or_err(optarg, _("invalid argument"), 0, MAX_HOPS_LIMIT);
break;
case 'p':
- ctl.base_port = atoi(optarg);
+ ctl.base_port = strtol_or_err(optarg, _("invalid argument"), 0, UINT16_MAX);
break;
case 'V':
printf(IPUTILS_VERSION("tracepath"));
@@ -511,7 +506,7 @@ int main(int argc, char **argv)
p = strchr(argv[0], '/');
if (p) {
*p = 0;
- ctl.base_port = atoi(p + 1);
+ ctl.base_port = strtol_or_err(p + 1, _("invalid argument"), 0, UINT16_MAX);
} else
ctl.base_port = DEFAULT_BASEPORT;
}
@@ -631,5 +626,5 @@ int main(int argc, char **argv)
exit(0);
pktlen_error:
- error(1, 0, _("pktlen must be > %d and <= %d"), ctl.overhead, INT_MAX);
+ error(1, 0, _("pktlen must be within: %d < value <= %d"), ctl.overhead, INT_MAX);
}
diff --git a/traceroute6.c b/traceroute6.c
index a0dddeb..6c06972 100644
--- a/traceroute6.c
+++ b/traceroute6.c
@@ -331,10 +331,10 @@ struct run_state {
char *source;
char *device;
char *hostname;
- int nprobes;
+ long nprobes;
int max_ttl;
pid_t ident;
- unsigned short port; /* start udp dest port # for probe packets */
+ uint16_t port; /* start udp dest port # for probe packets */
int options; /* socket options */
int waittime; /* time to wait for response (in seconds) */
unsigned int
@@ -655,7 +655,8 @@ int main(int argc, char **argv)
int status;
struct sockaddr_in6 from;
struct sockaddr_in6 *to = (struct sockaddr_in6 *)&ctl.whereto;
- int ch, i, probe, ttl, on = 1;
+ int ch, i, ttl, on = 1;
+ long probe;
uint32_t seq = 0;
char *resolved_hostname = NULL;
@@ -690,22 +691,16 @@ int main(int argc, char **argv)
ctl.options |= SO_DEBUG;
break;
case 'm':
- ctl.max_ttl = atoi(optarg);
- if (ctl.max_ttl <= 1)
- error(1, 0, _("max ttl must be >1"));
+ ctl.max_ttl = strtol_or_err(optarg, _("invalid argument"), 2, INT_MAX);
break;
case 'n':
ctl.nflag = 1;
break;
case 'p':
- ctl.port = atoi(optarg);
- if (ctl.port < 1)
- error(1, 0, _("port must be >0"));
+ ctl.port = strtol_or_err(optarg, _("invalid argument"), 1, UINT16_MAX);
break;
case 'q':
- ctl.nprobes = atoi(optarg);
- if (ctl.nprobes < 1)
- error(1, 0, _("nprobes must be >0"));
+ ctl.nprobes = strtol_or_err(optarg, _("invalid argument"), 1, LONG_MAX);
break;
case 'r':
ctl.options |= SO_DONTROUTE;
@@ -863,7 +858,7 @@ int main(int argc, char **argv)
for (ttl = 1; ttl <= ctl.max_ttl; ++ttl) {
struct in6_addr lastaddr = { {{0,}} };
uint8_t got_there = 0;
- int unreachable = 0;
+ long unreachable = 0;
printf("%2d ", ttl);
for (probe = 0; probe < ctl.nprobes; ++probe) {