aboutsummaryrefslogtreecommitdiff
path: root/sbin/route/route.c
diff options
context:
space:
mode:
authorHiroki Sato <hrs@FreeBSD.org>2012-12-16 23:46:59 +0000
committerHiroki Sato <hrs@FreeBSD.org>2012-12-16 23:46:59 +0000
commit0a16fa86cb5543bf46828b841356c93f0b6cb936 (patch)
tree3ed84ec241353e1227e63715d313736fa34d96f0 /sbin/route/route.c
parent11631ad0d6066d25d39f8f4ff7e72437fdaa666b (diff)
downloadsrc-0a16fa86cb5543bf46828b841356c93f0b6cb936.tar.gz
src-0a16fa86cb5543bf46828b841356c93f0b6cb936.zip
- Fix strtol() error handling.
- Add a range condition of given FIB number and the related error messages. - Fix free() problem. Spotted by: Artyom Mirgorodskiy Discussed with: glebius
Notes
Notes: svn path=/head/; revision=244325
Diffstat (limited to 'sbin/route/route.c')
-rw-r--r--sbin/route/route.c51
1 files changed, 35 insertions, 16 deletions
diff --git a/sbin/route/route.c b/sbin/route/route.c
index be85184f182e..847f3ee37135 100644
--- a/sbin/route/route.c
+++ b/sbin/route/route.c
@@ -260,19 +260,25 @@ static int
fiboptlist_range(const char *arg, struct fibl_head_t *flh)
{
struct fibl *fl;
- char *str, *token, *endptr;
+ char *str0, *str, *token, *endptr;
int fib[2], i, error;
- str = strdup(arg);
+ str0 = str = strdup(arg);
error = 0;
i = 0;
while ((token = strsep(&str, "-")) != NULL) {
switch (i) {
case 0:
case 1:
+ errno = 0;
fib[i] = strtol(token, &endptr, 0);
- if (*endptr != '\0' || (fib[i] == 0 &&
- (errno == EINVAL || errno == ERANGE)))
+ if (errno == 0) {
+ if (*endptr != '\0' ||
+ fib[i] < 0 ||
+ (numfibs != -1 && fib[i] > numfibs - 1))
+ errno = EINVAL;
+ }
+ if (errno)
error = 1;
break;
default:
@@ -296,7 +302,7 @@ fiboptlist_range(const char *arg, struct fibl_head_t *flh)
TAILQ_INSERT_TAIL(flh, fl, fl_next);
}
fiboptlist_range_ret:
- free(str);
+ free(str0);
return (error);
}
@@ -305,7 +311,7 @@ static int
fiboptlist_csv(const char *arg, struct fibl_head_t *flh)
{
struct fibl *fl;
- char *str, *token, *endptr;
+ char *str0, *str, *token, *endptr;
int fib, error;
if (strcmp("all", arg) == 0) {
@@ -319,14 +325,14 @@ fiboptlist_csv(const char *arg, struct fibl_head_t *flh)
else
snprintf(str, ALLSTRLEN - 1, "%d", 0);
} else if (strcmp("default", arg) == 0) {
- str = calloc(1, ALLSTRLEN);
+ str0 = str = calloc(1, ALLSTRLEN);
if (str == NULL) {
error = 1;
goto fiboptlist_csv_ret;
}
snprintf(str, ALLSTRLEN - 1, "%d", defaultfib);
} else
- str = strdup(arg);
+ str0 = str = strdup(arg);
error = 0;
while ((token = strsep(&str, ",")) != NULL) {
@@ -335,9 +341,15 @@ fiboptlist_csv(const char *arg, struct fibl_head_t *flh)
if (error)
goto fiboptlist_csv_ret;
} else {
+ errno = 0;
fib = strtol(token, &endptr, 0);
- if (*endptr != '\0' || (fib == 0 &&
- (errno == EINVAL || errno == ERANGE))) {
+ if (errno == 0) {
+ if (*endptr != '\0' ||
+ fib < 0 ||
+ (numfibs != -1 && fib > numfibs - 1))
+ errno = EINVAL;
+ }
+ if (errno) {
error = 1;
goto fiboptlist_csv_ret;
}
@@ -351,7 +363,7 @@ fiboptlist_csv(const char *arg, struct fibl_head_t *flh)
}
}
fiboptlist_csv_ret:
- free(str);
+ free(str0);
return (error);
}
@@ -396,7 +408,7 @@ flushroutes(int argc, char *argv[])
usage(*argv);
error = fiboptlist_csv(*++argv, &fibl_head);
if (error)
- usage(*argv);
+ errx(EX_USAGE, "invalid fib number: %s", *argv);
break;
default:
usage(*argv);
@@ -815,7 +827,8 @@ newroute(int argc, char **argv)
usage(NULL);
error = fiboptlist_csv(*++argv, &fibl_head);
if (error)
- usage(NULL);
+ errx(EX_USAGE,
+ "invalid fib number: %s", *argv);
break;
case K_IFA:
if (!--argc)
@@ -1383,10 +1396,16 @@ monitor(int argc, char *argv[])
case K_FIB:
if (!--argc)
usage(*argv);
+ errno = 0;
fib = strtol(*++argv, &endptr, 0);
- if (*endptr != '\0' || (fib == 0 &&
- (errno == EINVAL || errno == ERANGE)))
- usage(*argv);
+ if (errno == 0) {
+ if (*endptr != '\0' ||
+ fib < 0 ||
+ (numfibs != -1 && fib > numfibs - 1))
+ errno = EINVAL;
+ }
+ if (errno)
+ errx(EX_USAGE, "invalid fib number: %s", *argv);
break;
default:
usage(*argv);