Use sudo_strtonum() explicitly instead of via a macro.

This commit is contained in:
Todd C. Miller
2019-10-14 10:09:30 -06:00
parent 04a17095be
commit 2512f6efbf
23 changed files with 55 additions and 46 deletions

View File

@@ -379,11 +379,6 @@ int getdomainname(char *, size_t);
# endif
#endif /* __hpux && !__LP64__ */
/* We use our own strtonum() to get translatable error strings. */
__dso_public long long sudo_strtonum(const char *, long long, long long, const char **);
#undef strtonum
#define strtonum(_a, _b, _c, _d) sudo_strtonum((_a), (_b), (_c), (_d))
/*
* Functions "missing" from libc.
* All libc replacements are prefixed with "sudo_" to avoid namespace issues.

View File

@@ -246,6 +246,10 @@ __dso_public const char *sudo_strsplit_v1(const char *str, const char *endstr, c
__dso_public int sudo_strtobool_v1(const char *str);
#define sudo_strtobool(_a) sudo_strtobool_v1((_a))
/* strtonum.c */
/* Not versioned for historical reasons. */
__dso_public long long sudo_strtonum(const char *, long long, long long, const char **);
/* strtoid.c */
__dso_public id_t sudo_strtoid_v1(const char *str, const char *sep, char **endp, const char **errstr);
#define sudo_strtoid(_a, _b, _c, _d) sudo_strtoid_v1((_a), (_b), (_c), (_d))

View File

@@ -1057,11 +1057,13 @@ strtomode.i: $(srcdir)/strtomode.c $(incdir)/compat/stdbool.h \
$(CC) -E -o $@ $(CPPFLAGS) $<
strtomode.plog: strtomode.i
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/strtomode.c --i-file $< --output-file $@
strtonum.lo: $(srcdir)/strtonum.c $(incdir)/sudo_compat.h \
$(incdir)/sudo_gettext.h $(top_builddir)/config.h
strtonum.lo: $(srcdir)/strtonum.c $(incdir)/compat/stdbool.h \
$(incdir)/sudo_compat.h $(incdir)/sudo_gettext.h \
$(incdir)/sudo_util.h $(top_builddir)/config.h
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/strtonum.c
strtonum.i: $(srcdir)/strtonum.c $(incdir)/sudo_compat.h \
$(incdir)/sudo_gettext.h $(top_builddir)/config.h
strtonum.i: $(srcdir)/strtonum.c $(incdir)/compat/stdbool.h \
$(incdir)/sudo_compat.h $(incdir)/sudo_gettext.h \
$(incdir)/sudo_util.h $(top_builddir)/config.h
$(CC) -E -o $@ $(CPPFLAGS) $<
strtonum.plog: strtonum.i
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/strtonum.c --i-file $< --output-file $@

View File

@@ -39,6 +39,7 @@
#endif
#include "sudo_compat.h"
#include "sudo_util.h"
#include "pathnames.h"
#ifndef _POSIX_OPEN_MAX
@@ -116,7 +117,7 @@ sudo_closefrom(int lowfd)
struct dirent *dent;
while ((dent = readdir(dirp)) != NULL) {
const char *errstr;
int fd = strtonum(dent->d_name, lowfd, INT_MAX, &errstr);
int fd = sudo_strtonum(dent->d_name, lowfd, INT_MAX, &errstr);
if (errstr == NULL && fd != dirfd(dirp)) {
# ifdef __APPLE__
/* Avoid potential libdispatch crash when we close its fds. */

View File

@@ -239,7 +239,7 @@ gai_service(const char *servname, int flags, int *type, unsigned short *port)
const char *errstr;
unsigned short value;
value = strtonum(servname, 0, USHRT_MAX, &errstr);
value = sudo_strtonum(servname, 0, USHRT_MAX, &errstr);
if (errstr == NULL) {
*port = value;
} else if (errno == ERANGE) {

View File

@@ -41,6 +41,7 @@
#include "sudo_gettext.h" /* must be included before sudo_compat.h */
#include "sudo_compat.h"
#include "sudo_util.h"
enum strtonum_err {
STN_INITIAL,

View File

@@ -410,7 +410,7 @@ set_var_max_groups(const char *strval, const char *conf_file,
int max_groups;
debug_decl(set_var_max_groups, SUDO_DEBUG_UTIL)
max_groups = strtonum(strval, 1, INT_MAX, NULL);
max_groups = sudo_strtonum(strval, 1, INT_MAX, NULL);
if (max_groups <= 0) {
sudo_warnx(U_("invalid max groups \"%s\" in %s, line %u"), strval,
conf_file, lineno);

View File

@@ -60,11 +60,11 @@ sudo_get_ttysize_v1(int *rowp, int *colp)
/* Fall back on $LINES and $COLUMNS. */
if ((p = getenv("LINES")) == NULL ||
(*rowp = strtonum(p, 1, INT_MAX, NULL)) <= 0) {
(*rowp = sudo_strtonum(p, 1, INT_MAX, NULL)) <= 0) {
*rowp = 24;
}
if ((p = getenv("COLUMNS")) == NULL ||
(*colp = strtonum(p, 1, INT_MAX, NULL)) <= 0) {
(*colp = sudo_strtonum(p, 1, INT_MAX, NULL)) <= 0) {
*colp = 80;
}
}

View File

@@ -78,7 +78,7 @@ get_boottime(struct timespec *ts)
if (strncmp(line, "btime ", 6) == 0) {
if (line[len - 1] == '\n')
line[len - 1] = '\0';
llval = strtonum(line + 6, 1, LLONG_MAX, NULL);
llval = sudo_strtonum(line + 6, 1, LLONG_MAX, NULL);
if (llval > 0) {
ts->tv_sec = (time_t)llval;
ts->tv_nsec = 0;

View File

@@ -416,7 +416,7 @@ cvtsudoers_parse_keyword(const char *conf_file, const char *keyword,
case CONF_UINT:
{
unsigned int uval =
strtonum(value, 0, UINT_MAX, &errstr);
sudo_strtonum(value, 0, UINT_MAX, &errstr);
if (errstr != NULL) {
sudo_warnx(U_("%s: %s: %s: %s"),
conf_file, keyword, value, U_(errstr));

View File

@@ -834,7 +834,7 @@ store_int(const char *str, union sudo_defs_val *sd_un)
if (str == NULL) {
sd_un->ival = 0;
} else {
i = strtonum(str, INT_MIN, INT_MAX, &errstr);
i = sudo_strtonum(str, INT_MIN, INT_MAX, &errstr);
if (errstr != NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"%s: %s", str, errstr);
@@ -855,7 +855,7 @@ store_uint(const char *str, union sudo_defs_val *sd_un)
if (str == NULL) {
sd_un->uival = 0;
} else {
u = strtonum(str, 0, UINT_MAX, &errstr);
u = sudo_strtonum(str, 0, UINT_MAX, &errstr);
if (errstr != NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"%s: %s", str, errstr);

View File

@@ -206,7 +206,7 @@ io_set_max_sessid(const char *maxval)
unsigned int value;
debug_decl(io_set_max_sessid, SUDOERS_DEBUG_UTIL)
value = strtonum(maxval, 0, SESSID_MAX, &errstr);
value = sudo_strtonum(maxval, 0, SESSID_MAX, &errstr);
if (errstr != NULL) {
if (errno != ERANGE) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
@@ -611,7 +611,8 @@ iolog_deserialize_info(struct iolog_details *details, char * const user_info[],
switch (**cur) {
case 'c':
if (strncmp(*cur, "cols=", sizeof("cols=") - 1) == 0) {
int n = strtonum(*cur + sizeof("cols=") - 1, 1, INT_MAX, NULL);
int n = sudo_strtonum(*cur + sizeof("cols=") - 1, 1, INT_MAX,
NULL);
if (n > 0)
details->cols = n;
continue;
@@ -623,7 +624,8 @@ iolog_deserialize_info(struct iolog_details *details, char * const user_info[],
break;
case 'l':
if (strncmp(*cur, "lines=", sizeof("lines=") - 1) == 0) {
int n = strtonum(*cur + sizeof("lines=") - 1, 1, INT_MAX, NULL);
int n = sudo_strtonum(*cur + sizeof("lines=") - 1, 1, INT_MAX,
NULL);
if (n > 0)
details->lines = n;
continue;

View File

@@ -109,7 +109,7 @@ parse_logfile(const char *logfile)
goto bad;
}
*ep = '\0';
li->tstamp = strtonum(cp, 0, TIME_T_MAX, &errstr);
li->tstamp = sudo_strtonum(cp, 0, TIME_T_MAX, &errstr);
if (errstr != NULL) {
sudo_warn(U_("%s: time stamp %s: %s"), logfile, cp, errstr);
goto bad;
@@ -155,18 +155,19 @@ parse_logfile(const char *logfile)
if ((li->tty = strndup(cp, (size_t)(ep - cp))) == NULL)
sudo_fatalx(U_("%s: %s"), __func__, U_("unable to allocate memory"));
cp = ep + 1;
/* need to NULL out separator to use strtonum() */
/* need to NULL out separator to use sudo_strtonum() */
/* XXX - use sudo_strtonumx */
if ((ep = strchr(cp, ':')) != NULL) {
*ep = '\0';
}
li->rows = strtonum(cp, 1, INT_MAX, &errstr);
li->rows = sudo_strtonum(cp, 1, INT_MAX, &errstr);
if (errstr != NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"%s: tty rows %s: %s", logfile, cp, errstr);
}
if (ep != NULL) {
cp = ep + 1;
li->cols = strtonum(cp, 1, INT_MAX, &errstr);
li->cols = sudo_strtonum(cp, 1, INT_MAX, &errstr);
if (errstr != NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"%s: tty cols %s: %s", logfile, cp, errstr);
@@ -240,7 +241,7 @@ parse_delay(const char *cp, struct timespec *delay, const char *decimal_point)
}
memcpy(numbuf, cp, len);
numbuf[len] = '\0';
delay->tv_sec = strtonum(numbuf, 0, TIME_T_MAX, &errstr);
delay->tv_sec = sudo_strtonum(numbuf, 0, TIME_T_MAX, &errstr);
if (errstr != NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"%s: number of seconds is %s", numbuf, errstr);
@@ -266,7 +267,7 @@ parse_delay(const char *cp, struct timespec *delay, const char *decimal_point)
}
memcpy(numbuf, cp, len);
numbuf[len] = '\0';
llval = strtonum(numbuf, 0, LLONG_MAX, &errstr);
llval = sudo_strtonum(numbuf, 0, LLONG_MAX, &errstr);
if (errstr != NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"%s: number of nanoseconds is %s", numbuf, errstr);

View File

@@ -430,7 +430,8 @@ sudo_ldap_parse_keyword(const char *keyword, const char *value,
*(int *)(cur->valp) = sudo_strtobool(value) == true;
break;
case CONF_INT:
*(int *)(cur->valp) = strtonum(value, INT_MIN, INT_MAX, &errstr);
*(int *)(cur->valp) = sudo_strtonum(value, INT_MIN, INT_MAX,
&errstr);
if (errstr != NULL) {
sudo_warnx(U_("%s: %s: %s: %s"),
path_ldap_conf, keyword, value, U_(errstr));

View File

@@ -132,7 +132,7 @@ addr_matches_if_netmask(const char *n, const char *m)
debug_return_bool(false);
}
} else {
i = strtonum(m, 1, 32, &errstr);
i = sudo_strtonum(m, 1, 32, &errstr);
if (errstr != NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"IPv4 netmask %s: %s", m, errstr);
@@ -145,7 +145,7 @@ addr_matches_if_netmask(const char *n, const char *m)
#ifdef HAVE_STRUCT_IN6_ADDR
else {
if (inet_pton(AF_INET6, m, &mask.ip6) != 1) {
j = strtonum(m, 1, 128, &errstr);
j = sudo_strtonum(m, 1, 128, &errstr);
if (errstr != NULL) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"IPv6 netmask %s: %s", m, errstr);

View File

@@ -173,7 +173,7 @@ sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group)
if (MATCHES(*cur, "closefrom=")) {
errno = 0;
p = *cur + sizeof("closefrom=") - 1;
user_closefrom = strtonum(p, 4, INT_MAX, &errstr);
user_closefrom = sudo_strtonum(p, 4, INT_MAX, &errstr);
if (user_closefrom == 0) {
sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
goto bad;
@@ -300,7 +300,7 @@ sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group)
if (MATCHES(*cur, "max_groups=")) {
errno = 0;
p = *cur + sizeof("max_groups=") - 1;
sudo_user.max_groups = strtonum(p, 1, INT_MAX, &errstr);
sudo_user.max_groups = sudo_strtonum(p, 1, INT_MAX, &errstr);
if (sudo_user.max_groups == 0) {
sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
goto bad;
@@ -397,7 +397,7 @@ sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group)
if (MATCHES(*cur, "lines=")) {
errno = 0;
p = *cur + sizeof("lines=") - 1;
sudo_user.lines = strtonum(p, 1, INT_MAX, &errstr);
sudo_user.lines = sudo_strtonum(p, 1, INT_MAX, &errstr);
if (sudo_user.lines == 0) {
sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
goto bad;
@@ -407,7 +407,7 @@ sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group)
if (MATCHES(*cur, "cols=")) {
errno = 0;
p = *cur + sizeof("cols=") - 1;
sudo_user.cols = strtonum(p, 1, INT_MAX, &errstr);
sudo_user.cols = sudo_strtonum(p, 1, INT_MAX, &errstr);
if (sudo_user.cols == 0) {
sudo_warnx(U_("%s: %s"), *cur, U_(errstr));
goto bad;

View File

@@ -89,10 +89,10 @@ main(int argc, char *argv[])
dash = strchr(cp, '-');
if (dash != NULL) {
*dash = '\0';
len = strtonum(cp, 1, INT_MAX, NULL);
maxlen = strtonum(dash + 1, 1, INT_MAX, NULL);
len = sudo_strtonum(cp, 1, INT_MAX, NULL);
maxlen = sudo_strtonum(dash + 1, 1, INT_MAX, NULL);
} else {
len = maxlen = strtonum(cp, 1, INT_MAX, NULL);
len = maxlen = sudo_strtonum(cp, 1, INT_MAX, NULL);
}
if (len == 0 || maxlen == 0)
sudo_fatalx("%s: invalid length on line %d\n", argv[1], lineno);

View File

@@ -60,7 +60,7 @@ check_addr(char *input)
cp = input + len;
while (isspace((unsigned char)*cp))
cp++;
expected = strtonum(cp, 0, 1, &errstr);
expected = sudo_strtonum(cp, 0, 1, &errstr);
if (errstr != NULL)
sudo_fatalx("expecting 0 or 1, got %s", cp);
input[len] = '\0';

View File

@@ -52,7 +52,7 @@ get_now(struct timespec *now)
buf[strcspn(buf, "\n")] = '\0';
/* Boot time is in seconds since the epoch. */
seconds = strtonum(buf + 6, 0, TIME_T_MAX, &errstr);
seconds = sudo_strtonum(buf + 6, 0, TIME_T_MAX, &errstr);
if (errstr != NULL)
return -1;

View File

@@ -325,7 +325,7 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv,
break;
case 'C':
assert(optarg != NULL);
if (strtonum(optarg, 3, INT_MAX, NULL) == 0) {
if (sudo_strtonum(optarg, 3, INT_MAX, NULL) == 0) {
sudo_warnx(U_("the argument to -C must be a number greater than or equal to 3"));
usage(1);
}

View File

@@ -103,7 +103,7 @@ main(int argc, char *argv[], char *envp[])
const char *errstr;
cp = argv[1] + 9;
fd = strtonum(cp, 0, INT_MAX, &errstr);
fd = sudo_strtonum(cp, 0, INT_MAX, &errstr);
if (errstr != NULL)
sudo_fatalx(U_("invalid file descriptor number: %s"), cp);
argv++;

View File

@@ -674,7 +674,7 @@ command_info_to_details(char * const info[], struct command_details *details)
SET_STRING("cwd=", cwd)
if (strncmp("closefrom=", info[i], sizeof("closefrom=") - 1) == 0) {
cp = info[i] + sizeof("closefrom=") - 1;
details->closefrom = strtonum(cp, 0, INT_MAX, &errstr);
details->closefrom = sudo_strtonum(cp, 0, INT_MAX, &errstr);
if (errstr != NULL)
sudo_fatalx(U_("%s: %s"), info[i], U_(errstr));
break;
@@ -684,7 +684,7 @@ command_info_to_details(char * const info[], struct command_details *details)
SET_FLAG("exec_background=", CD_EXEC_BG)
if (strncmp("execfd=", info[i], sizeof("execfd=") - 1) == 0) {
cp = info[i] + sizeof("execfd=") - 1;
details->execfd = strtonum(cp, 0, INT_MAX, &errstr);
details->execfd = sudo_strtonum(cp, 0, INT_MAX, &errstr);
if (errstr != NULL)
sudo_fatalx(U_("%s: %s"), info[i], U_(errstr));
#ifdef HAVE_FEXECVE
@@ -704,7 +704,8 @@ command_info_to_details(char * const info[], struct command_details *details)
case 'n':
if (strncmp("nice=", info[i], sizeof("nice=") - 1) == 0) {
cp = info[i] + sizeof("nice=") - 1;
details->priority = strtonum(cp, INT_MIN, INT_MAX, &errstr);
details->priority = sudo_strtonum(cp, INT_MIN, INT_MAX,
&errstr);
if (errstr != NULL)
sudo_fatalx(U_("%s: %s"), info[i], U_(errstr));
SET(details->flags, CD_SET_PRIORITY);
@@ -799,7 +800,7 @@ command_info_to_details(char * const info[], struct command_details *details)
case 't':
if (strncmp("timeout=", info[i], sizeof("timeout=") - 1) == 0) {
cp = info[i] + sizeof("timeout=") - 1;
details->timeout = strtonum(cp, 0, INT_MAX, &errstr);
details->timeout = sudo_strtonum(cp, 0, INT_MAX, &errstr);
if (errstr != NULL)
sudo_fatalx(U_("%s: %s"), info[i], U_(errstr));
SET(details->flags, CD_SET_TIMEOUT);

View File

@@ -235,7 +235,8 @@ get_process_ttyname(char *name, size_t namelen)
if (*ep == ' ') {
*ep = '\0';
if (++field == 7) {
int tty_nr = strtonum(cp, INT_MIN, INT_MAX, &errstr);
int tty_nr = sudo_strtonum(cp, INT_MIN, INT_MAX,
&errstr);
if (errstr) {
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
"%s: tty device %s: %s", path, cp, errstr);