diff options
author | hrs <hrs@FreeBSD.org> | 2012-12-16 23:46:59 +0000 |
---|---|---|
committer | hrs <hrs@FreeBSD.org> | 2012-12-16 23:46:59 +0000 |
commit | 2a6db409ab7daeaadc29117638217ffd0b02c64f (patch) | |
tree | 3ed84ec241353e1227e63715d313736fa34d96f0 /sbin | |
parent | cbf6823f9afcdfa0776c6a47cce2962d97a087ef (diff) | |
download | FreeBSD-src-2a6db409ab7daeaadc29117638217ffd0b02c64f.zip FreeBSD-src-2a6db409ab7daeaadc29117638217ffd0b02c64f.tar.gz |
- 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
Diffstat (limited to 'sbin')
-rw-r--r-- | sbin/route/route.c | 51 |
1 files changed, 35 insertions, 16 deletions
diff --git a/sbin/route/route.c b/sbin/route/route.c index be85184..847f3ee 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); |