Use strtonum() instead of atoi(), strtol() or strtoul() where possible.
This commit is contained in:
@@ -182,16 +182,14 @@ set_var_group_source(const char *entry, const char *conf_file)
|
|||||||
static void
|
static void
|
||||||
set_var_max_groups(const char *entry, const char *conf_file)
|
set_var_max_groups(const char *entry, const char *conf_file)
|
||||||
{
|
{
|
||||||
long lval;
|
int max_groups;
|
||||||
char *ep;
|
|
||||||
|
|
||||||
lval = strtol(entry, &ep, 10);
|
max_groups = strtonum(entry, 1, INT_MAX, NULL);
|
||||||
if (*entry == '\0' || *ep != '\0' || lval <= 0 || lval > INT_MAX ||
|
if (max_groups > 0) {
|
||||||
(errno == ERANGE && lval == LONG_MAX)) {
|
sudo_conf_data.max_groups = max_groups;
|
||||||
warningx(U_("invalid max groups `%s' in %s, line %d"), entry,
|
|
||||||
conf_file, conf_lineno);
|
|
||||||
} else {
|
} else {
|
||||||
sudo_conf_data.max_groups = (int)lval;
|
warningx(U_("invalid max groups `%s' in %s, line %d"), entry,
|
||||||
|
conf_file, conf_lineno);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -77,10 +77,14 @@ get_ttysize(int *rowp, int *colp)
|
|||||||
char *p;
|
char *p;
|
||||||
|
|
||||||
/* Fall back on $LINES and $COLUMNS. */
|
/* Fall back on $LINES and $COLUMNS. */
|
||||||
if ((p = getenv("LINES")) == NULL || (*rowp = atoi(p)) <= 0)
|
if ((p = getenv("LINES")) == NULL ||
|
||||||
|
(*rowp = strtonum(p, 1, INT_MAX, NULL)) <= 0) {
|
||||||
*rowp = 24;
|
*rowp = 24;
|
||||||
if ((p = getenv("COLUMNS")) == NULL || (*colp = atoi(p)) <= 0)
|
}
|
||||||
|
if ((p = getenv("COLUMNS")) == NULL ||
|
||||||
|
(*colp = strtonum(p, 1, INT_MAX, NULL)) <= 0) {
|
||||||
*colp = 80;
|
*colp = 80;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_return;
|
debug_return;
|
||||||
|
@@ -222,7 +222,8 @@ strlcpy.lo: $(srcdir)/strlcpy.c $(incdir)/missing.h $(top_builddir)/config.h
|
|||||||
strsignal.lo: $(srcdir)/strsignal.c $(incdir)/gettext.h $(incdir)/missing.h \
|
strsignal.lo: $(srcdir)/strsignal.c $(incdir)/gettext.h $(incdir)/missing.h \
|
||||||
$(top_builddir)/config.h
|
$(top_builddir)/config.h
|
||||||
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/strsignal.c
|
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/strsignal.c
|
||||||
strtonum.lo: $(srcdir)/strtonum.c $(incdir)/missing.h $(top_builddir)/config.h
|
strtonum.lo: $(srcdir)/strtonum.c $(incdir)/gettext.h $(incdir)/missing.h \
|
||||||
|
$(top_builddir)/config.h
|
||||||
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/strtonum.c
|
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/strtonum.c
|
||||||
utimes.lo: $(srcdir)/utimes.c $(incdir)/missing.h $(top_builddir)/config.h \
|
utimes.lo: $(srcdir)/utimes.c $(incdir)/missing.h $(top_builddir)/config.h \
|
||||||
$(top_srcdir)/compat/utime.h
|
$(top_srcdir)/compat/utime.h
|
||||||
|
@@ -86,7 +86,7 @@ closefrom_fallback(int lowfd)
|
|||||||
for (fd = lowfd; fd < maxfd; fd++) {
|
for (fd = lowfd; fd < maxfd; fd++) {
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
/* Avoid potential crash with libdispatch when we close its fds. */
|
/* Avoid potential crash with libdispatch when we close its fds. */
|
||||||
(void) fcntl(fd, F_SETFD, FD_CLOEXEC);
|
(void) fcntl((int) fd, F_SETFD, FD_CLOEXEC);
|
||||||
#else
|
#else
|
||||||
(void) close((int) fd);
|
(void) close((int) fd);
|
||||||
#endif
|
#endif
|
||||||
@@ -123,17 +123,17 @@ void
|
|||||||
closefrom(int lowfd)
|
closefrom(int lowfd)
|
||||||
{
|
{
|
||||||
struct dirent *dent;
|
struct dirent *dent;
|
||||||
|
const char *errstr;
|
||||||
DIR *dirp;
|
DIR *dirp;
|
||||||
char *endp;
|
int fd;
|
||||||
long fd;
|
|
||||||
|
|
||||||
/* Use /proc/self/fd directory if it exists. */
|
/* Use /proc/self/fd directory if it exists. */
|
||||||
if ((dirp = opendir("/proc/self/fd")) != NULL) {
|
if ((dirp = opendir("/proc/self/fd")) != NULL) {
|
||||||
while ((dent = readdir(dirp)) != NULL) {
|
while ((dent = readdir(dirp)) != NULL) {
|
||||||
fd = strtol(dent->d_name, &endp, 10);
|
fd = strtonum(dent->d_name, lowfd, INT_MAX, &errstr);
|
||||||
if (dent->d_name != endp && *endp == '\0' &&
|
if (errstr == NULL && fd != dirfd(dirp)) {
|
||||||
fd >= 0 && fd < INT_MAX && fd >= lowfd && fd != dirfd(dirp))
|
(void) close(fd);
|
||||||
(void) close((int) fd);
|
}
|
||||||
}
|
}
|
||||||
(void) closedir(dirp);
|
(void) closedir(dirp);
|
||||||
} else
|
} else
|
||||||
|
@@ -187,29 +187,6 @@ freeaddrinfo(struct addrinfo *ai)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Convert a numeric service string to a number with error checking, returning
|
|
||||||
* true if the number was parsed correctly and false otherwise. Stores the
|
|
||||||
* converted number in the second argument. Equivalent to calling strtol, but
|
|
||||||
* with the base always fixed at 10, with checking of errno, ensuring that all
|
|
||||||
* of the string is consumed, and checking that the resulting number is
|
|
||||||
* positive.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
convert_service(const char *string, long *result)
|
|
||||||
{
|
|
||||||
char *end;
|
|
||||||
|
|
||||||
if (*string == '\0')
|
|
||||||
return 0;
|
|
||||||
errno = 0;
|
|
||||||
*result = strtol(string, &end, 10);
|
|
||||||
if (errno != 0 || *end != '\0' || *result < 0)
|
|
||||||
return 0;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate a new addrinfo struct, setting some defaults given that this
|
* Allocate a new addrinfo struct, setting some defaults given that this
|
||||||
* implementation is IPv4 only. Also allocates an attached sockaddr_in and
|
* implementation is IPv4 only. Also allocates an attached sockaddr_in and
|
||||||
@@ -268,12 +245,14 @@ gai_service(const char *servname, int flags, int *type, unsigned short *port)
|
|||||||
{
|
{
|
||||||
struct servent *servent;
|
struct servent *servent;
|
||||||
const char *protocol;
|
const char *protocol;
|
||||||
long value;
|
const char *errstr;
|
||||||
|
unsigned short value;
|
||||||
|
|
||||||
if (convert_service(servname, &value)) {
|
value = strtonum(servname, 0, USHRT_MAX, &errstr);
|
||||||
if (value > (1L << 16) - 1)
|
if (errstr == NULL) {
|
||||||
return EAI_SERVICE;
|
|
||||||
*port = value;
|
*port = value;
|
||||||
|
} else if (errno == ERANGE) {
|
||||||
|
return EAI_SERVICE;
|
||||||
} else {
|
} else {
|
||||||
if (flags & AI_NUMERICSERV)
|
if (flags & AI_NUMERICSERV)
|
||||||
return EAI_NONAME;
|
return EAI_NONAME;
|
||||||
|
@@ -28,6 +28,9 @@
|
|||||||
|
|
||||||
#include "missing.h"
|
#include "missing.h"
|
||||||
|
|
||||||
|
#define DEFAULT_TEXT_DOMAIN "sudo"
|
||||||
|
#include "gettext.h"
|
||||||
|
|
||||||
enum strtonum_err {
|
enum strtonum_err {
|
||||||
STN_VALID,
|
STN_VALID,
|
||||||
STN_INVALID,
|
STN_INVALID,
|
||||||
@@ -133,19 +136,19 @@ done:
|
|||||||
result = 0;
|
result = 0;
|
||||||
errno = EINVAL;
|
errno = EINVAL;
|
||||||
if (errstrp != NULL)
|
if (errstrp != NULL)
|
||||||
*errstrp = "invalid";
|
*errstrp = N_("invalid");
|
||||||
break;
|
break;
|
||||||
case STN_TOOSMALL:
|
case STN_TOOSMALL:
|
||||||
result = 0;
|
result = 0;
|
||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
if (errstrp != NULL)
|
if (errstrp != NULL)
|
||||||
*errstrp = "too small";
|
*errstrp = N_("too small");
|
||||||
break;
|
break;
|
||||||
case STN_TOOBIG:
|
case STN_TOOBIG:
|
||||||
result = 0;
|
result = 0;
|
||||||
errno = ERANGE;
|
errno = ERANGE;
|
||||||
if (errstrp != NULL)
|
if (errstrp != NULL)
|
||||||
*errstrp = "too large";
|
*errstrp = N_("too large");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
2
configure
vendored
2
configure
vendored
@@ -16297,7 +16297,7 @@ $as_echo "#define HAVE_LONG_LONG_INT 1" >>confdefs.h
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if test X"$ac_cv_type_long_long_int" != X"yes"; then
|
if test X"$ac_cv_type_long_long_int" != X"yes"; then
|
||||||
as_fn_error $? "\"C compiler does not appear have required long long support\"" "$LINENO" 5
|
as_fn_error $? "\"C compiler does not appear to support the long long int type\"" "$LINENO" 5
|
||||||
fi
|
fi
|
||||||
# The cast to long int works around a bug in the HP C Compiler
|
# The cast to long int works around a bug in the HP C Compiler
|
||||||
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
|
# version HP92453-01 B.11.11.23709.GP, which incorrectly rejects
|
||||||
|
@@ -2196,7 +2196,7 @@ AC_CHECK_TYPES([struct in6_addr], [], [], [#include <sys/types.h>
|
|||||||
#include <netinet/in.h>])
|
#include <netinet/in.h>])
|
||||||
AC_TYPE_LONG_LONG_INT
|
AC_TYPE_LONG_LONG_INT
|
||||||
if test X"$ac_cv_type_long_long_int" != X"yes"; then
|
if test X"$ac_cv_type_long_long_int" != X"yes"; then
|
||||||
AC_MSG_ERROR(["C compiler does not appear have required long long support"])
|
AC_MSG_ERROR(["C compiler does not appear to support the long long int type"])
|
||||||
fi
|
fi
|
||||||
AC_CHECK_SIZEOF([long int])
|
AC_CHECK_SIZEOF([long int])
|
||||||
AC_CHECK_TYPE(id_t, unsigned int)
|
AC_CHECK_TYPE(id_t, unsigned int)
|
||||||
|
@@ -124,10 +124,38 @@
|
|||||||
# define OPEN_MAX 256
|
# define OPEN_MAX 256
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef USHRT_MAX
|
||||||
|
# define USHRT_MAX 0xffff
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef INT_MAX
|
#ifndef INT_MAX
|
||||||
# define INT_MAX 0x7fffffff
|
# define INT_MAX 0x7fffffff
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifndef INT_MIN
|
||||||
|
# define INT_MIN (-0x7fffffff-1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef UINT_MAX
|
||||||
|
# define UINT_MAX 0xffffffffU
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LLONG_MAX
|
||||||
|
# if defined(QUAD_MAX)
|
||||||
|
# define LLONG_MAX QUAD_MAX
|
||||||
|
# else
|
||||||
|
# define LLONG_MAX 0x7fffffffffffffffLL
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef LLONG_MIN
|
||||||
|
# if defined(QUAD_MIN)
|
||||||
|
# define LLONG_MIN QUAD_MIN
|
||||||
|
# else
|
||||||
|
# define LLONG_MIN (-0x7fffffffffffffffLL-1)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef PATH_MAX
|
#ifndef PATH_MAX
|
||||||
# ifdef _POSIX_PATH_MAX
|
# ifdef _POSIX_PATH_MAX
|
||||||
# define PATH_MAX _POSIX_PATH_MAX
|
# define PATH_MAX _POSIX_PATH_MAX
|
||||||
|
@@ -74,21 +74,12 @@ get_boottime(struct timeval *tv)
|
|||||||
if (fp != NULL) {
|
if (fp != NULL) {
|
||||||
while ((len = getline(&line, &linesize, fp)) != -1) {
|
while ((len = getline(&line, &linesize, fp)) != -1) {
|
||||||
if (strncmp(line, "btime ", 6) == 0) {
|
if (strncmp(line, "btime ", 6) == 0) {
|
||||||
#ifdef HAVE_STRTOLL
|
long long llval = strtonum(line + 6, 1, LLONG_MAX, NULL);
|
||||||
long long llval = strtoll(line + 6, &ep, 10);
|
if (llval > 0) {
|
||||||
if (line[6] != '\0' && *ep == '\0' && (time_t)llval == llval) {
|
|
||||||
tv->tv_sec = (time_t)llval;
|
tv->tv_sec = (time_t)llval;
|
||||||
tv->tv_usec = 0;
|
tv->tv_usec = 0;
|
||||||
debug_return_bool(1);
|
debug_return_bool(1);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
long lval = strtol(line + 6, &ep, 10);
|
|
||||||
if (line[6] != '\0' && *ep == '\0' && (time_t)lval == lval) {
|
|
||||||
tv->tv_sec = (time_t)llval;
|
|
||||||
tv->tv_usec = 0;
|
|
||||||
debug_return_bool(1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
|
@@ -600,18 +600,20 @@ check_defaults(int what, bool quiet)
|
|||||||
static bool
|
static bool
|
||||||
store_int(char *val, struct sudo_defs_types *def, int op)
|
store_int(char *val, struct sudo_defs_types *def, int op)
|
||||||
{
|
{
|
||||||
char *endp;
|
const char *errstr;
|
||||||
long l;
|
int i;
|
||||||
debug_decl(store_int, SUDO_DEBUG_DEFAULTS)
|
debug_decl(store_int, SUDO_DEBUG_DEFAULTS)
|
||||||
|
|
||||||
if (op == false) {
|
if (op == false) {
|
||||||
def->sd_un.ival = 0;
|
def->sd_un.ival = 0;
|
||||||
} else {
|
} else {
|
||||||
l = strtol(val, &endp, 10);
|
i = strtonum(val, INT_MIN, INT_MAX, &errstr);
|
||||||
if (*endp != '\0')
|
if (errstr != NULL) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"%s is %s", val, errstr);
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
/* XXX - should check against INT_MAX */
|
}
|
||||||
def->sd_un.ival = (int)l;
|
def->sd_un.ival = i;
|
||||||
}
|
}
|
||||||
if (def->callback)
|
if (def->callback)
|
||||||
debug_return_bool(def->callback(val));
|
debug_return_bool(def->callback(val));
|
||||||
@@ -621,18 +623,21 @@ store_int(char *val, struct sudo_defs_types *def, int op)
|
|||||||
static bool
|
static bool
|
||||||
store_uint(char *val, struct sudo_defs_types *def, int op)
|
store_uint(char *val, struct sudo_defs_types *def, int op)
|
||||||
{
|
{
|
||||||
char *endp;
|
const char *errstr;
|
||||||
long l;
|
unsigned int u;
|
||||||
debug_decl(store_uint, SUDO_DEBUG_DEFAULTS)
|
debug_decl(store_uint, SUDO_DEBUG_DEFAULTS)
|
||||||
|
|
||||||
if (op == false) {
|
if (op == false) {
|
||||||
def->sd_un.ival = 0;
|
def->sd_un.ival = 0;
|
||||||
} else {
|
} else {
|
||||||
l = strtol(val, &endp, 10);
|
u = strtonum(val, 0, UINT_MAX, &errstr);
|
||||||
if (*endp != '\0' || l < 0)
|
if (errstr != NULL) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"%s is %s", val, errstr);
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
/* XXX - should check against INT_MAX */
|
}
|
||||||
def->sd_un.ival = (unsigned int)l;
|
/* XXX - should have uival */
|
||||||
|
def->sd_un.ival = u;
|
||||||
}
|
}
|
||||||
if (def->callback)
|
if (def->callback)
|
||||||
debug_return_bool(def->callback(val));
|
debug_return_bool(def->callback(val));
|
||||||
@@ -814,7 +819,7 @@ store_mode(char *val, struct sudo_defs_types *def, int op)
|
|||||||
def->sd_un.mode = (mode_t)0777;
|
def->sd_un.mode = (mode_t)0777;
|
||||||
} else {
|
} else {
|
||||||
l = strtol(val, &endp, 8);
|
l = strtol(val, &endp, 8);
|
||||||
if (*endp != '\0' || l < 0 || l > 0777)
|
if (endp == val || *endp != '\0' || l < 0 || l > 0777)
|
||||||
debug_return_bool(false);
|
debug_return_bool(false);
|
||||||
def->sd_un.mode = (mode_t)l;
|
def->sd_un.mode = (mode_t)l;
|
||||||
}
|
}
|
||||||
|
@@ -136,17 +136,22 @@ io_mkdirs(char *path, mode_t mode, bool is_temp)
|
|||||||
int
|
int
|
||||||
io_set_max_sessid(const char *maxval)
|
io_set_max_sessid(const char *maxval)
|
||||||
{
|
{
|
||||||
unsigned long ulval;
|
const char *errstr;
|
||||||
char *ep;
|
unsigned int value;
|
||||||
|
debug_decl(io_set_max_sessid, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
errno = 0;
|
value = strtonum(maxval, 0, SESSID_MAX, &errstr);
|
||||||
ulval = strtoul(maxval, &ep, 0);
|
if (errstr != NULL) {
|
||||||
if (*maxval != '\0' && *ep == '\0' &&
|
if (errno != ERANGE) {
|
||||||
(errno != ERANGE || ulval != ULONG_MAX)) {
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
sessid_max = MIN((unsigned int)ulval, SESSID_MAX);
|
"bad maxseq: %s is %s", maxval, errstr);
|
||||||
return true;
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
|
/* Out of range, clamp to SESSID_MAX as documented. */
|
||||||
|
value = SESSID_MAX;
|
||||||
}
|
}
|
||||||
return false;
|
sessid_max = value;
|
||||||
|
debug_return_bool(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -202,7 +207,7 @@ io_nextid(char *iolog_dir, char *iolog_dir_fallback, char sessid[7])
|
|||||||
nread = read(fd2, buf, sizeof(buf));
|
nread = read(fd2, buf, sizeof(buf));
|
||||||
if (nread > 0) {
|
if (nread > 0) {
|
||||||
id = strtoul(buf, &ep, 36);
|
id = strtoul(buf, &ep, 36);
|
||||||
if (buf == ep || id >= sessid_max)
|
if (ep == buf || *ep != '\0' || id >= sessid_max)
|
||||||
id = 0;
|
id = 0;
|
||||||
}
|
}
|
||||||
close(fd2);
|
close(fd2);
|
||||||
@@ -217,7 +222,7 @@ io_nextid(char *iolog_dir, char *iolog_dir_fallback, char sessid[7])
|
|||||||
if (nread == -1)
|
if (nread == -1)
|
||||||
log_fatal(USE_ERRNO, N_("unable to read %s"), pathbuf);
|
log_fatal(USE_ERRNO, N_("unable to read %s"), pathbuf);
|
||||||
id = strtoul(buf, &ep, 36);
|
id = strtoul(buf, &ep, 36);
|
||||||
if (buf == ep || id >= sessid_max)
|
if (ep == buf || *ep != '\0' || id >= sessid_max)
|
||||||
id = 0;
|
id = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -237,7 +242,7 @@ io_nextid(char *iolog_dir, char *iolog_dir_fallback, char sessid[7])
|
|||||||
memcpy(sessid, buf, 6);
|
memcpy(sessid, buf, 6);
|
||||||
sessid[6] = '\0';
|
sessid[6] = '\0';
|
||||||
|
|
||||||
/* Rewind and overwrite old seq file. */
|
/* Rewind and overwrite old seq file, including the NUL byte. */
|
||||||
if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1 || write(fd, buf, 7) != 7)
|
if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1 || write(fd, buf, 7) != 7)
|
||||||
log_fatal(USE_ERRNO, N_("unable to write to %s"), pathbuf);
|
log_fatal(USE_ERRNO, N_("unable to write to %s"), pathbuf);
|
||||||
close(fd);
|
close(fd);
|
||||||
@@ -332,7 +337,9 @@ iolog_deserialize_info(struct iolog_details *details, char * const user_info[],
|
|||||||
switch (**cur) {
|
switch (**cur) {
|
||||||
case 'c':
|
case 'c':
|
||||||
if (strncmp(*cur, "cols=", sizeof("cols=") - 1) == 0) {
|
if (strncmp(*cur, "cols=", sizeof("cols=") - 1) == 0) {
|
||||||
details->cols = atoi(*cur + sizeof("cols=") - 1);
|
int n = strtonum(*cur + sizeof("cols=") - 1, 1, INT_MAX, NULL);
|
||||||
|
if (n > 0)
|
||||||
|
details->cols = n;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (strncmp(*cur, "cwd=", sizeof("cwd=") - 1) == 0) {
|
if (strncmp(*cur, "cwd=", sizeof("cwd=") - 1) == 0) {
|
||||||
@@ -342,7 +349,9 @@ iolog_deserialize_info(struct iolog_details *details, char * const user_info[],
|
|||||||
break;
|
break;
|
||||||
case 'l':
|
case 'l':
|
||||||
if (strncmp(*cur, "lines=", sizeof("lines=") - 1) == 0) {
|
if (strncmp(*cur, "lines=", sizeof("lines=") - 1) == 0) {
|
||||||
details->lines = atoi(*cur + sizeof("lines=") - 1);
|
int n = strtonum(*cur + sizeof("lines=") - 1, 1, INT_MAX, NULL);
|
||||||
|
if (n > 0)
|
||||||
|
details->lines = n;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@@ -1398,6 +1398,7 @@ sudo_ldap_parse_keyword(const char *keyword, const char *value,
|
|||||||
struct ldap_config_table *table)
|
struct ldap_config_table *table)
|
||||||
{
|
{
|
||||||
struct ldap_config_table *cur;
|
struct ldap_config_table *cur;
|
||||||
|
const char *errstr;
|
||||||
debug_decl(sudo_ldap_parse_keyword, SUDO_DEBUG_LDAP)
|
debug_decl(sudo_ldap_parse_keyword, SUDO_DEBUG_LDAP)
|
||||||
|
|
||||||
/* Look up keyword in config tables */
|
/* Look up keyword in config tables */
|
||||||
@@ -1418,7 +1419,11 @@ sudo_ldap_parse_keyword(const char *keyword, const char *value,
|
|||||||
*(int *)(cur->valp) = atobool(value) == true;
|
*(int *)(cur->valp) = atobool(value) == true;
|
||||||
break;
|
break;
|
||||||
case CONF_INT:
|
case CONF_INT:
|
||||||
*(int *)(cur->valp) = atoi(value);
|
*(int *)(cur->valp) = strtonum(value, INT_MIN, INT_MAX, &errstr);
|
||||||
|
if (errstr != NULL) {
|
||||||
|
warningx(U_("%s: %s: value %s out of range)"),
|
||||||
|
path_ldap_conf, keyword, value);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case CONF_STR:
|
case CONF_STR:
|
||||||
efree(*(char **)(cur->valp));
|
efree(*(char **)(cur->valp));
|
||||||
|
@@ -109,6 +109,7 @@ addr_matches_if_netmask(const char *n, const char *m)
|
|||||||
unsigned int j;
|
unsigned int j;
|
||||||
#endif
|
#endif
|
||||||
unsigned int family;
|
unsigned int family;
|
||||||
|
const char *errstr;
|
||||||
debug_decl(addr_matches_if, SUDO_DEBUG_MATCH)
|
debug_decl(addr_matches_if, SUDO_DEBUG_MATCH)
|
||||||
|
|
||||||
#ifdef HAVE_STRUCT_IN6_ADDR
|
#ifdef HAVE_STRUCT_IN6_ADDR
|
||||||
@@ -125,7 +126,12 @@ addr_matches_if_netmask(const char *n, const char *m)
|
|||||||
if (strchr(m, '.')) {
|
if (strchr(m, '.')) {
|
||||||
mask.ip4.s_addr = inet_addr(m);
|
mask.ip4.s_addr = inet_addr(m);
|
||||||
} else {
|
} else {
|
||||||
i = atoi(m);
|
i = strtonum(m, 0, 32, &errstr);
|
||||||
|
if (errstr != NULL) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"IPv4 netmask %s: %s", m, errstr);
|
||||||
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
mask.ip4.s_addr = 0;
|
mask.ip4.s_addr = 0;
|
||||||
else if (i == 32)
|
else if (i == 32)
|
||||||
@@ -139,7 +145,12 @@ addr_matches_if_netmask(const char *n, const char *m)
|
|||||||
#ifdef HAVE_STRUCT_IN6_ADDR
|
#ifdef HAVE_STRUCT_IN6_ADDR
|
||||||
else {
|
else {
|
||||||
if (inet_pton(AF_INET6, m, &mask.ip6) <= 0) {
|
if (inet_pton(AF_INET6, m, &mask.ip6) <= 0) {
|
||||||
j = atoi(m);
|
j = strtonum(m, 0, 128, &errstr);
|
||||||
|
if (errstr != NULL) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"IPv6 netmask %s: %s", m, errstr);
|
||||||
|
debug_return_bool(false);
|
||||||
|
}
|
||||||
for (i = 0; i < sizeof(addr.ip6.s6_addr); i++) {
|
for (i = 0; i < sizeof(addr.ip6.s6_addr); i++) {
|
||||||
if (j < i * 8)
|
if (j < i * 8)
|
||||||
mask.ip6.s6_addr[i] = 0;
|
mask.ip6.s6_addr[i] = 0;
|
||||||
|
@@ -91,7 +91,6 @@ sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group)
|
|||||||
const char *debug_flags = NULL;
|
const char *debug_flags = NULL;
|
||||||
const char *remhost = NULL;
|
const char *remhost = NULL;
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
long lval;
|
|
||||||
char *ep;
|
char *ep;
|
||||||
debug_decl(sudoers_policy_deserialize_info, SUDO_DEBUG_PLUGIN)
|
debug_decl(sudoers_policy_deserialize_info, SUDO_DEBUG_PLUGIN)
|
||||||
|
|
||||||
@@ -119,14 +118,16 @@ sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (MATCHES(*cur, "sudoers_mode=")) {
|
if (MATCHES(*cur, "sudoers_mode=")) {
|
||||||
|
long lval;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
p = *cur + sizeof("sudoers_mode=") - 1;
|
p = *cur + sizeof("sudoers_mode=") - 1;
|
||||||
lval = strtol(p, &ep, 8);
|
lval = strtol(p, &ep, 8);
|
||||||
if (*p == '\0' || *ep != '\0')
|
if (ep == p || *ep != '\0')
|
||||||
fatalx(U_("%s: %s"), *cur, U_("invalid value"));
|
fatalx(U_("%s: %s"), *cur, U_("invalid"));
|
||||||
if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN))
|
if (lval < 0)
|
||||||
|| (lval > 0777 || lval < 0))
|
fatalx(U_("%s: %s"), *cur, U_("too small"));
|
||||||
fatalx(U_("%s: %s"), *cur, U_("value out of range"));
|
if (lval > 0777)
|
||||||
|
fatalx(U_("%s: %s"), *cur, U_("too large"));
|
||||||
sudoers_mode = (mode_t) lval;
|
sudoers_mode = (mode_t) lval;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -147,13 +148,9 @@ sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group)
|
|||||||
if (MATCHES(*cur, "closefrom=")) {
|
if (MATCHES(*cur, "closefrom=")) {
|
||||||
errno = 0;
|
errno = 0;
|
||||||
p = *cur + sizeof("closefrom=") - 1;
|
p = *cur + sizeof("closefrom=") - 1;
|
||||||
lval = strtol(p, &ep, 10);
|
user_closefrom = strtonum(p, 4, INT_MAX, &errstr);
|
||||||
if (*p == '\0' || *ep != '\0')
|
if (user_closefrom == 0)
|
||||||
fatalx(U_("%s: %s"), *cur, U_("invalid value"));
|
fatalx(U_("%s: %s"), *cur, U_(errstr));
|
||||||
if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN))
|
|
||||||
|| (lval > INT_MAX || lval < 3))
|
|
||||||
fatalx(U_("%s: %s"), *cur, U_("value out of range"));
|
|
||||||
user_closefrom = (int) lval;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (MATCHES(*cur, "debug_flags=")) {
|
if (MATCHES(*cur, "debug_flags=")) {
|
||||||
@@ -265,13 +262,9 @@ sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group)
|
|||||||
if (MATCHES(*cur, "max_groups=")) {
|
if (MATCHES(*cur, "max_groups=")) {
|
||||||
errno = 0;
|
errno = 0;
|
||||||
p = *cur + sizeof("max_groups=") - 1;
|
p = *cur + sizeof("max_groups=") - 1;
|
||||||
lval = strtol(p, &ep, 10);
|
sudo_user.max_groups = strtonum(p, 1, INT_MAX, &errstr);
|
||||||
if (*p == '\0' || *ep != '\0')
|
if (sudo_user.max_groups == 0)
|
||||||
fatalx(U_("%s: %s"), *cur, U_("invalid value"));
|
fatalx(U_("%s: %s"), *cur, U_(errstr));
|
||||||
if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN))
|
|
||||||
|| (lval > INT_MAX || lval <= 0))
|
|
||||||
fatalx(U_("%s: %s"), *cur, U_("value out of range"));
|
|
||||||
sudo_user.max_groups = (int) lval;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (MATCHES(*cur, "remote_host=")) {
|
if (MATCHES(*cur, "remote_host=")) {
|
||||||
@@ -322,25 +315,17 @@ sudoers_policy_deserialize_info(void *v, char **runas_user, char **runas_group)
|
|||||||
if (MATCHES(*cur, "lines=")) {
|
if (MATCHES(*cur, "lines=")) {
|
||||||
errno = 0;
|
errno = 0;
|
||||||
p = *cur + sizeof("lines=") - 1;
|
p = *cur + sizeof("lines=") - 1;
|
||||||
lval = strtol(p, &ep, 10);
|
sudo_user.lines = strtonum(p, 1, INT_MAX, &errstr);
|
||||||
if (*p == '\0' || *ep != '\0')
|
if (sudo_user.lines == 0)
|
||||||
fatalx(U_("%s: %s"), *cur, U_("invalid value"));
|
fatalx(U_("%s: %s"), *cur, U_(errstr));
|
||||||
if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN))
|
|
||||||
|| (lval > INT_MAX || lval <= 0))
|
|
||||||
fatalx(U_("%s: %s"), *cur, U_("value out of range"));
|
|
||||||
sudo_user.lines = (int) lval;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (MATCHES(*cur, "cols=")) {
|
if (MATCHES(*cur, "cols=")) {
|
||||||
errno = 0;
|
errno = 0;
|
||||||
p = *cur + sizeof("cols=") - 1;
|
p = *cur + sizeof("cols=") - 1;
|
||||||
lval = strtol(p, &ep, 10);
|
sudo_user.cols = strtonum(p, 1, INT_MAX, &errstr);
|
||||||
if (*p == '\0' || *ep != '\0')
|
if (sudo_user.lines == 0)
|
||||||
fatalx(U_("%s: %s"), *cur, U_("invalid value"));
|
fatalx(U_("%s: %s"), *cur, U_(errstr));
|
||||||
if ((errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN))
|
|
||||||
|| (lval > INT_MAX || lval <= 0))
|
|
||||||
fatalx(U_("%s: %s"), *cur, U_("value out of range"));
|
|
||||||
sudo_user.cols = (int) lval;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (MATCHES(*cur, "sid=")) {
|
if (MATCHES(*cur, "sid=")) {
|
||||||
|
@@ -59,6 +59,7 @@ main(int argc, char *argv[])
|
|||||||
size_t len;
|
size_t len;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *cp, *dash, *line, lines[2][2048];
|
char *cp, *dash, *line, lines[2][2048];
|
||||||
|
int lineno = 0;
|
||||||
int which = 0;
|
int which = 0;
|
||||||
|
|
||||||
initprogname(argc > 0 ? argv[0] : "check_wrap");
|
initprogname(argc > 0 ? argv[0] : "check_wrap");
|
||||||
@@ -83,13 +84,20 @@ main(int argc, char *argv[])
|
|||||||
|
|
||||||
/* If we read the 2nd line, parse list of line lengths and check. */
|
/* If we read the 2nd line, parse list of line lengths and check. */
|
||||||
if (which) {
|
if (which) {
|
||||||
|
lineno++;
|
||||||
for (cp = strtok(lines[1], ","); cp != NULL; cp = strtok(NULL, ",")) {
|
for (cp = strtok(lines[1], ","); cp != NULL; cp = strtok(NULL, ",")) {
|
||||||
size_t maxlen;
|
size_t maxlen;
|
||||||
/* May be either a number or a range. */
|
/* May be either a number or a range. */
|
||||||
len = maxlen = atoi(cp);
|
|
||||||
dash = strchr(cp, '-');
|
dash = strchr(cp, '-');
|
||||||
if (dash)
|
if (dash != NULL) {
|
||||||
maxlen = atoi(dash + 1);
|
*dash = '\0';
|
||||||
|
len = strtonum(cp, 1, INT_MAX, NULL);
|
||||||
|
maxlen = strtonum(dash + 1, 1, INT_MAX, NULL);
|
||||||
|
} else {
|
||||||
|
len = maxlen = strtonum(cp, 1, INT_MAX, NULL);
|
||||||
|
}
|
||||||
|
if (len == 0 || maxlen == 0)
|
||||||
|
fatalx("%s: invalid length on line %d\n", argv[1], lineno);
|
||||||
while (len <= maxlen) {
|
while (len <= maxlen) {
|
||||||
printf("# word wrap at %d characters\n", (int)len);
|
printf("# word wrap at %d characters\n", (int)len);
|
||||||
writeln_wrap(stdout, lines[0], strlen(lines[0]), len);
|
writeln_wrap(stdout, lines[0], strlen(lines[0]), len);
|
||||||
|
@@ -54,6 +54,7 @@ static int
|
|||||||
check_addr(char *input)
|
check_addr(char *input)
|
||||||
{
|
{
|
||||||
int expected, matched;
|
int expected, matched;
|
||||||
|
const char *errstr;
|
||||||
size_t len;
|
size_t len;
|
||||||
char *cp;
|
char *cp;
|
||||||
|
|
||||||
@@ -65,7 +66,9 @@ check_addr(char *input)
|
|||||||
cp = input + len;
|
cp = input + len;
|
||||||
while (isspace((unsigned char)*cp))
|
while (isspace((unsigned char)*cp))
|
||||||
cp++;
|
cp++;
|
||||||
expected = atoi(cp);
|
expected = strtonum(cp, 0, 1, &errstr);
|
||||||
|
if (errstr != NULL)
|
||||||
|
fatalx("expecting 0 or 1, got %s", cp);
|
||||||
input[len] = '\0';
|
input[len] = '\0';
|
||||||
|
|
||||||
matched = addr_matches(input);
|
matched = addr_matches(input);
|
||||||
|
@@ -438,6 +438,7 @@ replay_session(const double max_wait, const char *decimal)
|
|||||||
bool need_nlcr = false;
|
bool need_nlcr = false;
|
||||||
char last_char = '\0';
|
char last_char = '\0';
|
||||||
|
|
||||||
|
buf[strcspn(buf, "\n")] = '\0';
|
||||||
if (!parse_timing(buf, decimal, &idx, &seconds, &nbytes))
|
if (!parse_timing(buf, decimal, &idx, &seconds, &nbytes))
|
||||||
fatalx(U_("invalid timing file line: %s"), buf);
|
fatalx(U_("invalid timing file line: %s"), buf);
|
||||||
|
|
||||||
@@ -802,13 +803,9 @@ parse_logfile(char *logfile)
|
|||||||
{
|
{
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
char *buf = NULL, *cp, *ep;
|
char *buf = NULL, *cp, *ep;
|
||||||
|
const char *errstr;
|
||||||
size_t bufsize = 0, cwdsize = 0, cmdsize = 0;
|
size_t bufsize = 0, cwdsize = 0, cmdsize = 0;
|
||||||
struct log_info *li = NULL;
|
struct log_info *li = NULL;
|
||||||
#ifdef HAVE_STRTOLL
|
|
||||||
long long llval;
|
|
||||||
#else
|
|
||||||
long lval;
|
|
||||||
#endif
|
|
||||||
debug_decl(parse_logfile, SUDO_DEBUG_UTIL)
|
debug_decl(parse_logfile, SUDO_DEBUG_UTIL)
|
||||||
|
|
||||||
fp = fopen(logfile, "r");
|
fp = fopen(logfile, "r");
|
||||||
@@ -837,26 +834,21 @@ parse_logfile(char *logfile)
|
|||||||
/*
|
/*
|
||||||
* Crack the log line (rows and cols not present in old versions).
|
* Crack the log line (rows and cols not present in old versions).
|
||||||
* timestamp:user:runas_user:runas_group:tty:rows:cols
|
* timestamp:user:runas_user:runas_group:tty:rows:cols
|
||||||
|
* XXX - probably better to use strtok and switch on the state.
|
||||||
*/
|
*/
|
||||||
buf[strcspn(buf, "\n")] = '\0';
|
buf[strcspn(buf, "\n")] = '\0';
|
||||||
|
cp = buf;
|
||||||
|
|
||||||
/* timestamp */
|
/* timestamp */
|
||||||
errno = 0;
|
if ((ep = strchr(cp, ':')) == NULL)
|
||||||
#ifdef HAVE_STRTOLL
|
|
||||||
llval = strtoll(buf, &ep, 10);
|
|
||||||
if (buf[0] == '\0' || *ep != ':')
|
|
||||||
goto bad;
|
goto bad;
|
||||||
if (errno == ERANGE && (llval == LLONG_MAX || llval == LLONG_MIN))
|
*ep = '\0';
|
||||||
|
li->tstamp = strtonum(cp, LLONG_MIN, LLONG_MAX, &errstr);
|
||||||
|
if (errstr != NULL) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"%s: timestamp %s is %s", logfile, cp, errstr);
|
||||||
goto bad;
|
goto bad;
|
||||||
li->tstamp = (time_t)llval;
|
}
|
||||||
#else
|
|
||||||
lval = strtol(buf, &ep, 10);
|
|
||||||
if (buf[0] == '\0' || *ep != ':')
|
|
||||||
goto bad;
|
|
||||||
if (errno == ERANGE && (lval == LONG_MAX || lval == LONG_MIN))
|
|
||||||
goto bad;
|
|
||||||
li->tstamp = (time_t)lval;
|
|
||||||
#endif /* HAVE_STRTOLL */
|
|
||||||
|
|
||||||
/* user */
|
/* user */
|
||||||
cp = ep + 1;
|
cp = ep + 1;
|
||||||
@@ -880,14 +872,28 @@ parse_logfile(char *logfile)
|
|||||||
/* tty, followed by optional rows + columns */
|
/* tty, followed by optional rows + columns */
|
||||||
cp = ep + 1;
|
cp = ep + 1;
|
||||||
if ((ep = strchr(cp, ':')) == NULL) {
|
if ((ep = strchr(cp, ':')) == NULL) {
|
||||||
|
/* just the tty */
|
||||||
li->tty = estrdup(cp);
|
li->tty = estrdup(cp);
|
||||||
} else {
|
} else {
|
||||||
|
/* tty followed by rows + columns */
|
||||||
li->tty = estrndup(cp, (size_t)(ep - cp));
|
li->tty = estrndup(cp, (size_t)(ep - cp));
|
||||||
cp = ep + 1;
|
cp = ep + 1;
|
||||||
li->rows = atoi(cp);
|
/* need to NULL out separator to use strtonum() */
|
||||||
if ((ep = strchr(cp, ':')) != NULL) {
|
if ((ep = strchr(cp, ':')) != NULL) {
|
||||||
|
*ep = '\0';
|
||||||
|
}
|
||||||
|
li->rows = strtonum(cp, 1, INT_MAX, &errstr);
|
||||||
|
if (errstr != NULL) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"%s: tty rows %s is %s", logfile, cp, errstr);
|
||||||
|
}
|
||||||
|
if (ep != NULL) {
|
||||||
cp = ep + 1;
|
cp = ep + 1;
|
||||||
li->cols = atoi(cp);
|
li->cols = strtonum(cp, 1, INT_MAX, &errstr);
|
||||||
|
if (errstr != NULL) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"%s: tty cols %s is %s", logfile, cp, errstr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
@@ -1158,6 +1164,8 @@ parse_timing(const char *buf, const char *decimal, int *idx, double *seconds,
|
|||||||
|
|
||||||
/* Parse index */
|
/* Parse index */
|
||||||
ul = strtoul(buf, &ep, 10);
|
ul = strtoul(buf, &ep, 10);
|
||||||
|
if (ep == buf || !isspace((unsigned char) *ep))
|
||||||
|
goto bad;
|
||||||
if (ul >= IOFD_TIMING) {
|
if (ul >= IOFD_TIMING) {
|
||||||
if (ul != 6)
|
if (ul != 6)
|
||||||
goto bad;
|
goto bad;
|
||||||
@@ -1176,11 +1184,10 @@ parse_timing(const char *buf, const char *decimal, int *idx, double *seconds,
|
|||||||
*/
|
*/
|
||||||
errno = 0;
|
errno = 0;
|
||||||
l = strtol(cp, &ep, 10);
|
l = strtol(cp, &ep, 10);
|
||||||
if ((errno == ERANGE && (l == LONG_MAX || l == LONG_MIN)) ||
|
if (ep == cp || (*ep != '.' && strncmp(ep, decimal, strlen(decimal)) != 0))
|
||||||
l < 0 || l > INT_MAX ||
|
goto bad;
|
||||||
(*ep != '.' && strncmp(ep, decimal, strlen(decimal)) != 0)) {
|
if (l < 0 || l > INT_MAX || (errno == ERANGE && l == LONG_MAX))
|
||||||
goto bad;
|
goto bad;
|
||||||
}
|
|
||||||
*seconds = (double)l;
|
*seconds = (double)l;
|
||||||
cp = ep + (*ep == '.' ? 1 : strlen(decimal));
|
cp = ep + (*ep == '.' ? 1 : strlen(decimal));
|
||||||
d = 10.0;
|
d = 10.0;
|
||||||
@@ -1195,7 +1202,7 @@ parse_timing(const char *buf, const char *decimal, int *idx, double *seconds,
|
|||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
ul = strtoul(cp, &ep, 10);
|
ul = strtoul(cp, &ep, 10);
|
||||||
if (errno == ERANGE && ul == ULONG_MAX)
|
if (ep == cp || *ep != '\0' || (errno == ERANGE && ul == ULONG_MAX))
|
||||||
goto bad;
|
goto bad;
|
||||||
*nbytes = (size_t)ul;
|
*nbytes = (size_t)ul;
|
||||||
|
|
||||||
|
@@ -73,6 +73,8 @@ static sysgroup_getgrgid_t sysgroup_getgrgid;
|
|||||||
static sysgroup_gr_delref_t sysgroup_gr_delref;
|
static sysgroup_gr_delref_t sysgroup_gr_delref;
|
||||||
static bool need_setent;
|
static bool need_setent;
|
||||||
|
|
||||||
|
extern id_t atoid(const char *str, const char *sep, char **endp, const char **errstr);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
sysgroup_init(int version, sudo_printf_t sudo_printf, char *const argv[])
|
sysgroup_init(int version, sudo_printf_t sudo_printf, char *const argv[])
|
||||||
{
|
{
|
||||||
@@ -128,16 +130,15 @@ sysgroup_cleanup(void)
|
|||||||
static int
|
static int
|
||||||
sysgroup_query(const char *user, const char *group, const struct passwd *pwd)
|
sysgroup_query(const char *user, const char *group, const struct passwd *pwd)
|
||||||
{
|
{
|
||||||
char **member, *ep = '\0';
|
char **member;
|
||||||
struct group *grp;
|
struct group *grp;
|
||||||
|
|
||||||
grp = sysgroup_getgrnam(group);
|
grp = sysgroup_getgrnam(group);
|
||||||
if (grp == NULL && group[0] == '#' && group[1] != '\0') {
|
if (grp == NULL && group[0] == '#' && group[1] != '\0') {
|
||||||
long lval = strtol(group + 1, &ep, 10);
|
const char *errstr;
|
||||||
if (*ep == '\0') {
|
gid_t gid = atoid(group + 1, NULL, NULL, &errstr);
|
||||||
if ((lval != LONG_MAX && lval != LONG_MIN) || errno != ERANGE)
|
if (errstr == NULL)
|
||||||
grp = sysgroup_getgrgid((gid_t)lval);
|
grp = sysgroup_getgrgid(gid);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (grp != NULL) {
|
if (grp != NULL) {
|
||||||
for (member = grp->gr_mem; *member != NULL; member++) {
|
for (member = grp->gr_mem; *member != NULL; member++) {
|
||||||
|
@@ -178,7 +178,7 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
|
|||||||
char *cp, **env_add, **settings;
|
char *cp, **env_add, **settings;
|
||||||
const char *runas_user = NULL;
|
const char *runas_user = NULL;
|
||||||
const char *runas_group = NULL;
|
const char *runas_group = NULL;
|
||||||
const char *debug_flags;
|
const char *debug_flags, *errstr;
|
||||||
int nenv = 0;
|
int nenv = 0;
|
||||||
int env_size = 32;
|
int env_size = 32;
|
||||||
debug_decl(parse_args, SUDO_DEBUG_ARGS)
|
debug_decl(parse_args, SUDO_DEBUG_ARGS)
|
||||||
@@ -242,8 +242,9 @@ parse_args(int argc, char **argv, int *nargc, char ***nargv, char ***settingsp,
|
|||||||
SET(flags, MODE_BACKGROUND);
|
SET(flags, MODE_BACKGROUND);
|
||||||
break;
|
break;
|
||||||
case 'C':
|
case 'C':
|
||||||
if (atoi(optarg) < 3) {
|
strtonum(optarg, 4, INT_MAX, &errstr);
|
||||||
warningx(U_("the argument to -C must be a number greater than or equal to 3"));
|
if (errstr != NULL) {
|
||||||
|
warningx(U_("the argument to -C was %s"), U_(errstr));
|
||||||
usage(1);
|
usage(1);
|
||||||
}
|
}
|
||||||
sudo_settings[ARG_CLOSEFROM].value = optarg;
|
sudo_settings[ARG_CLOSEFROM].value = optarg;
|
||||||
|
53
src/sudo.c
53
src/sudo.c
@@ -530,8 +530,7 @@ command_info_to_details(char * const info[], struct command_details *details)
|
|||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
id_t id;
|
id_t id;
|
||||||
long lval;
|
char *cp;
|
||||||
char *cp, *ep;
|
|
||||||
const char *errstr;
|
const char *errstr;
|
||||||
debug_decl(command_info_to_details, SUDO_DEBUG_PCOMM)
|
debug_decl(command_info_to_details, SUDO_DEBUG_PCOMM)
|
||||||
|
|
||||||
@@ -553,16 +552,10 @@ command_info_to_details(char * const info[], struct command_details *details)
|
|||||||
SET_STRING("command=", command)
|
SET_STRING("command=", command)
|
||||||
SET_STRING("cwd=", cwd)
|
SET_STRING("cwd=", cwd)
|
||||||
if (strncmp("closefrom=", info[i], sizeof("closefrom=") - 1) == 0) {
|
if (strncmp("closefrom=", info[i], sizeof("closefrom=") - 1) == 0) {
|
||||||
errno = 0;
|
|
||||||
cp = info[i] + sizeof("closefrom=") - 1;
|
cp = info[i] + sizeof("closefrom=") - 1;
|
||||||
lval = strtol(cp, &ep, 10);
|
details->closefrom = strtonum(cp, 0, INT_MAX, &errstr);
|
||||||
if (*cp == '\0' || *ep != '\0')
|
if (errstr != NULL)
|
||||||
fatalx(U_("%s: %s"), info[i], U_("invalid value"));
|
fatalx(U_("%s: %s"), cp, U_(errstr));
|
||||||
if ((errno == ERANGE &&
|
|
||||||
(lval == LONG_MAX || lval == LONG_MIN)) ||
|
|
||||||
(lval > INT_MAX || lval < 0))
|
|
||||||
fatalx(U_("%s: %s"), info[i], U_("value out of range"));
|
|
||||||
details->closefrom = (int)lval;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -578,16 +571,10 @@ command_info_to_details(char * const info[], struct command_details *details)
|
|||||||
break;
|
break;
|
||||||
case 'n':
|
case 'n':
|
||||||
if (strncmp("nice=", info[i], sizeof("nice=") - 1) == 0) {
|
if (strncmp("nice=", info[i], sizeof("nice=") - 1) == 0) {
|
||||||
errno = 0;
|
|
||||||
cp = info[i] + sizeof("nice=") - 1;
|
cp = info[i] + sizeof("nice=") - 1;
|
||||||
lval = strtol(cp, &ep, 10);
|
details->priority = strtonum(cp, INT_MIN, INT_MAX, &errstr);
|
||||||
if (*cp == '\0' || *ep != '\0')
|
if (errstr != NULL)
|
||||||
fatalx(U_("%s: %s"), info[i], U_("invalid value"));
|
fatalx(U_("%s: %s"), cp, U_(errstr));
|
||||||
if ((errno == ERANGE &&
|
|
||||||
(lval == LONG_MAX || lval == LONG_MIN)) ||
|
|
||||||
(lval > INT_MAX || lval < INT_MIN))
|
|
||||||
fatalx(U_("%s: %s"), info[i], U_("value out of range"));
|
|
||||||
details->priority = (int)lval;
|
|
||||||
SET(details->flags, CD_SET_PRIORITY);
|
SET(details->flags, CD_SET_PRIORITY);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -686,31 +673,27 @@ command_info_to_details(char * const info[], struct command_details *details)
|
|||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
if (strncmp("timeout=", info[i], sizeof("timeout=") - 1) == 0) {
|
if (strncmp("timeout=", info[i], sizeof("timeout=") - 1) == 0) {
|
||||||
errno = 0;
|
|
||||||
cp = info[i] + sizeof("timeout=") - 1;
|
cp = info[i] + sizeof("timeout=") - 1;
|
||||||
lval = strtol(cp, &ep, 10);
|
details->timeout = strtonum(cp, 0, INT_MAX, &errstr);
|
||||||
if (*cp == '\0' || *ep != '\0')
|
if (errstr != NULL)
|
||||||
fatalx(U_("%s: %s"), info[i], U_("invalid value"));
|
fatalx(U_("%s: %s"), cp, U_(errstr));
|
||||||
if ((errno == ERANGE &&
|
|
||||||
(lval == LONG_MAX || lval == LONG_MIN)) ||
|
|
||||||
(lval > INT_MAX || lval < 0))
|
|
||||||
fatalx(U_("%s: %s"), info[i], U_("value out of range"));
|
|
||||||
details->timeout = (int)lval;
|
|
||||||
SET(details->flags, CD_SET_TIMEOUT);
|
SET(details->flags, CD_SET_TIMEOUT);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
if (strncmp("umask=", info[i], sizeof("umask=") - 1) == 0) {
|
if (strncmp("umask=", info[i], sizeof("umask=") - 1) == 0) {
|
||||||
|
long lval;
|
||||||
|
char *ep;
|
||||||
errno = 0;
|
errno = 0;
|
||||||
cp = info[i] + sizeof("umask=") - 1;
|
cp = info[i] + sizeof("umask=") - 1;
|
||||||
lval = strtol(cp, &ep, 8);
|
lval = strtol(cp, &ep, 8);
|
||||||
if (*cp == '\0' || *ep != '\0')
|
if (ep == cp || *ep != '\0')
|
||||||
fatalx(U_("%s: %s"), info[i], U_("invalid value"));
|
fatalx(U_("%s: %s"), info[i], U_("invalid"));
|
||||||
if ((errno == ERANGE &&
|
if (lval < 0)
|
||||||
(lval == LONG_MAX || lval == LONG_MIN)) ||
|
fatalx(U_("%s: %s"), info[i], U_("too small"));
|
||||||
(lval > 0777 || lval < 0))
|
if (lval > 0777)
|
||||||
fatalx(U_("%s: %s"), info[i], U_("value out of range"));
|
fatalx(U_("%s: %s"), info[i], U_("too large"));
|
||||||
details->umask = (mode_t)lval;
|
details->umask = (mode_t)lval;
|
||||||
SET(details->flags, CD_SET_UMASK);
|
SET(details->flags, CD_SET_UMASK);
|
||||||
break;
|
break;
|
||||||
|
@@ -441,11 +441,16 @@ get_process_ttyname(void)
|
|||||||
if (len != -1) {
|
if (len != -1) {
|
||||||
/* Field 7 is the tty dev (0 if no tty) */
|
/* Field 7 is the tty dev (0 if no tty) */
|
||||||
char *cp = line;
|
char *cp = line;
|
||||||
|
const char *errstr;
|
||||||
int field = 1;
|
int field = 1;
|
||||||
while (*cp != '\0') {
|
while (*cp != '\0') {
|
||||||
if (*cp++ == ' ') {
|
if (*cp++ == ' ') {
|
||||||
if (++field == 7) {
|
if (++field == 7) {
|
||||||
dev_t tdev = (dev_t)atoi(cp);
|
dev_t tdev = strtonum(cp, INT_MIN, INT_MAX, &errstr);
|
||||||
|
if (errstr) {
|
||||||
|
sudo_debug_printf(SUDO_DEBUG_ERROR|SUDO_DEBUG_LINENO,
|
||||||
|
"%s: tty device number %s", path, errstr);
|
||||||
|
}
|
||||||
if (tdev > 0)
|
if (tdev > 0)
|
||||||
tty = sudo_ttyname_dev(tdev);
|
tty = sudo_ttyname_dev(tdev);
|
||||||
break;
|
break;
|
||||||
|
Reference in New Issue
Block a user