diff options
author | Sami Kerola <kerolasa@iki.fi> | 2019-02-03 12:20:47 +0000 |
---|---|---|
committer | Sami Kerola <kerolasa@iki.fi> | 2019-02-03 14:59:27 +0000 |
commit | 1571497b3de5ff9771f43a218528dc6ad7441cdc (patch) | |
tree | 75bf4adb2db69898562611190881c3a61431a3f4 | |
parent | a6b97ab399bf9b7e676c9c0dfc2fd1861557aa69 (diff) | |
download | iputils-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.c | 6 | ||||
-rw-r--r-- | ping.c | 35 | ||||
-rw-r--r-- | tracepath.c | 15 | ||||
-rw-r--r-- | traceroute6.c | 21 |
4 files changed, 23 insertions, 54 deletions
@@ -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; @@ -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) { |