From: Todd C. Miller Date: Wed, 30 Nov 2016 14:32:59 +0000 (-0700) Subject: id_t is 64-bits on FreeBSD so use strtoll() there. X-Git-Tag: SUDO_1_8_19^2~13 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=334350af4598069511c8032f63d57afa1017a57a;p=sudo id_t is 64-bits on FreeBSD so use strtoll() there. Fixes the strtoid regress. --- diff --git a/config.h.in b/config.h.in index 4a080aaf9..75b00825a 100644 --- a/config.h.in +++ b/config.h.in @@ -1034,6 +1034,12 @@ /* Define to 1 if you want sudo to set $HOME in shell mode. */ #undef SHELL_SETS_HOME +/* The size of `id_t', as computed by sizeof. */ +#undef SIZEOF_ID_T + +/* The size of `long long', as computed by sizeof. */ +#undef SIZEOF_LONG_LONG + /* Define to 1 to compile the sudoers plugin statically into the sudo binary. */ #undef STATIC_SUDOERS_PLUGIN diff --git a/configure b/configure index 0af324726..e8d03eb92 100755 --- a/configure +++ b/configure @@ -2367,6 +2367,189 @@ $as_echo "$ac_res" >&6; } eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno } # ac_fn_c_check_member + +# ac_fn_c_compute_int LINENO EXPR VAR INCLUDES +# -------------------------------------------- +# Tries to find the compile-time value of EXPR in a program that includes +# INCLUDES, setting VAR accordingly. Returns whether the value could be +# computed +ac_fn_c_compute_int () +{ + as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack + if test "$cross_compiling" = yes; then + # Depending upon the size, compute the lo and hi bounds. +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=0 ac_mid=0 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid; break +else + as_fn_arith $ac_mid + 1 && ac_lo=$as_val + if test $ac_lo -le $ac_mid; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid + 1 && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) < 0)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=-1 ac_mid=-1 + while :; do + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) >= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_lo=$ac_mid; break +else + as_fn_arith '(' $ac_mid ')' - 1 && ac_hi=$as_val + if test $ac_mid -le $ac_hi; then + ac_lo= ac_hi= + break + fi + as_fn_arith 2 '*' $ac_mid && ac_mid=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + done +else + ac_lo= ac_hi= +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +# Binary search between lo and hi bounds. +while test "x$ac_lo" != "x$ac_hi"; do + as_fn_arith '(' $ac_hi - $ac_lo ')' / 2 + $ac_lo && ac_mid=$as_val + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +int +main () +{ +static int test_array [1 - 2 * !(($2) <= $ac_mid)]; +test_array [0] = 0; +return test_array [0]; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + ac_hi=$ac_mid +else + as_fn_arith '(' $ac_mid ')' + 1 && ac_lo=$as_val +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +done +case $ac_lo in #(( +?*) eval "$3=\$ac_lo"; ac_retval=0 ;; +'') ac_retval=1 ;; +esac + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$4 +static long int longval () { return $2; } +static unsigned long int ulongval () { return $2; } +#include +#include +int +main () +{ + + FILE *f = fopen ("conftest.val", "w"); + if (! f) + return 1; + if (($2) < 0) + { + long int i = longval (); + if (i != ($2)) + return 1; + fprintf (f, "%ld", i); + } + else + { + unsigned long int i = ulongval (); + if (i != ($2)) + return 1; + fprintf (f, "%lu", i); + } + /* Do not output a trailing newline, as this causes \r\n confusion + on some platforms. */ + return ferror (f) || fclose (f) != 0; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_run "$LINENO"; then : + echo >>conftest.val; read $3 config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. @@ -17984,6 +18167,72 @@ $as_echo "#define HAVE_STRUCT_SOCKADDR_IN_SIN_LEN 1" >>confdefs.h fi +# 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 +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of id_t" >&5 +$as_echo_n "checking size of id_t... " >&6; } +if ${ac_cv_sizeof_id_t+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (id_t))" "ac_cv_sizeof_id_t" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_id_t" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (id_t) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_id_t=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_id_t" >&5 +$as_echo "$ac_cv_sizeof_id_t" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_ID_T $ac_cv_sizeof_id_t +_ACEOF + + +# 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 +# declarations like `int a3[[(sizeof (unsigned char)) >= 0]];'. +# This bug is HP SR number 8606223364. +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking size of long long" >&5 +$as_echo_n "checking size of long long... " >&6; } +if ${ac_cv_sizeof_long_long+:} false; then : + $as_echo_n "(cached) " >&6 +else + if ac_fn_c_compute_int "$LINENO" "(long int) (sizeof (long long))" "ac_cv_sizeof_long_long" "$ac_includes_default"; then : + +else + if test "$ac_cv_type_long_long" = yes; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error 77 "cannot compute sizeof (long long) +See \`config.log' for more details" "$LINENO" 5; } + else + ac_cv_sizeof_long_long=0 + fi +fi + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sizeof_long_long" >&5 +$as_echo "$ac_cv_sizeof_long_long" >&6; } + + + +cat >>confdefs.h <<_ACEOF +#define SIZEOF_LONG_LONG $ac_cv_sizeof_long_long +_ACEOF + + if test $ac_cv_header_utmpx_h = "yes"; then ac_fn_c_check_member "$LINENO" "struct utmpx" "ut_id" "ac_cv_member_struct_utmpx_ut_id" " # include diff --git a/configure.ac b/configure.ac index 02f47fb49..5625ef275 100644 --- a/configure.ac +++ b/configure.ac @@ -2337,6 +2337,8 @@ AC_CHECK_TYPE(errno_t, int) SUDO_UID_T_LEN SUDO_SOCK_SA_LEN SUDO_SOCK_SIN_LEN +AC_CHECK_SIZEOF([id_t]) +AC_CHECK_SIZEOF([long long]) dnl dnl Check for utmp/utmpx struct members. dnl We need to have already defined _GNU_SOURCE on glibc which only has diff --git a/include/sudo_debug.h b/include/sudo_debug.h index 658e48d05..881dfce59 100644 --- a/include/sudo_debug.h +++ b/include/sudo_debug.h @@ -132,6 +132,14 @@ struct sudo_conf_debug_file_list; return sudo_debug_ret; \ } while (0) +#define debug_return_id_t(ret) \ + do { \ + id_t sudo_debug_ret = (ret); \ + sudo_debug_exit_id_t(__func__, __FILE__, __LINE__, sudo_debug_subsys,\ + sudo_debug_ret); \ + return sudo_debug_ret; \ + } while (0) + #define debug_return_size_t(ret) \ do { \ size_t sudo_debug_ret = (ret); \ @@ -234,6 +242,7 @@ __dso_public void sudo_debug_exit_bool_v1(const char *func, const char *file, in __dso_public void sudo_debug_exit_int_v1(const char *func, const char *file, int line, int subsys, int ret); __dso_public void sudo_debug_exit_long_v1(const char *func, const char *file, int line, int subsys, long ret); __dso_public void sudo_debug_exit_ptr_v1(const char *func, const char *file, int line, int subsys, const void *ret); +__dso_public void sudo_debug_exit_id_t_v1(const char *func, const char *file, int line, int subsys, id_t ret); __dso_public void sudo_debug_exit_size_t_v1(const char *func, const char *file, int line, int subsys, size_t ret); __dso_public void sudo_debug_exit_ssize_t_v1(const char *func, const char *file, int line, int subsys, ssize_t ret); __dso_public void sudo_debug_exit_str_v1(const char *func, const char *file, int line, int subsys, const char *ret); @@ -258,6 +267,7 @@ __dso_public void sudo_debug_write2_v1(int fd, const char *func, const char *fil #define sudo_debug_exit_int(_a, _b, _c, _d, _e) sudo_debug_exit_int_v1((_a), (_b), (_c), (_d), (_e)) #define sudo_debug_exit_long(_a, _b, _c, _d, _e) sudo_debug_exit_long_v1((_a), (_b), (_c), (_d), (_e)) #define sudo_debug_exit_ptr(_a, _b, _c, _d, _e) sudo_debug_exit_ptr_v1((_a), (_b), (_c), (_d), (_e)) +#define sudo_debug_exit_id_t(_a, _b, _c, _d, _e) sudo_debug_exit_id_t_v1((_a), (_b), (_c), (_d), (_e)) #define sudo_debug_exit_size_t(_a, _b, _c, _d, _e) sudo_debug_exit_size_t_v1((_a), (_b), (_c), (_d), (_e)) #define sudo_debug_exit_ssize_t(_a, _b, _c, _d, _e) sudo_debug_exit_ssize_t_v1((_a), (_b), (_c), (_d), (_e)) #define sudo_debug_exit_str(_a, _b, _c, _d, _e) sudo_debug_exit_str_v1((_a), (_b), (_c), (_d), (_e)) diff --git a/lib/util/regress/atofoo/atofoo_test.c b/lib/util/regress/atofoo/atofoo_test.c index 62cbbd070..78b48758a 100644 --- a/lib/util/regress/atofoo/atofoo_test.c +++ b/lib/util/regress/atofoo/atofoo_test.c @@ -82,7 +82,9 @@ static struct strtoid_data { { "0,1", 0, ",", "," }, { "10", 10, NULL, NULL }, { "-2", -2, NULL, NULL }, +#if (id_t)-2 == 4294967294U { "-2", 4294967294U, NULL, NULL }, +#endif { "4294967294", 4294967294U, NULL, NULL }, { NULL, 0, NULL, NULL } }; diff --git a/lib/util/strtoid.c b/lib/util/strtoid.c index c70925f0d..34f732a7b 100644 --- a/lib/util/strtoid.c +++ b/lib/util/strtoid.c @@ -48,6 +48,54 @@ * On success, returns the parsed ID and clears errstr. * On error, returns 0 and sets errstr. */ +#if SIZEOF_ID_T == SIZEOF_LONG_LONG +id_t +sudo_strtoid_v1(const char *p, const char *sep, char **endp, const char **errstr) +{ + char *ep; + id_t ret = 0; + long long llval; + bool valid = false; + debug_decl(sudo_strtoid, SUDO_DEBUG_UTIL) + + /* skip leading space so we can pick up the sign, if any */ + while (isspace((unsigned char)*p)) + p++; + if (sep == NULL) + sep = ""; + errno = 0; + llval = strtoll(p, &ep, 10); + if (ep != p) { + /* check for valid separator (including '\0') */ + do { + if (*ep == *sep) + valid = true; + } while (*sep++ != '\0'); + } + if (!valid) { + if (errstr != NULL) + *errstr = N_("invalid value"); + errno = EINVAL; + goto done; + } + if (errno == ERANGE) { + if (errstr != NULL) { + if (llval == LLONG_MAX)) { + *errstr = N_("value too large"); + else + *errstr = N_("value too small"); + } + goto done; + } + ret = (id_t)llval; + if (errstr != NULL) + *errstr = NULL; + if (endp != NULL) + *endp = ep; +done: + debug_return_id_t(ret); +} +#else id_t sudo_strtoid_v1(const char *p, const char *sep, char **endp, const char **errstr) { @@ -118,5 +166,6 @@ sudo_strtoid_v1(const char *p, const char *sep, char **endp, const char **errstr if (endp != NULL) *endp = ep; done: - debug_return_int(ret); + debug_return_id_t(ret); } +#endif /* SIZEOF_ID_T == 8 */ diff --git a/lib/util/sudo_debug.c b/lib/util/sudo_debug.c index a65b7ddcf..a9965ca8c 100644 --- a/lib/util/sudo_debug.c +++ b/lib/util/sudo_debug.c @@ -452,6 +452,19 @@ sudo_debug_exit_long_v1(const char *func, const char *file, int line, "<- %s @ %s:%d := %ld", func, file, line, ret); } +void +sudo_debug_exit_id_t_v1(const char *func, const char *file, int line, + int subsys, id_t ret) +{ +#if SIZEOF_ID_T == 8 + sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE, + "<- %s @ %s:%d := %lld", func, file, line, (long long)ret); +#else + sudo_debug_printf2(NULL, NULL, 0, subsys | SUDO_DEBUG_TRACE, + "<- %s @ %s:%d := %d", func, file, line, (int)ret); +#endif +} + void sudo_debug_exit_size_t_v1(const char *func, const char *file, int line, int subsys, size_t ret) diff --git a/lib/util/util.exp.in b/lib/util/util.exp.in index 0164491e8..0c5f13bcf 100644 --- a/lib/util/util.exp.in +++ b/lib/util/util.exp.in @@ -17,6 +17,7 @@ sudo_debug_enter_v1 sudo_debug_execve2_v1 sudo_debug_exit_v1 sudo_debug_exit_bool_v1 +sudo_debug_exit_id_t_v1 sudo_debug_exit_int_v1 sudo_debug_exit_long_v1 sudo_debug_exit_ptr_v1