ping(8): improve diagnostics in case of wrong arguments.
For example, in case of super-user: $ sudo ping -s -64 127.0.0.1 PING 127.0.0.1 (127.0.0.1): -64 data bytes ping: sendto: Invalid argument For unprivileged user: $ ping -s -64 127.0.0.1 ping: packet size too large: 18446744073709551552 > 56: Operation not permitted Fix this by switching from strtoul() to strtol() for integer arguments and adding explicit checks for negative values. MFC after: 1 month
This commit is contained in:
parent
0a9fcf3237
commit
c0a3773ad2
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=340245
@ -242,7 +242,8 @@ main(int argc, char *const *argv)
|
|||||||
#endif
|
#endif
|
||||||
struct sockaddr_in *to;
|
struct sockaddr_in *to;
|
||||||
double t;
|
double t;
|
||||||
u_long alarmtimeout, ultmp;
|
u_long alarmtimeout;
|
||||||
|
long ltmp;
|
||||||
int almost_done, ch, df, hold, i, icmp_len, mib[4], preload;
|
int almost_done, ch, df, hold, i, icmp_len, mib[4], preload;
|
||||||
int ssend_errno, srecv_errno, tos, ttl;
|
int ssend_errno, srecv_errno, tos, ttl;
|
||||||
char ctrl[CMSG_SPACE(sizeof(struct timeval))];
|
char ctrl[CMSG_SPACE(sizeof(struct timeval))];
|
||||||
@ -311,12 +312,12 @@ main(int argc, char *const *argv)
|
|||||||
options |= F_AUDIBLE;
|
options |= F_AUDIBLE;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
ultmp = strtoul(optarg, &ep, 0);
|
ltmp = strtol(optarg, &ep, 0);
|
||||||
if (*ep || ep == optarg || ultmp > LONG_MAX || !ultmp)
|
if (*ep || ep == optarg || ltmp > LONG_MAX || ltmp <=0)
|
||||||
errx(EX_USAGE,
|
errx(EX_USAGE,
|
||||||
"invalid count of packets to transmit: `%s'",
|
"invalid count of packets to transmit: `%s'",
|
||||||
optarg);
|
optarg);
|
||||||
npackets = ultmp;
|
npackets = ltmp;
|
||||||
break;
|
break;
|
||||||
case 'D':
|
case 'D':
|
||||||
options |= F_HDRINCL;
|
options |= F_HDRINCL;
|
||||||
@ -334,46 +335,46 @@ main(int argc, char *const *argv)
|
|||||||
setbuf(stdout, (char *)NULL);
|
setbuf(stdout, (char *)NULL);
|
||||||
break;
|
break;
|
||||||
case 'G': /* Maximum packet size for ping sweep */
|
case 'G': /* Maximum packet size for ping sweep */
|
||||||
ultmp = strtoul(optarg, &ep, 0);
|
ltmp = strtol(optarg, &ep, 0);
|
||||||
if (*ep || ep == optarg)
|
if (*ep || ep == optarg || ltmp <= 0)
|
||||||
errx(EX_USAGE, "invalid packet size: `%s'",
|
errx(EX_USAGE, "invalid packet size: `%s'",
|
||||||
optarg);
|
optarg);
|
||||||
if (uid != 0 && ultmp > DEFDATALEN) {
|
if (uid != 0 && ltmp > DEFDATALEN) {
|
||||||
errno = EPERM;
|
errno = EPERM;
|
||||||
err(EX_NOPERM,
|
err(EX_NOPERM,
|
||||||
"packet size too large: %lu > %u",
|
"packet size too large: %ld > %u",
|
||||||
ultmp, DEFDATALEN);
|
ltmp, DEFDATALEN);
|
||||||
}
|
}
|
||||||
options |= F_SWEEP;
|
options |= F_SWEEP;
|
||||||
sweepmax = ultmp;
|
sweepmax = ltmp;
|
||||||
break;
|
break;
|
||||||
case 'g': /* Minimum packet size for ping sweep */
|
case 'g': /* Minimum packet size for ping sweep */
|
||||||
ultmp = strtoul(optarg, &ep, 0);
|
ltmp = strtol(optarg, &ep, 0);
|
||||||
if (*ep || ep == optarg)
|
if (*ep || ep == optarg || ltmp <= 0)
|
||||||
errx(EX_USAGE, "invalid packet size: `%s'",
|
errx(EX_USAGE, "invalid packet size: `%s'",
|
||||||
optarg);
|
optarg);
|
||||||
if (uid != 0 && ultmp > DEFDATALEN) {
|
if (uid != 0 && ltmp > DEFDATALEN) {
|
||||||
errno = EPERM;
|
errno = EPERM;
|
||||||
err(EX_NOPERM,
|
err(EX_NOPERM,
|
||||||
"packet size too large: %lu > %u",
|
"packet size too large: %ld > %u",
|
||||||
ultmp, DEFDATALEN);
|
ltmp, DEFDATALEN);
|
||||||
}
|
}
|
||||||
options |= F_SWEEP;
|
options |= F_SWEEP;
|
||||||
sweepmin = ultmp;
|
sweepmin = ltmp;
|
||||||
break;
|
break;
|
||||||
case 'h': /* Packet size increment for ping sweep */
|
case 'h': /* Packet size increment for ping sweep */
|
||||||
ultmp = strtoul(optarg, &ep, 0);
|
ltmp = strtol(optarg, &ep, 0);
|
||||||
if (*ep || ep == optarg || ultmp < 1)
|
if (*ep || ep == optarg || ltmp < 1)
|
||||||
errx(EX_USAGE, "invalid increment size: `%s'",
|
errx(EX_USAGE, "invalid increment size: `%s'",
|
||||||
optarg);
|
optarg);
|
||||||
if (uid != 0 && ultmp > DEFDATALEN) {
|
if (uid != 0 && ltmp > DEFDATALEN) {
|
||||||
errno = EPERM;
|
errno = EPERM;
|
||||||
err(EX_NOPERM,
|
err(EX_NOPERM,
|
||||||
"packet size too large: %lu > %u",
|
"packet size too large: %ld > %u",
|
||||||
ultmp, DEFDATALEN);
|
ltmp, DEFDATALEN);
|
||||||
}
|
}
|
||||||
options |= F_SWEEP;
|
options |= F_SWEEP;
|
||||||
sweepincr = ultmp;
|
sweepincr = ltmp;
|
||||||
break;
|
break;
|
||||||
case 'I': /* multicast interface */
|
case 'I': /* multicast interface */
|
||||||
if (inet_aton(optarg, &ifaddr) == 0)
|
if (inet_aton(optarg, &ifaddr) == 0)
|
||||||
@ -399,15 +400,15 @@ main(int argc, char *const *argv)
|
|||||||
loop = 0;
|
loop = 0;
|
||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
ultmp = strtoul(optarg, &ep, 0);
|
ltmp = strtol(optarg, &ep, 0);
|
||||||
if (*ep || ep == optarg || ultmp > INT_MAX)
|
if (*ep || ep == optarg || ltmp > INT_MAX || ltmp < 0)
|
||||||
errx(EX_USAGE,
|
errx(EX_USAGE,
|
||||||
"invalid preload value: `%s'", optarg);
|
"invalid preload value: `%s'", optarg);
|
||||||
if (uid) {
|
if (uid) {
|
||||||
errno = EPERM;
|
errno = EPERM;
|
||||||
err(EX_NOPERM, "-l flag");
|
err(EX_NOPERM, "-l flag");
|
||||||
}
|
}
|
||||||
preload = ultmp;
|
preload = ltmp;
|
||||||
break;
|
break;
|
||||||
case 'M':
|
case 'M':
|
||||||
switch(optarg[0]) {
|
switch(optarg[0]) {
|
||||||
@ -425,10 +426,10 @@ main(int argc, char *const *argv)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'm': /* TTL */
|
case 'm': /* TTL */
|
||||||
ultmp = strtoul(optarg, &ep, 0);
|
ltmp = strtol(optarg, &ep, 0);
|
||||||
if (*ep || ep == optarg || ultmp > MAXTTL)
|
if (*ep || ep == optarg || ltmp > MAXTTL || ltmp < 0)
|
||||||
errx(EX_USAGE, "invalid TTL: `%s'", optarg);
|
errx(EX_USAGE, "invalid TTL: `%s'", optarg);
|
||||||
ttl = ultmp;
|
ttl = ltmp;
|
||||||
options |= F_TTL;
|
options |= F_TTL;
|
||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
@ -470,24 +471,24 @@ main(int argc, char *const *argv)
|
|||||||
source = optarg;
|
source = optarg;
|
||||||
break;
|
break;
|
||||||
case 's': /* size of packet to send */
|
case 's': /* size of packet to send */
|
||||||
ultmp = strtoul(optarg, &ep, 0);
|
ltmp = strtol(optarg, &ep, 0);
|
||||||
if (*ep || ep == optarg)
|
if (*ep || ep == optarg || ltmp < 0)
|
||||||
errx(EX_USAGE, "invalid packet size: `%s'",
|
errx(EX_USAGE, "invalid packet size: `%s'",
|
||||||
optarg);
|
optarg);
|
||||||
if (uid != 0 && ultmp > DEFDATALEN) {
|
if (uid != 0 && ltmp > DEFDATALEN) {
|
||||||
errno = EPERM;
|
errno = EPERM;
|
||||||
err(EX_NOPERM,
|
err(EX_NOPERM,
|
||||||
"packet size too large: %lu > %u",
|
"packet size too large: %ld > %u",
|
||||||
ultmp, DEFDATALEN);
|
ltmp, DEFDATALEN);
|
||||||
}
|
}
|
||||||
datalen = ultmp;
|
datalen = ltmp;
|
||||||
break;
|
break;
|
||||||
case 'T': /* multicast TTL */
|
case 'T': /* multicast TTL */
|
||||||
ultmp = strtoul(optarg, &ep, 0);
|
ltmp = strtol(optarg, &ep, 0);
|
||||||
if (*ep || ep == optarg || ultmp > MAXTTL)
|
if (*ep || ep == optarg || ltmp > MAXTTL || ltmp < 0)
|
||||||
errx(EX_USAGE, "invalid multicast TTL: `%s'",
|
errx(EX_USAGE, "invalid multicast TTL: `%s'",
|
||||||
optarg);
|
optarg);
|
||||||
mttl = ultmp;
|
mttl = ltmp;
|
||||||
options |= F_MTTL;
|
options |= F_MTTL;
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
@ -513,10 +514,10 @@ main(int argc, char *const *argv)
|
|||||||
break;
|
break;
|
||||||
case 'z':
|
case 'z':
|
||||||
options |= F_HDRINCL;
|
options |= F_HDRINCL;
|
||||||
ultmp = strtoul(optarg, &ep, 0);
|
ltmp = strtol(optarg, &ep, 0);
|
||||||
if (*ep || ep == optarg || ultmp > MAXTOS)
|
if (*ep || ep == optarg || ltmp > MAXTOS || ltmp < 0)
|
||||||
errx(EX_USAGE, "invalid TOS: `%s'", optarg);
|
errx(EX_USAGE, "invalid TOS: `%s'", optarg);
|
||||||
tos = ultmp;
|
tos = ltmp;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
usage();
|
usage();
|
||||||
|
Loading…
Reference in New Issue
Block a user