2
0
mirror of https://github.com/sudo-project/sudo.git synced 2025-08-22 09:57:41 +00:00

Store signal name, not number in I/O log timing file.

The "SIG" prefix is not used so, e.g. SIGTERM -> "TERM".
This makes the I/O log files portable from one system to another.
Older I/O log files with signal numbers can still be replayed.
This commit is contained in:
Todd C. Miller 2019-08-05 16:30:58 -06:00
parent dfc32e5b3e
commit 3e56be3564
11 changed files with 225 additions and 25 deletions

View File

@ -96,10 +96,10 @@ lib/util/fatal.c
lib/util/fnmatch.c lib/util/fnmatch.c
lib/util/getaddrinfo.c lib/util/getaddrinfo.c
lib/util/getcwd.c lib/util/getcwd.c
lib/util/getdelim.c
lib/util/getentropy.c lib/util/getentropy.c
lib/util/getgrouplist.c lib/util/getgrouplist.c
lib/util/gethostname.c lib/util/gethostname.c
lib/util/getdelim.c
lib/util/getopt_long.c lib/util/getopt_long.c
lib/util/gettime.c lib/util/gettime.c
lib/util/gidlist.c lib/util/gidlist.c
@ -173,6 +173,7 @@ lib/util/sha2.c
lib/util/sig2str.c lib/util/sig2str.c
lib/util/siglist.in lib/util/siglist.in
lib/util/snprintf.c lib/util/snprintf.c
lib/util/str2sig.c
lib/util/strlcat.c lib/util/strlcat.c
lib/util/strlcpy.c lib/util/strlcpy.c
lib/util/strndup.c lib/util/strndup.c

View File

@ -718,6 +718,9 @@
/* Define to 1 if you have the <stdlib.h> header file. */ /* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H #undef HAVE_STDLIB_H
/* Define to 1 if you have the `str2sig' function. */
#undef HAVE_STR2SIG
/* Define to 1 if you have the <strings.h> header file. */ /* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H #undef HAVE_STRINGS_H

40
configure vendored
View File

@ -22728,7 +22728,6 @@ _ACEOF
if test $ac_have_decl = 1; then : if test $ac_have_decl = 1; then :
HAVE_SIGLIST="true" HAVE_SIGLIST="true"
break
fi fi
ac_fn_c_check_decl "$LINENO" "_sys_siglist" "ac_cv_have_decl__sys_siglist" " ac_fn_c_check_decl "$LINENO" "_sys_siglist" "ac_cv_have_decl__sys_siglist" "
@ -22748,7 +22747,6 @@ _ACEOF
if test $ac_have_decl = 1; then : if test $ac_have_decl = 1; then :
HAVE_SIGLIST="true" HAVE_SIGLIST="true"
break
fi fi
@ -22801,6 +22799,38 @@ esac
" "
done done
fi
done
for ac_func in str2sig
do :
ac_fn_c_check_func "$LINENO" "str2sig" "ac_cv_func_str2sig"
if test "x$ac_cv_func_str2sig" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_STR2SIG 1
_ACEOF
else
case " $LIBOBJS " in
*" str2sig.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS str2sig.$ac_objext"
;;
esac
for _sym in sudo_str2sig; do
COMPAT_EXP="${COMPAT_EXP}${_sym}
"
done
fi
done
if test x"${ac_cv_func_sig2str}${ac_cv_func_str2sig}" != x"yesyes"; then
HAVE_SIGNAME="false" HAVE_SIGNAME="false"
ac_fn_c_check_decl "$LINENO" "sys_signame" "ac_cv_have_decl_sys_signame" " ac_fn_c_check_decl "$LINENO" "sys_signame" "ac_cv_have_decl_sys_signame" "
$ac_includes_default $ac_includes_default
@ -22819,7 +22849,6 @@ _ACEOF
if test $ac_have_decl = 1; then : if test $ac_have_decl = 1; then :
HAVE_SIGNAME="true" HAVE_SIGNAME="true"
break
fi fi
ac_fn_c_check_decl "$LINENO" "_sys_signame" "ac_cv_have_decl__sys_signame" " ac_fn_c_check_decl "$LINENO" "_sys_signame" "ac_cv_have_decl__sys_signame" "
@ -22839,7 +22868,6 @@ _ACEOF
if test $ac_have_decl = 1; then : if test $ac_have_decl = 1; then :
HAVE_SIGNAME="true" HAVE_SIGNAME="true"
break
fi fi
ac_fn_c_check_decl "$LINENO" "sys_sigabbrev" "ac_cv_have_decl_sys_sigabbrev" " ac_fn_c_check_decl "$LINENO" "sys_sigabbrev" "ac_cv_have_decl_sys_sigabbrev" "
@ -22859,7 +22887,6 @@ _ACEOF
if test $ac_have_decl = 1; then : if test $ac_have_decl = 1; then :
HAVE_SIGNAME="true" HAVE_SIGNAME="true"
break
fi fi
@ -22905,10 +22932,7 @@ esac
fi fi
fi fi
fi fi
done
OLIBS="$LIBS" OLIBS="$LIBS"
LIBS="$LIBS $lt_cv_dlopen_libs" LIBS="$LIBS $lt_cv_dlopen_libs"

View File

@ -3264,7 +3264,6 @@ AC_CHECK_FUNCS([strsignal], [], [
HAVE_SIGLIST="false" HAVE_SIGLIST="false"
AC_CHECK_DECLS([sys_siglist, _sys_siglist], [ AC_CHECK_DECLS([sys_siglist, _sys_siglist], [
HAVE_SIGLIST="true" HAVE_SIGLIST="true"
break
], [ ], [ ], [ ], [
AC_INCLUDES_DEFAULT AC_INCLUDES_DEFAULT
#include <signal.h> #include <signal.h>
@ -3275,7 +3274,7 @@ AC_INCLUDES_DEFAULT
]) ])
dnl dnl
dnl Check for sig2str(), sys_signame or sys_sigabbrev dnl Check for sig2str() and str2sig(), sys_signame or sys_sigabbrev
dnl dnl
AC_CHECK_FUNCS([sig2str], [ AC_CHECK_FUNCS([sig2str], [
AC_CHECK_DECLS(SIG2STR_MAX, [], [], [ AC_CHECK_DECLS(SIG2STR_MAX, [], [], [
@ -3283,10 +3282,19 @@ AC_CHECK_FUNCS([sig2str], [
])], [ ])], [
AC_LIBOBJ(sig2str) AC_LIBOBJ(sig2str)
SUDO_APPEND_COMPAT_EXP(sudo_sig2str) SUDO_APPEND_COMPAT_EXP(sudo_sig2str)
])
AC_CHECK_FUNCS([str2sig], [], [
AC_LIBOBJ(str2sig)
SUDO_APPEND_COMPAT_EXP(sudo_str2sig)
])
dnl
dnl Check for sys_signame or sys_sigabbrev if missing sig2str() or str2sig().
dnl
if test x"${ac_cv_func_sig2str}${ac_cv_func_str2sig}" != x"yesyes"; then
HAVE_SIGNAME="false" HAVE_SIGNAME="false"
AC_CHECK_DECLS([sys_signame, _sys_signame, sys_sigabbrev], [ AC_CHECK_DECLS([sys_signame, _sys_signame, sys_sigabbrev], [
HAVE_SIGNAME="true" HAVE_SIGNAME="true"
break
], [ ], [ ], [ ], [
AC_INCLUDES_DEFAULT AC_INCLUDES_DEFAULT
#include <signal.h> #include <signal.h>
@ -3307,7 +3315,7 @@ AC_INCLUDES_DEFAULT
AC_LIBOBJ(signame) AC_LIBOBJ(signame)
fi fi
fi fi
]) fi
dnl dnl
dnl Check for dl_iterate_phdr, may require -ldl dnl Check for dl_iterate_phdr, may require -ldl

View File

@ -25,7 +25,7 @@
.nr BA @BAMAN@ .nr BA @BAMAN@
.nr LC @LCMAN@ .nr LC @LCMAN@
.nr PS @PSMAN@ .nr PS @PSMAN@
.TH "SUDOERS" "@mansectform@" "July 19, 2019" "Sudo @PACKAGE_VERSION@" "File Formats Manual" .TH "SUDOERS" "@mansectform@" "August 5, 2019" "Sudo @PACKAGE_VERSION@" "File Formats Manual"
.nh .nh
.if n .ad l .if n .ad l
.SH "NAME" .SH "NAME"
@ -4886,7 +4886,7 @@ bug compatibility for
1.8.7 terminal output 1.8.7 terminal output
.TP 6n .TP 6n
7 7
command suspend or resume, signal number received command suspend or resume, signal received
.PP .PP
.RE .RE
.PD .PD

View File

@ -24,7 +24,7 @@
.nr BA @BAMAN@ .nr BA @BAMAN@
.nr LC @LCMAN@ .nr LC @LCMAN@
.nr PS @PSMAN@ .nr PS @PSMAN@
.Dd July 19, 2019 .Dd August 5, 2019
.Dt SUDOERS @mansectform@ .Dt SUDOERS @mansectform@
.Os Sudo @PACKAGE_VERSION@ .Os Sudo @PACKAGE_VERSION@
.Sh NAME .Sh NAME
@ -4550,7 +4550,7 @@ bug compatibility for
.Nm sudo .Nm sudo
1.8.7 terminal output 1.8.7 terminal output
.It 7 .It 7
command suspend or resume, signal number received command suspend or resume, signal received
.El .El
.It Pa ttyin .It Pa ttyin
Raw input from the user's terminal, exactly as it was received. Raw input from the user's terminal, exactly as it was received.

View File

@ -500,6 +500,11 @@ __dso_public int sudo_sig2str(int signo, char *signame);
# undef sig2str # undef sig2str
# define sig2str(_a, _b) sudo_sig2str((_a), (_b)) # define sig2str(_a, _b) sudo_sig2str((_a), (_b))
#endif /* HAVE_SIG2STR */ #endif /* HAVE_SIG2STR */
#ifndef HAVE_STR2SIG
__dso_public int sudo_str2sig(const char *signame, int *signum);
# undef str2sig
# define str2sig(_a, _b) sudo_str2sig((_a), (_b))
#endif /* HAVE_STR2SIG */
#if !defined(HAVE_INET_NTOP) && defined(SUDO_NET_IFS_C) #if !defined(HAVE_INET_NTOP) && defined(SUDO_NET_IFS_C)
__dso_public char *sudo_inet_ntop(int af, const void *src, char *dst, socklen_t size); __dso_public char *sudo_inet_ntop(int af, const void *src, char *dst, socklen_t size);
# undef inet_ntop # undef inet_ntop

View File

@ -938,6 +938,12 @@ snprintf.i: $(srcdir)/snprintf.c $(incdir)/sudo_compat.h \
$(CC) -E -o $@ $(CPPFLAGS) $< $(CC) -E -o $@ $(CPPFLAGS) $<
snprintf.plog: snprintf.i snprintf.plog: snprintf.i
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/snprintf.c --i-file $< --output-file $@ rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/snprintf.c --i-file $< --output-file $@
str2sig.lo: $(srcdir)/str2sig.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/str2sig.c
str2sig.i: $(srcdir)/str2sig.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
$(CC) -E -o $@ $(CPPFLAGS) $<
str2sig.plog: str2sig.i
rm -f $@; pvs-studio --cfg $(PVS_CFG) --sourcetree-root $(top_srcdir) --skip-cl-exe yes --source-file $(srcdir)/str2sig.c --i-file $< --output-file $@
strlcat.lo: $(srcdir)/strlcat.c $(incdir)/sudo_compat.h $(top_builddir)/config.h strlcat.lo: $(srcdir)/strlcat.c $(incdir)/sudo_compat.h $(top_builddir)/config.h
$(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/strlcat.c $(LIBTOOL) $(LTFLAGS) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(ASAN_CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(srcdir)/strlcat.c
strlcat.i: $(srcdir)/strlcat.c $(incdir)/sudo_compat.h $(top_builddir)/config.h strlcat.i: $(srcdir)/strlcat.c $(incdir)/sudo_compat.h $(top_builddir)/config.h

154
lib/util/str2sig.c Normal file
View File

@ -0,0 +1,154 @@
/*
* SPDX-License-Identifier: ISC
*
* Copyright (c) 2019 Todd C. Miller <Todd.Miller@sudo.ws>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
/*
* This is an open source non-commercial project. Dear PVS-Studio, please check it.
* PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
*/
#include <config.h>
#ifndef HAVE_STR2SIG
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_STRING_H
# include <string.h>
#endif /* HAVE_STRING_H */
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif /* HAVE_STRINGS_H */
#include <signal.h>
#include <ctype.h>
#include "sudo_compat.h"
#if defined(HAVE_DECL_SYS_SIGNAME) && HAVE_DECL_SYS_SIGNAME == 1
# define sudo_sys_signame sys_signame
#elif defined(HAVE_DECL__SYS_SIGNAME) && HAVE_DECL__SYS_SIGNAME == 1
# define sudo_sys_signame _sys_signame
#elif defined(HAVE_DECL_SYS_SIGABBREV) && HAVE_DECL_SYS_SIGABBREV == 1
# define sudo_sys_signame sys_sigabbrev
#else
# ifdef HAVE_SYS_SIGABBREV
/* sys_sigabbrev is not declared by glibc */
# define sudo_sys_signame sys_sigabbrev
# endif
extern const char *const sudo_sys_signame[NSIG];
#endif
/*
* Translate signal name to number.
*/
int
sudo_str2sig(const char *signame, int *result)
{
int signo;
const char *errstr;
/* Could be a signal number encoded as a string. */
if (isdigit((unsigned char)signame[0])) {
signo = strtonum(signame, 0, NSIG - 1, &errstr);
if (errstr != NULL)
return -1;
*result = signo;
return 0;
}
/* Special cases. */
switch (signame[0]) {
case 'C':
/* support both SIGCLD and SIGCHLD */
#ifdef SIGCLD
if (strcmp(signame, "CLD") == 0) {
*result = SIGCLD;
return 0;
}
#endif
#ifdef SIGCHLD
if (strcmp(signame, "CHLD") == 0) {
*result = SIGCHLD;
return 0;
}
#endif
break;
#ifdef SIGIO
case 'I':
/* support both SIGIO and SIGPOLL */
if (strcmp(signame, "IO") == 0) {
*result = SIGIO;
return 0;
}
break;
#endif
#ifdef SIGPOLL
case 'P':
/* support both SIGIO and SIGPOLL */
if (strcmp(signame, "POLL") == 0) {
*result = SIGPOLL;
return 0;
}
break;
#endif
case 'R':
/* real-time signals */
#if defined(SIGRTMIN)
if (strncmp(signame, "RTMIN", 5) == 0) {
if (signame[5] == '\0') {
*result = SIGRTMIN;
return 0;
}
if (signame[5] == '+') {
if (signame[6] == '1' || signame[6] == '2' || signame[6] == '3') {
*result = SIGRTMIN + (signame[6] - '0');
return 0;
}
}
}
#endif
#if defined(SIGRTMAX)
if (strncmp(signame, "RTMAX", 5) == 0) {
if (signame[5] == '\0') {
*result = SIGRTMAX;
return 0;
}
if (signame[5] == '-') {
if (signame[6] == '1' || signame[6] == '2' || signame[6] == '3') {
*result = SIGRTMAX - (signame[6] - '0');
return 0;
}
}
}
#endif
break;
}
for (signo = 0; signo < NSIG; signo++) {
if (strcmp(signame, sudo_sys_signame[signo]) == 0) {
*result = signo;
return 0;
}
}
errno = EINVAL;
return -1;
}
#endif /* HAVE_STR2SIG */

View File

@ -1221,12 +1221,13 @@ sudoers_io_suspend(int signo)
{ {
struct timespec now, delay; struct timespec now, delay;
unsigned int len; unsigned int len;
char signame[SIG2STR_MAX];
char tbuf[1024]; char tbuf[1024];
const char *errstr = NULL; const char *errstr = NULL;
int ret = -1; int ret = -1;
debug_decl(sudoers_io_suspend, SUDOERS_DEBUG_PLUGIN) debug_decl(sudoers_io_suspend, SUDOERS_DEBUG_PLUGIN)
if (signo <= 0) { if (signo <= 0 || sig2str(signo, signame) == -1) {
sudo_warnx(U_("%s: internal error, invalid signal %d"), sudo_warnx(U_("%s: internal error, invalid signal %d"),
__func__, signo); __func__, signo);
debug_return_int(-1); debug_return_int(-1);
@ -1241,8 +1242,8 @@ sudoers_io_suspend(int signo)
/* Write suspend event to the timing file. */ /* Write suspend event to the timing file. */
sudo_timespecsub(&now, &last_time, &delay); sudo_timespecsub(&now, &last_time, &delay);
len = (unsigned int)snprintf(tbuf, sizeof(tbuf), "%d %lld.%09ld %d\n", len = (unsigned int)snprintf(tbuf, sizeof(tbuf), "%d %lld.%09ld %s\n",
IO_EVENT_SUSPEND, (long long)delay.tv_sec, delay.tv_nsec, signo); IO_EVENT_SUSPEND, (long long)delay.tv_sec, delay.tv_nsec, signame);
if (len >= sizeof(tbuf)) { if (len >= sizeof(tbuf)) {
/* Not actually possible due to the size of tbuf[]. */ /* Not actually possible due to the size of tbuf[]. */
errstr = strerror(EOVERFLOW); errstr = strerror(EOVERFLOW);

View File

@ -37,6 +37,7 @@
#ifdef HAVE_STRINGS_H #ifdef HAVE_STRINGS_H
# include <strings.h> # include <strings.h>
#endif /* HAVE_STRINGS_H */ #endif /* HAVE_STRINGS_H */
#include <signal.h>
#include <unistd.h> #include <unistd.h>
#include <ctype.h> #include <ctype.h>
#include <errno.h> #include <errno.h>
@ -333,12 +334,9 @@ parse_timing(const char *buf, struct timespec *delay,
switch (timing->event) { switch (timing->event) {
case IO_EVENT_SUSPEND: case IO_EVENT_SUSPEND:
ulval = strtoul(cp, &ep, 10); /* Signal name (no leading SIG prefix) or number. */
if (ep == cp || *ep != '\0') if (str2sig(cp, &timing->u.signo) == -1)
goto bad; goto bad;
if (ulval > INT_MAX)
goto bad;
timing->u.signo = (int)ulval;
break; break;
case IO_EVENT_WINSIZE: case IO_EVENT_WINSIZE:
ulval = strtoul(cp, &ep, 10); ulval = strtoul(cp, &ep, 10);