Use futimens() and utimensat() instead of futimes() and utimes().

This commit is contained in:
Todd C. Miller
2015-03-02 13:58:50 -07:00
parent ea514dc391
commit ee72cba937
20 changed files with 433 additions and 259 deletions

View File

@@ -93,6 +93,7 @@ lib/util/getgrouplist.c
lib/util/gethostname.c
lib/util/getline.c
lib/util/getopt_long.c
lib/util/gettime.c
lib/util/gidlist.c
lib/util/glob.c
lib/util/inet_ntop.c
@@ -170,7 +171,7 @@ lib/util/sudo_dso.c
lib/util/term.c
lib/util/ttysize.c
lib/util/util.exp.in
lib/util/utimes.c
lib/util/utimens.c
lib/zlib/Makefile.in
lib/zlib/adler32.c
lib/zlib/compress.c
@@ -257,7 +258,6 @@ plugins/sudoers/find_path.c
plugins/sudoers/getdate.c
plugins/sudoers/getdate.y
plugins/sudoers/getspwuid.c
plugins/sudoers/gettime.c
plugins/sudoers/goodpath.c
plugins/sudoers/gram.c
plugins/sudoers/gram.h

View File

@@ -244,6 +244,9 @@
/* Define to 1 if you have the `futime' function. */
#undef HAVE_FUTIME
/* Define to 1 if you have the `futimens' function. */
#undef HAVE_FUTIMENS
/* Define to 1 if you have the `futimes' function. */
#undef HAVE_FUTIMES
@@ -826,6 +829,9 @@
/* Define to 1 if you have the <util.h> header file. */
#undef HAVE_UTIL_H
/* Define to 1 if you have the `utimensat' function. */
#undef HAVE_UTIMENSAT
/* Define to 1 if you have the `utimes' function. */
#undef HAVE_UTIMES

88
configure vendored
View File

@@ -18939,7 +18939,29 @@ done
fi
done
for ac_func in utimes
for ac_func in utimensat
do :
ac_fn_c_check_func "$LINENO" "utimensat" "ac_cv_func_utimensat"
if test "x$ac_cv_func_utimensat" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_UTIMENSAT 1
_ACEOF
else
case " $LIBOBJS " in
*" utimens.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS utimens.$ac_objext"
;;
esac
for _sym in sudo_utimensat; do
COMPAT_EXP="${COMPAT_EXP}${_sym}
"
done
for ac_func in utimes
do :
ac_fn_c_check_func "$LINENO" "utimes" "ac_cv_func_utimes"
if test "x$ac_cv_func_utimes" = xyes; then :
@@ -18947,7 +18969,36 @@ if test "x$ac_cv_func_utimes" = xyes; then :
#define HAVE_UTIMES 1
_ACEOF
for ac_func in futimes futimesat
fi
done
fi
done
for ac_func in futimens
do :
ac_fn_c_check_func "$LINENO" "futimens" "ac_cv_func_futimens"
if test "x$ac_cv_func_futimens" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_FUTIMENS 1
_ACEOF
else
case " $LIBOBJS " in
*" utimens.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS utimens.$ac_objext"
;;
esac
for _sym in sudo_futimens; do
COMPAT_EXP="${COMPAT_EXP}${_sym}
"
done
for ac_func in futimes futimesat futime
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -18960,37 +19011,6 @@ fi
done
else
case " $LIBOBJS " in
*" utimes.$ac_objext "* ) ;;
*) LIBOBJS="$LIBOBJS utimes.$ac_objext"
;;
esac
for _sym in sudo_utimes; do
COMPAT_EXP="${COMPAT_EXP}${_sym}
"
done
for ac_func in futime
do :
ac_fn_c_check_func "$LINENO" "futime" "ac_cv_func_futime"
if test "x$ac_cv_func_futime" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_FUTIME 1
_ACEOF
for _sym in sudo_futimes; do
COMPAT_EXP="${COMPAT_EXP}${_sym}
"
done
fi
done
fi
done
@@ -19295,7 +19315,7 @@ if test "x$ac_cv_lib_rt_clock_gettime" = xyes; then :
$as_echo "#define HAVE_CLOCK_GETTIME 1" >>confdefs.h
SUDOERS_LIBS="${SUDOERS_LIBS} -lrt"
LIBS="${LIBS} -lrt"
fi

View File

@@ -2495,12 +2495,15 @@ AC_INCLUDES_DEFAULT
], [
AC_CHECK_FUNCS([sysinfo], [AC_CHECK_HEADERS([sys/systeminfo.h])])
])
AC_CHECK_FUNCS([utimes], [
AC_CHECK_FUNCS([futimes futimesat], [break])
], [
AC_LIBOBJ(utimes)
SUDO_APPEND_COMPAT_EXP(sudo_utimes)
AC_CHECK_FUNCS([futime], [SUDO_APPEND_COMPAT_EXP(sudo_futimes)])
AC_CHECK_FUNCS([utimensat], [], [
AC_LIBOBJ(utimens)
SUDO_APPEND_COMPAT_EXP(sudo_utimensat)
AC_CHECK_FUNCS([utimes])
])
AC_CHECK_FUNCS([futimens], [], [
AC_LIBOBJ(utimens)
SUDO_APPEND_COMPAT_EXP(sudo_futimens)
AC_CHECK_FUNCS([futimes futimesat futime], [break])
])
SUDO_FUNC_FNMATCH([AC_DEFINE(HAVE_FNMATCH)], [
AC_LIBOBJ(fnmatch)
@@ -2536,7 +2539,7 @@ AC_CHECK_FUNCS([clock_gettime], [], [
# On Solaris, clock_gettime is in librt
AC_CHECK_LIB(rt, clock_gettime, [
AC_DEFINE(HAVE_CLOCK_GETTIME)
SUDOERS_LIBS="${SUDOERS_LIBS} -lrt"
LIBS="${LIBS} -lrt"
])
])
AC_CHECK_FUNCS([getopt_long], [], [

View File

@@ -189,6 +189,19 @@
# define S_IRWXU 0000700 /* rwx for owner */
#endif /* S_IRWXU */
/* For futimens() and utimensat() emulation. */
#if !defined(HAVE_FUTIMENS) && !defined(HAVE_UTIMENSAT)
# ifndef UTIME_OMIT
# define UTIME_OMIT -1L
# endif
# ifndef UTIME_NOW
# define UTIME_NOW -2L
# endif
# ifndef AT_FDCWD
# define AT_FDCWD -100
# endif
#endif
/*
* These should be defined in <unistd.h> but not everyone has them.
*/
@@ -276,14 +289,6 @@ typedef struct sigaction sigaction_t;
# define HAVE_DIRFD
#endif
/*
* Define futimes() in terms of futimesat() if needed.
*/
#if !defined(HAVE_FUTIMES) && defined(HAVE_FUTIMESAT)
# define futimes(_f, _tv) futimesat(_f, NULL, _tv)
# define HAVE_FUTIMES
#endif
#if !defined(HAVE_KILLPG) && !defined(killpg)
# define killpg(s) kill(-(s))
#endif
@@ -386,16 +391,16 @@ __dso_public ssize_t sudo_getline(char **bufp, size_t *bufsizep, FILE *fp);
# undef getline
# define getline(_a, _b, _c) sudo_getline((_a), (_b), (_c))
#endif /* HAVE_GETLINE */
#ifndef HAVE_UTIMES
__dso_public int sudo_utimes(const char *file, const struct timeval *times);
# undef utimes
# define utimes(_a, _b) sudo_utimes((_a), (_b))
#endif /* HAVE_UTIMES */
#ifdef HAVE_FUTIME
__dso_public int sudo_futimes(int fd, const struct timeval *times);
# undef futimes
# define futimes(_a, _b) sudo_futimes((_a), (_b))
#endif /* HAVE_FUTIME */
#ifndef HAVE_UTIMENSAT
__dso_public int sudo_utimensat(int fd, const char *file, const struct timespec *times, int flag);
# undef utimensat
# define utimensat(_a, _b, _c, _d) sudo_utimensat((_a), (_b), (_c), (_d))
#endif /* HAVE_UTIMENSAT */
#ifndef HAVE_FUTIMENS
__dso_public int sudo_futimens(int fd, const struct timespec *times);
# undef futimens
# define futimens(_a, _b) sudo_futimens((_a), (_b))
#endif /* HAVE_FUTIMENS */
#if !defined(HAVE_SNPRINTF) || defined(PREFER_PORTABLE_SNPRINTF)
__dso_public int sudo_snprintf(char *str, size_t n, char const *fmt, ...) __printflike(3, 4);
# undef snprintf

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 2013-2014 Todd C. Miller <Todd.Miller@courtesan.com>
* Copyright (c) 2013-2015 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -104,24 +104,32 @@
#endif
/*
* Macros to extract ctime and mtime as timevals.
* The timespec version of st_mtime may vary on different platforms.
*/
#ifdef HAVE_ST_MTIM
# ifdef HAVE_ST__TIM
# define ctim_get(_x, _y) TIMESPEC_TO_TIMEVAL((_y), &(_x)->st_ctim.st__tim)
# define mtim_get(_x, _y) TIMESPEC_TO_TIMEVAL((_y), &(_x)->st_mtim.st__tim)
#if defined(HAVE_ST_MTIM)
# if defined(HAVE_ST__TIM)
# define SUDO_ST_MTIM st_mtim.st__tim
# else
# define ctim_get(_x, _y) TIMESPEC_TO_TIMEVAL((_y), &(_x)->st_ctim)
# define mtim_get(_x, _y) TIMESPEC_TO_TIMEVAL((_y), &(_x)->st_mtim)
# define SUDO_ST_MTIM st_mtim
# endif
#elif defined(HAVE_ST_MTIMESPEC)
# define SUDO_ST_MTIM st_mtimespec
#endif
/*
* Macro to extract mtime as timespec.
* If there is no way to set the timestamp using nanosecond precision,
* we only fetch microsecond precision. Otherwise there is a mismatch
* between the timestamp we read and the one we wrote.
*/
#if defined(SUDO_ST_MTIM)
# if defined(HAVE_FUTIMENS) && defined(HAVE_UTIMENSAT)
# define mtim_get(_x, _y) ((_y) = (_x)->SUDO_ST_MTIM)
# else
# define mtim_get(_x, _y) do { (_y).tv_sec = (_x)->SUDO_ST_MTIM.tv_sec; (_y).tv_nsec = ((_x)->SUDO_ST_MTIM.tv_nsec / 1000) * 1000; } while (0)
# endif
#else
# ifdef HAVE_ST_MTIMESPEC
# define ctim_get(_x, _y) TIMESPEC_TO_TIMEVAL((_y), &(_x)->st_ctimespec)
# define mtim_get(_x, _y) TIMESPEC_TO_TIMEVAL((_y), &(_x)->st_mtimespec)
# else
# define ctim_get(_x, _y) do { (_y)->tv_sec = (_x)->st_ctime; (_y)->tv_usec = 0; } while (0)
# define mtim_get(_x, _y) do { (_y)->tv_sec = (_x)->st_mtime; (_y)->tv_usec = 0; } while (0)
# endif /* HAVE_ST_MTIMESPEC */
# define mtim_get(_x, _y) do { (_y).tv_sec = (_x)->st_mtime; (_y).tv_nsec = 0; } while (0)
#endif /* HAVE_ST_MTIM */
/*
@@ -148,6 +156,12 @@ __dso_public int aix_setauthdb_v1(char *user);
__dso_public char *sudo_gethostname_v1(void);
#define sudo_gethostname() sudo_gethostname_v1()
/* gettime.c */
__dso_public int sudo_gettime_mono_v1(struct timespec *ts);
#define sudo_gettime_mono(_a) sudo_gettime_mono_v1((_a))
__dso_public int sudo_gettime_real_v1(struct timespec *ts);
#define sudo_gettime_real(_a) sudo_gettime_real_v1((_a))
/* gidlist.c */
__dso_public int sudo_parse_gids_v1(const char *gidstr, const gid_t *basegid, GETGROUPS_T **gidsp);
#define sudo_parse_gids(_a, _b, _c) sudo_parse_gids_v1((_a), (_b), (_c))

View File

@@ -96,10 +96,10 @@ DEVEL = @DEVEL@
SHELL = @SHELL@
LTOBJS = alloc.lo event.lo fatal.lo key_val.lo gethostname.lo gidlist.lo \
lbuf.lo locking.lo parseln.lo progname.lo secure_path.lo setgroups.lo \
strtobool.lo strtoid.lo strtomode.lo sudo_conf.lo sudo_debug.lo \
sudo_dso.lo term.lo ttysize.lo @COMMON_OBJS@ @LTLIBOBJS@
LTOBJS = alloc.lo event.lo fatal.lo key_val.lo gethostname.lo gettime.lo \
gidlist.lo lbuf.lo locking.lo parseln.lo progname.lo secure_path.lo \
setgroups.lo strtobool.lo strtoid.lo strtomode.lo sudo_conf.lo \
sudo_debug.lo sudo_dso.lo term.lo ttysize.lo @COMMON_OBJS@ @LTLIBOBJS@
ATOFOO_TEST_OBJS = atofoo_test.lo locale_stub.lo
@@ -375,6 +375,11 @@ getopt_long.lo: $(srcdir)/getopt_long.c $(incdir)/compat/getopt.h \
$(incdir)/sudo_compat.h $(incdir)/sudo_fatal.h \
$(top_builddir)/config.h
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/getopt_long.c
gettime.lo: $(srcdir)/gettime.c $(incdir)/compat/stdbool.h \
$(incdir)/compat/timespec.h $(incdir)/sudo_compat.h \
$(incdir)/sudo_debug.h $(incdir)/sudo_queue.h \
$(incdir)/sudo_util.h $(top_builddir)/config.h
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/gettime.c
gidlist.lo: $(srcdir)/gidlist.c $(incdir)/compat/stdbool.h \
$(incdir)/sudo_alloc.h $(incdir)/sudo_compat.h \
$(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
@@ -530,6 +535,7 @@ ttysize.lo: $(srcdir)/ttysize.c $(incdir)/compat/stdbool.h \
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
$(top_builddir)/config.h
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/ttysize.c
utimes.lo: $(srcdir)/utimes.c $(incdir)/compat/utime.h $(incdir)/sudo_compat.h \
$(top_builddir)/config.h
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/utimes.c
utimens.lo: $(srcdir)/utimens.c $(incdir)/compat/timespec.h \
$(incdir)/compat/utime.h $(incdir)/sudo_compat.h \
$(top_builddir)/config.h
$(LIBTOOL) --mode=compile $(CC) -c -o $@ $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/utimens.c

View File

@@ -44,7 +44,9 @@
# include <mach/clock.h>
#endif
#include "sudoers.h"
#include "sudo_compat.h"
#include "sudo_debug.h"
#include "sudo_util.h"
/* On Linux, CLOCK_MONOTONIC does not run while suspended. */
#if defined(CLOCK_BOOTTIME)
@@ -55,9 +57,9 @@
#if defined(HAVE_CLOCK_GETTIME)
int
sudo_gettime_real(struct timespec *ts)
sudo_gettime_real_v1(struct timespec *ts)
{
debug_decl(sudo_gettime_real, SUDOERS_DEBUG_UTIL)
debug_decl(sudo_gettime_real, SUDO_DEBUG_UTIL)
if (clock_gettime(CLOCK_REALTIME, ts) == -1) {
struct timeval tv;
@@ -72,10 +74,10 @@ sudo_gettime_real(struct timespec *ts)
}
#else
int
sudo_gettime_real(struct timespec *ts)
sudo_gettime_real_v1(struct timespec *ts)
{
struct timeval tv;
debug_decl(sudo_gettime_real, SUDOERS_DEBUG_UTIL)
debug_decl(sudo_gettime_real, SUDO_DEBUG_UTIL)
if (gettimeofday(&tv, NULL) == -1)
debug_return_int(-1);
@@ -86,10 +88,10 @@ sudo_gettime_real(struct timespec *ts)
#if defined(HAVE_CLOCK_GETTIME) && defined(SUDO_CLOCK_MONOTONIC)
int
sudo_gettime_mono(struct timespec *ts)
sudo_gettime_mono_v1(struct timespec *ts)
{
static int has_monoclock = -1;
debug_decl(sudo_gettime_mono, SUDOERS_DEBUG_UTIL)
debug_decl(sudo_gettime_mono, SUDO_DEBUG_UTIL)
/* Check whether the kernel/libc actually supports CLOCK_MONOTONIC. */
# ifdef _SC_MONOTONIC_CLOCK
@@ -108,11 +110,11 @@ sudo_gettime_mono(struct timespec *ts)
}
#elif defined(__MACH__)
int
sudo_gettime_mono(struct timespec *ts)
sudo_gettime_mono_v1(struct timespec *ts)
{
uint64_t abstime, nsec;
static mach_timebase_info_data_t timebase_info;
debug_decl(sudo_gettime_mono, SUDOERS_DEBUG_UTIL)
debug_decl(sudo_gettime_mono, SUDO_DEBUG_UTIL)
if (timebase_info.denom == 0)
(void) mach_timebase_info(&timebase_info);
@@ -124,7 +126,7 @@ sudo_gettime_mono(struct timespec *ts)
}
#else
int
sudo_gettime_mono(struct timespec *ts)
sudo_gettime_mono_v1(struct timespec *ts)
{
/* No monotonic clock available, use wall clock. */
return sudo_gettime_real(ts);

View File

@@ -66,6 +66,8 @@ sudo_fatal_nodebug_v1
sudo_fatalx_nodebug_v1
sudo_get_ttysize_v1
sudo_gethostname_v1
sudo_gettime_mono_v1
sudo_gettime_real_v1
sudo_lbuf_append_quoted_v1
sudo_lbuf_append_v1
sudo_lbuf_destroy_v1

198
lib/util/utimens.c Normal file
View File

@@ -0,0 +1,198 @@
/*
* Copyright (c) 2015 Todd C. Miller <Todd.Miller@courtesan.com>
*
* 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.
*/
#include <config.h>
#if !defined(HAVE_FUTIMENS) || !defined(HAVE_UTIMENSAT)
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <stdio.h>
#include <errno.h>
#ifdef TIME_WITH_SYS_TIME
# include <time.h>
#endif
#ifndef HAVE_STRUCT_TIMESPEC
# include "compat/timespec.h"
#endif
#ifdef HAVE_UTIME_H
# include <utime.h>
#else
# include "compat/utime.h"
#endif
#include "sudo_compat.h"
#if !defined(HAVE_FUTIMES) && defined(HAVE_FUTIMESAT)
# define futimes(_f, _tv) futimesat(_f, NULL, _tv)
# define HAVE_FUTIMES
#endif
#if defined(HAVE_ST_MTIM)
# ifdef HAVE_ST__TIM
# define ATIME_TO_TIMEVAL(_x, _y) TIMESPEC_TO_TIMEVAL((_x), &(_y)->st_atim.st__tim)
# define MTIME_TO_TIMEVAL(_x, _y) TIMESPEC_TO_TIMEVAL((_x), &(_y)->st_mtim.st__tim)
# else
# define ATIME_TO_TIMEVAL(_x, _y) TIMESPEC_TO_TIMEVAL((_x), &(_y)->st_atim)
# define MTIME_TO_TIMEVAL(_x, _y) TIMESPEC_TO_TIMEVAL((_x), &(_y)->st_mtim)
# endif
#elif defined(HAVE_ST_MTIMESPEC)
# define ATIME_TO_TIMEVAL(_x, _y) TIMESPEC_TO_TIMEVAL((_x), &(_y)->st_atimespec)
# define MTIME_TO_TIMEVAL(_x, _y) TIMESPEC_TO_TIMEVAL((_x), &(_y)->st_mtimespec)
#else
# define ATIME_TO_TIMEVAL(_x, _y) do { (_x)->tv_sec = (_y)->st_atime; (_x)->tv_usec = 0; } while (0)
# define MTIME_TO_TIMEVAL(_x, _y) do { (_x)->tv_sec = (_y)->st_mtime; (_x)->tv_usec = 0; } while (0)
#endif /* HAVE_ST_MTIM */
/*
* Convert the pair of timespec structs passed to futimens() / utimensat()
* to a pair of timeval structs, handling UTIME_OMIT and UTIME_NOW.
* Returns 0 on success and -1 on failure (setting errno).
*/
static int
utimens_ts_to_tv(int fd, const char *file, const struct timespec *ts,
struct timeval *tv)
{
TIMESPEC_TO_TIMEVAL(&tv[0], &ts[0]);
TIMESPEC_TO_TIMEVAL(&tv[1], &ts[1]);
if (ts[0].tv_nsec == UTIME_OMIT || ts[1].tv_nsec == UTIME_OMIT) {
struct stat sb;
if (fd != -1) {
/* For futimens() */
if (fstat(fd, &sb) == -1)
return -1;
} else {
/* For utimensat() */
if (stat(file, &sb) == -1)
return -1;
}
if (ts[0].tv_nsec == UTIME_OMIT)
ATIME_TO_TIMEVAL(&tv[0], &sb);
if (ts[1].tv_nsec == UTIME_OMIT)
MTIME_TO_TIMEVAL(&tv[1], &sb);
}
if (ts[0].tv_nsec == UTIME_NOW || ts[1].tv_nsec == UTIME_NOW) {
struct timeval now;
if (gettimeofday(&now, NULL) == -1)
return -1;
if (ts[0].tv_nsec == UTIME_NOW)
tv[0] = now;
if (ts[1].tv_nsec == UTIME_NOW)
tv[1] = now;
}
return 0;
}
#if defined(HAVE_FUTIMES)
/*
* Emulate futimens() via futimes()
*/
int
sudo_futimens(int fd, const struct timespec *ts)
{
struct timeval tv[2], *times = NULL;
if (ts != NULL) {
if (utimens_ts_to_tv(fd, NULL, ts, tv) == -1)
return -1;
times = tv;
}
return futimes(fd, times);
}
#elif defined(HAVE_FUTIME)
/*
* Emulate futimens() via futime()
*/
int
sudo_futimens(int fd, const struct timeval *ts)
{
struct utimbuf utb, *times = NULL;
if (ts != NULL) {
struct timeval tv[2];
if (utimens_ts_to_tv(fd, NULL, ts, tv) == -1)
return -1;
utb.actime = (time_t)(tv[0].tv_sec + tv[0].tv_usec / 1000000);
utb.modtime = (time_t)(tv[1].tv_sec + tv[1].tv_usec / 1000000);
times = &utb;
}
return futime(fd, times);
}
#else
/*
* Nothing to do but fail.
*/
int
sudo_futimens(int fd, const struct timeval *ts)
{
errno = ENOSYS;
return -1;
}
#endif /* HAVE_FUTIMES */
#if defined(HAVE_UTIMES)
/*
* Emulate utimensat() via utimes()
*/
int
sudo_utimensat(int fd, const char *file, const struct timespec *ts, int flag)
{
struct timeval tv[2], *times = NULL;
if (fd != AT_FDCWD || flag != 0) {
errno = ENOTSUP;
return -1;
}
if (ts != NULL) {
if (utimens_ts_to_tv(-1, file, ts, tv) == -1)
return -1;
times = tv;
}
return utimes(file, times);
}
#else
/*
* Emulate utimensat() via utime()
*/
int
sudo_utimensat(int fd, const char *file, const struct timespec *ts, int flag)
{
struct utimbuf utb, *times = NULL;
if (fd != AT_FDCWD || flag != 0) {
errno = ENOTSUP;
return -1;
}
if (ts != NULL) {
struct timeval tv[2];
if (utimens_ts_to_tv(-1, file, ts, tv) == -1)
return -1;
utb.actime = (time_t)(tv[0].tv_sec + tv[0].tv_usec / 1000000);
utb.modtime = (time_t)(tv[1].tv_sec + tv[1].tv_usec / 1000000);
times = &utb;
}
return utime(file, times);
}
#endif /* !HAVE_UTIMES */
#endif /* !HAVE_FUTIMENS && !HAVE_UTIMENSAT */

View File

@@ -1,73 +0,0 @@
/*
* Copyright (c) 2004-2005, 2007, 2010-2011, 2013, 2014
* Todd C. Miller <Todd.Miller@courtesan.com>
*
* 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.
*/
#include <config.h>
#if !defined(HAVE_UTIMES) || (!defined(HAVE_FUTIMES) && !defined(HAVE_FUTIMESAT))
#include <sys/types.h>
#include <sys/time.h>
#include <stdio.h>
#ifdef TIME_WITH_SYS_TIME
# include <time.h>
#endif
#ifdef HAVE_UTIME_H
# include <utime.h>
#else
# include "compat/utime.h"
#endif
#include "sudo_compat.h"
#ifndef HAVE_UTIMES
/*
* Emulate utimes() via utime()
*/
int
sudo_utimes(const char *file, const struct timeval *times)
{
if (times != NULL) {
struct utimbuf utb;
utb.actime = (time_t)(times[0].tv_sec + times[0].tv_usec / 1000000);
utb.modtime = (time_t)(times[1].tv_sec + times[1].tv_usec / 1000000);
return utime(file, &utb);
} else
return utime(file, NULL);
}
#endif /* !HAVE_UTIMES */
#ifdef HAVE_FUTIME
/*
* Emulate futimes() via futime()
*/
int
sudo_futimes(int fd, const struct timeval *times)
{
if (times != NULL) {
struct utimbuf utb;
utb.actime = (time_t)(times[0].tv_sec + times[0].tv_usec / 1000000);
utb.modtime = (time_t)(times[1].tv_sec + times[1].tv_usec / 1000000);
return futime(fd, &utb);
} else
return futime(fd, NULL);
}
#endif /* HAVE_FUTIME */
#endif /* !HAVE_UTIMES || (!HAVE_FUTIMES && !HAVE_FUTIMESAT) */

View File

@@ -70,7 +70,7 @@ sub mkdep {
$makefile =~ s:\@SUDOERS_OBJS\@:bsm_audit.lo linux_audit.lo ldap.lo solaris_audit.lo sssd.lo:;
# XXX - fill in AUTH_OBJS from contents of the auth dir instead
$makefile =~ s:\@AUTH_OBJS\@:afs.lo aix_auth.lo bsdauth.lo dce.lo fwtk.lo getspwuid.lo kerb5.lo pam.lo passwd.lo rfc1938.lo secureware.lo securid5.lo sia.lo:;
$makefile =~ s:\@LTLIBOBJS\@:closefrom.lo fnmatch.lo getaddrinfo.lo getcwd.lo getgrouplist.lo getline.lo getopt_long.lo glob.lo inet_ntop_lo inet_pton.lo isblank.lo memrchr.lo memset_s.lo mksiglist.lo mksigname.lo mktemp.lo pw_dup.lo sha2.lo sig2str.lo siglist.lo signame.lo snprintf.lo strlcat.lo strlcpy.lo strsignal.lo strtonum.lo utimes.lo:;
$makefile =~ s:\@LTLIBOBJS\@:closefrom.lo fnmatch.lo getaddrinfo.lo getcwd.lo getgrouplist.lo getline.lo getopt_long.lo glob.lo inet_ntop_lo inet_pton.lo isblank.lo memrchr.lo memset_s.lo mksiglist.lo mksigname.lo mktemp.lo pw_dup.lo sha2.lo sig2str.lo siglist.lo signame.lo snprintf.lo strlcat.lo strlcpy.lo strsignal.lo strtonum.lo utimens.lo:;
# Parse OBJS lines
my %objs;

View File

@@ -143,7 +143,7 @@ LIBPARSESUDOERS_OBJS = alias.lo audit.lo base64.lo defaults.lo hexchar.lo \
toke_util.lo
SUDOERS_OBJS = $(AUTH_OBJS) boottime.lo check.lo env.lo find_path.lo \
gettime.lo goodpath.lo group_plugin.lo interfaces.lo iolog.lo \
goodpath.lo group_plugin.lo interfaces.lo iolog.lo \
iolog_path.lo locale.lo logging.lo logwrap.lo parse.lo \
policy.lo prompt.lo set_perms.lo sudo_nss.lo sudoers.lo \
timestamp.lo @SUDOERS_OBJS@
@@ -654,16 +654,6 @@ getspwuid.lo: $(srcdir)/getspwuid.c $(devdir)/def_data.h \
$(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
$(top_builddir)/config.h $(top_builddir)/pathnames.h
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/getspwuid.c
gettime.lo: $(srcdir)/gettime.c $(devdir)/def_data.h \
$(incdir)/compat/stdbool.h $(incdir)/compat/timespec.h \
$(incdir)/sudo_alloc.h $(incdir)/sudo_compat.h \
$(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
$(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
$(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h \
$(incdir)/sudo_util.h $(srcdir)/defaults.h $(srcdir)/logging.h \
$(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
$(top_builddir)/config.h $(top_builddir)/pathnames.h
$(LIBTOOL) --mode=compile $(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/gettime.c
goodpath.lo: $(srcdir)/goodpath.c $(devdir)/def_data.h \
$(incdir)/compat/stdbool.h $(incdir)/sudo_alloc.h \
$(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
@@ -1091,14 +1081,14 @@ tsgetgrpw.o: $(srcdir)/tsgetgrpw.c $(devdir)/def_data.h \
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/tsgetgrpw.c
visudo.o: $(srcdir)/visudo.c $(devdir)/def_data.h $(devdir)/gram.h \
$(incdir)/compat/getopt.h $(incdir)/compat/stdbool.h \
$(incdir)/sudo_alloc.h $(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
$(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
$(incdir)/sudo_gettext.h $(incdir)/sudo_plugin.h \
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/defaults.h \
$(srcdir)/logging.h $(srcdir)/parse.h $(srcdir)/redblack.h \
$(srcdir)/sudo_nss.h $(srcdir)/sudoers.h $(srcdir)/sudoers_debug.h \
$(srcdir)/sudoers_version.h $(top_builddir)/config.h \
$(top_builddir)/pathnames.h
$(incdir)/compat/timespec.h $(incdir)/sudo_alloc.h \
$(incdir)/sudo_compat.h $(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
$(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
$(incdir)/sudo_plugin.h $(incdir)/sudo_queue.h $(incdir)/sudo_util.h \
$(srcdir)/defaults.h $(srcdir)/logging.h $(srcdir)/parse.h \
$(srcdir)/redblack.h $(srcdir)/sudo_nss.h $(srcdir)/sudoers.h \
$(srcdir)/sudoers_debug.h $(srcdir)/sudoers_version.h \
$(top_builddir)/config.h $(top_builddir)/pathnames.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/visudo.c
visudo_json.o: $(srcdir)/visudo_json.c $(devdir)/def_data.h $(devdir)/gram.h \
$(incdir)/compat/stdbool.h $(incdir)/sudo_alloc.h \

View File

@@ -59,13 +59,13 @@
#include "sudoers.h"
/*
* Fill in a struct timeval with the time the system booted.
* Fill in a struct timespec with the time the system booted.
* Returns 1 on success and 0 on failure.
*/
#if defined(__linux__)
bool
get_boottime(struct timeval *tv)
get_boottime(struct timespec *ts)
{
char *line = NULL;
size_t linesize = 0;
@@ -81,8 +81,8 @@ get_boottime(struct timeval *tv)
if (strncmp(line, "btime ", 6) == 0) {
long long llval = strtonum(line + 6, 1, LLONG_MAX, NULL);
if (llval > 0) {
tv->tv_sec = (time_t)llval;
tv->tv_usec = 0;
ts->tv_sec = (time_t)llval;
ts->tv_nsec = 0;
found = true;
break;
}
@@ -98,17 +98,20 @@ get_boottime(struct timeval *tv)
#elif defined(HAVE_SYSCTL) && defined(KERN_BOOTTIME)
bool
get_boottime(struct timeval *tv)
get_boottime(struct timespec *ts)
{
size_t size;
int mib[2];
struct timeval tv;
debug_decl(get_boottime, SUDOERS_DEBUG_UTIL)
mib[0] = CTL_KERN;
mib[1] = KERN_BOOTTIME;
size = sizeof(*tv);
if (sysctl(mib, 2, tv, &size, NULL, 0) != -1)
size = sizeof(tv);
if (sysctl(mib, 2, &tv, &size, NULL, 0) != -1) {
TIMEVAL_TO_TIMESPEC(&tv, ts);
debug_return_bool(true);
}
debug_return_bool(false);
}
@@ -116,7 +119,7 @@ get_boottime(struct timeval *tv)
#elif defined(HAVE_GETUTXID)
bool
get_boottime(struct timeval *tv)
get_boottime(struct timespec *ts)
{
struct utmpx *ut, key;
debug_decl(get_boottime, SUDOERS_DEBUG_UTIL)
@@ -124,10 +127,8 @@ get_boottime(struct timeval *tv)
memset(&key, 0, sizeof(key));
key.ut_type = BOOT_TIME;
setutxent();
if ((ut = getutxid(&key)) != NULL) {
tv->tv_sec = ut->ut_tv.tv_sec;
tv->tv_usec = ut->ut_tv.tv_usec;
}
if ((ut = getutxid(&key)) != NULL)
TIMEVAL_TO_TIMESPEC(&ut->ut_tv, ts);
endutxent();
debug_return_bool(ut != NULL);
}
@@ -135,7 +136,7 @@ get_boottime(struct timeval *tv)
#elif defined(HAVE_GETUTID)
bool
get_boottime(struct timeval *tv)
get_boottime(struct timespec *ts)
{
struct utmp *ut, key;
debug_decl(get_boottime, SUDOERS_DEBUG_UTIL)
@@ -144,8 +145,8 @@ get_boottime(struct timeval *tv)
key.ut_type = BOOT_TIME;
setutent();
if ((ut = getutid(&key)) != NULL) {
tv->tv_sec = ut->ut_time;
tv->tv_usec = 0;
ts->tv_sec = ut->ut_time;
ts->tv_nsec = 0;
}
endutent();
debug_return_bool(ut != NULL);
@@ -154,7 +155,7 @@ get_boottime(struct timeval *tv)
#else
bool
get_boottime(struct timeval *tv)
get_boottime(struct timespec *ts)
{
debug_decl(get_boottime, SUDOERS_DEBUG_UTIL)
debug_return_bool(false);

View File

@@ -239,10 +239,6 @@ char *expand_prompt(const char *old_prompt, const char *auth_user);
void remove_timestamp(bool);
bool set_lectured(void);
/* gettime.c */
int sudo_gettime_real(struct timespec *ts);
int sudo_gettime_mono(struct timespec *ts);
/* sudo_auth.c */
bool sudo_auth_needs_end_session(void);
int verify_user(struct passwd *pw, char *prompt, int validated);
@@ -315,7 +311,7 @@ void sudo_setspent(void);
char *get_timestr(time_t, int);
/* boottime.c */
bool get_boottime(struct timeval *);
bool get_boottime(struct timespec *);
/* iolog.c */
bool io_nextid(char *iolog_dir, char *iolog_dir_fallback, char sessid[7]);

View File

@@ -444,10 +444,10 @@ timestamp_status(struct passwd *pw)
/* Ignore and clear time stamp file if mtime predates boot time. */
if (fstat(fd, &sb) == 0) {
struct timeval boottime, mtime;
struct timespec boottime, mtime;
mtim_get(&sb, &mtime);
if (get_boottime(&boottime) && sudo_timevalcmp(&mtime, &boottime, <)) {
mtim_get(&sb, mtime);
if (get_boottime(&boottime) && sudo_timespeccmp(&mtime, &boottime, <)) {
ignore_result(ftruncate(fd, (off_t)0));
status = TS_MISSING;
goto done;

View File

@@ -70,6 +70,9 @@
#ifdef TIME_WITH_SYS_TIME
# include <time.h>
#endif
#ifndef HAVE_STRUCT_TIMESPEC
# include "compat/timespec.h"
#endif
#include "sudoers.h"
#include "parse.h"
@@ -321,8 +324,8 @@ edit_sudoers(struct sudoersfile *sp, char *editor, char *args, int lineno)
char *cp; /* scratch char pointer */
char buf[PATH_MAX*2]; /* buffer used for copying files */
char linestr[64]; /* string version of lineno */
struct timeval tv, times[2]; /* time before and after edit */
struct timeval orig_mtim; /* starting mtime of sudoers file */
struct timespec ts, times[2]; /* time before and after edit */
struct timespec orig_mtim; /* starting mtime of sudoers file */
off_t orig_size; /* starting size of sudoers file */
ssize_t nread; /* number of bytes read */
struct stat sb; /* stat buffer */
@@ -332,7 +335,7 @@ edit_sudoers(struct sudoersfile *sp, char *editor, char *args, int lineno)
if (fstat(sp->fd, &sb) == -1)
sudo_fatal(U_("unable to stat %s"), sp->path);
orig_size = sb.st_size;
mtim_get(&sb, &orig_mtim);
mtim_get(&sb, orig_mtim);
/* Create the temp file if needed and set timestamp. */
if (sp->tpath == NULL) {
@@ -358,8 +361,8 @@ edit_sudoers(struct sudoersfile *sp, char *editor, char *args, int lineno)
(void) close(tfd);
}
times[0].tv_sec = times[1].tv_sec = orig_mtim.tv_sec;
times[0].tv_usec = times[1].tv_usec = orig_mtim.tv_usec;
(void) utimes(sp->tpath, times);
times[0].tv_nsec = times[1].tv_nsec = orig_mtim.tv_nsec;
(void) utimensat(AT_FDCWD, sp->tpath, times, 0);
/* Does the editor support +lineno? */
if (lineno > 0)
@@ -429,13 +432,13 @@ edit_sudoers(struct sudoersfile *sp, char *editor, char *args, int lineno)
* XPG4 specifies that vi's exit value is a function of the
* number of errors during editing (?!?!).
*/
if (gettimeofday(&times[0], NULL) == -1) {
if (sudo_gettime_real(&times[0]) == -1) {
sudo_warn(U_("unable to read the clock"));
goto done;
}
if (run_command(editor, av) != -1) {
if (gettimeofday(&times[1], NULL) == -1) {
if (sudo_gettime_real(&times[1]) == -1) {
sudo_warn(U_("unable to read the clock"));
goto done;
}
@@ -460,13 +463,13 @@ edit_sudoers(struct sudoersfile *sp, char *editor, char *args, int lineno)
/* Set modified bit if the user changed the file. */
modified = true;
mtim_get(&sb, &tv);
if (orig_size == sb.st_size && sudo_timevalcmp(&orig_mtim, &tv, ==)) {
mtim_get(&sb, ts);
if (orig_size == sb.st_size && sudo_timespeccmp(&orig_mtim, &ts, ==)) {
/*
* If mtime and size match but the user spent no measurable
* time in the editor we can't tell if the file was changed.
*/
if (sudo_timevalcmp(&times[0], &times[1], !=))
if (sudo_timespeccmp(&times[0], &times[1], !=))
modified = false;
}

View File

@@ -349,12 +349,12 @@ sudo.o: $(srcdir)/sudo.c $(incdir)/compat/stdbool.h $(incdir)/sudo_alloc.h \
$(top_builddir)/pathnames.h ./sudo_usage.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/sudo.c
sudo_edit.o: $(srcdir)/sudo_edit.c $(incdir)/compat/stdbool.h \
$(incdir)/sudo_alloc.h $(incdir)/sudo_compat.h \
$(incdir)/sudo_conf.h $(incdir)/sudo_debug.h \
$(incdir)/sudo_fatal.h $(incdir)/sudo_gettext.h \
$(incdir)/sudo_queue.h $(incdir)/sudo_util.h $(srcdir)/sudo.h \
$(srcdir)/sudo_exec.h $(top_builddir)/config.h \
$(top_builddir)/pathnames.h
$(incdir)/compat/timespec.h $(incdir)/sudo_alloc.h \
$(incdir)/sudo_compat.h $(incdir)/sudo_conf.h \
$(incdir)/sudo_debug.h $(incdir)/sudo_fatal.h \
$(incdir)/sudo_gettext.h $(incdir)/sudo_queue.h \
$(incdir)/sudo_util.h $(srcdir)/sudo.h $(srcdir)/sudo_exec.h \
$(top_builddir)/config.h $(top_builddir)/pathnames.h
$(CC) -c $(CPPFLAGS) $(CFLAGS) $(PIE_CFLAGS) $(SSP_CFLAGS) $(DEFS) $(srcdir)/sudo_edit.c
sudo_noexec.lo: $(srcdir)/sudo_noexec.c $(incdir)/sudo_compat.h \
$(top_builddir)/config.h

View File

@@ -121,7 +121,7 @@ sesh_sudoedit(int argc, char *argv[])
int fd_src, fd_dst, i, oflags_dst, post, ret = SESH_ERR_FAILURE;
ssize_t nread, nwritten;
struct stat sb;
struct timeval times[2];
struct timespec times[2];
char buf[BUFSIZ];
debug_decl(sesh_sudoedit, SUDO_DEBUG_EDIT)
@@ -206,14 +206,13 @@ sesh_sudoedit(int argc, char *argv[])
if (fd_src == -1 || fstat(fd_src, &sb) != 0)
memset(&sb, 0, sizeof(sb));
/* Make mtime on temp file match src. */
mtim_get(&sb, &times[0]);
mtim_get(&sb, times[0]);
times[1].tv_sec = times[0].tv_sec;
times[1].tv_usec = times[0].tv_usec;
#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIME)
(void) futimes(fd_dst, times);
#else
(void) utimes(path_dst, times);
#endif
times[1].tv_nsec = times[0].tv_nsec;
if (futimens(fd_dst, times) == -1) {
if (utimensat(AT_FDCWD, path_dst, times, 0) == -1)
sudo_warn("%s", path_dst);
}
}
close(fd_dst);
}

View File

@@ -48,6 +48,9 @@
#ifdef TIME_WITH_SYS_TIME
# include <time.h>
#endif
#ifndef HAVE_STRUCT_TIMESPEC
# include "compat/timespec.h"
#endif
#ifdef HAVE_SELINUX
# include <selinux/selinux.h>
#endif
@@ -63,7 +66,7 @@
struct tempfile {
char *tfile;
char *ofile;
struct timeval omtim;
struct timespec omtim;
off_t osize;
};
@@ -174,7 +177,7 @@ sudo_edit_create_tfiles(struct command_details *command_details,
int i, j, tfd, ofd, rc;
char buf[BUFSIZ];
ssize_t nwritten, nread;
struct timeval times[2];
struct timespec times[2];
struct stat sb;
debug_decl(sudo_edit_create_tfiles, SUDO_DEBUG_EDIT)
@@ -207,7 +210,7 @@ sudo_edit_create_tfiles(struct command_details *command_details,
}
tf[j].ofile = files[i];
tf[j].osize = sb.st_size;
mtim_get(&sb, &tf[j].omtim);
mtim_get(&sb, tf[j].omtim);
sudo_debug_printf(SUDO_DEBUG_INFO|SUDO_DEBUG_LINENO,
"seteuid(%u)", user_details.uid);
if (seteuid(user_details.uid) != 0)
@@ -239,19 +242,18 @@ sudo_edit_create_tfiles(struct command_details *command_details,
* We always update the stashed mtime because the time
* resolution of the filesystem the temporary file is on may
* not match that of the filesystem where the file to be edited
* resides. It is OK if futimes() fails since we only use the
* resides. It is OK if futimens() fails since we only use the
* info to determine whether or not a file has been modified.
*/
times[0].tv_sec = times[1].tv_sec = tf[j].omtim.tv_sec;
times[0].tv_usec = times[1].tv_usec = tf[j].omtim.tv_usec;
#if defined(HAVE_FUTIMES) || defined(HAVE_FUTIME)
(void) futimes(tfd, times);
#else
(void) utimes(tf[j].tfile, times);
#endif
times[0].tv_nsec = times[1].tv_nsec = tf[j].omtim.tv_nsec;
if (futimens(tfd, times) == -1) {
if (utimensat(AT_FDCWD, tf[j].tfile, times, 0) == -1)
sudo_warn("%s", tf[j].tfile);
}
rc = fstat(tfd, &sb);
if (!rc)
mtim_get(&sb, &tf[j].omtim);
mtim_get(&sb, tf[j].omtim);
close(tfd);
j++;
}
@@ -264,12 +266,12 @@ sudo_edit_create_tfiles(struct command_details *command_details,
*/
static int
sudo_edit_copy_tfiles(struct command_details *command_details,
struct tempfile *tf, int nfiles, struct timeval *times)
struct tempfile *tf, int nfiles, struct timespec *times)
{
int i, tfd, ofd, rc, errors = 0;
char buf[BUFSIZ];
ssize_t nwritten, nread;
struct timeval tv;
struct timespec ts;
struct stat sb;
debug_decl(sudo_edit_copy_tfiles, SUDO_DEBUG_EDIT)
@@ -298,13 +300,13 @@ sudo_edit_copy_tfiles(struct command_details *command_details,
errors++;
continue;
}
mtim_get(&sb, &tv);
if (tf[i].osize == sb.st_size && sudo_timevalcmp(&tf[i].omtim, &tv, ==)) {
mtim_get(&sb, ts);
if (tf[i].osize == sb.st_size && sudo_timespeccmp(&tf[i].omtim, &ts, ==)) {
/*
* If mtime and size match but the user spent no measurable
* time in the editor we can't tell if the file was changed.
*/
if (sudo_timevalcmp(&times[0], &times[1], !=)) {
if (sudo_timespeccmp(&times[0], &times[1], !=)) {
sudo_warnx(U_("%s unchanged"), tf[i].ofile);
unlink(tf[i].tfile);
close(tfd);
@@ -387,7 +389,7 @@ selinux_edit_create_tfiles(struct command_details *command_details,
if (stat(ofile, &sb) == -1)
memset(&sb, 0, sizeof(sb)); /* new file */
tf[i].osize = sb.st_size;
mtim_get(&sb, &tf[i].omtim);
mtim_get(&sb, tf[i].omtim);
/*
* The temp file must be created by the sesh helper,
* which uses O_EXCL | O_NOFOLLOW to make this safe.
@@ -442,12 +444,12 @@ selinux_edit_create_tfiles(struct command_details *command_details,
static int
selinux_edit_copy_tfiles(struct command_details *command_details,
struct tempfile *tf, int nfiles, struct timeval *times)
struct tempfile *tf, int nfiles, struct timespec *times)
{
char **sesh_args, **sesh_ap;
int i, rc, sesh_nargs, rval = 1;
struct command_details saved_command_details;
struct timeval tv;
struct timespec ts;
struct stat sb;
debug_decl(selinux_edit_copy_tfiles, SUDO_DEBUG_EDIT)
@@ -473,13 +475,13 @@ selinux_edit_copy_tfiles(struct command_details *command_details,
/* Construct args for sesh -e 1 */
for (i = 0; i < nfiles; i++) {
if (stat(tf[i].tfile, &sb) == 0) {
mtim_get(&sb, &tv);
if (tf[i].osize == sb.st_size && sudo_timevalcmp(&tf[i].omtim, &tv, ==)) {
mtim_get(&sb, ts);
if (tf[i].osize == sb.st_size && sudo_timespeccmp(&tf[i].omtim, &ts, ==)) {
/*
* If mtime and size match but the user spent no measurable
* time in the editor we can't tell if the file was changed.
*/
if (sudo_timevalcmp(&times[0], &times[1], !=)) {
if (sudo_timespeccmp(&times[0], &times[1], !=)) {
sudo_warnx(U_("%s unchanged"), tf[i].ofile);
unlink(tf[i].tfile);
continue;
@@ -537,7 +539,7 @@ sudo_edit(struct command_details *command_details)
char **nargv = NULL, **ap, **files = NULL;
int errors, i, ac, nargc, rval;
int editor_argc = 0, nfiles = 0;
struct timeval times[2];
struct timespec times[2];
struct tempfile *tf = NULL;
debug_decl(sudo_edit, SUDO_DEBUG_EDIT)
@@ -600,7 +602,7 @@ sudo_edit(struct command_details *command_details)
* Run the editor with the invoking user's creds,
* keeping track of the time spent in the editor.
*/
if (gettimeofday(&times[0], NULL) == -1) {
if (sudo_gettime_real(&times[0]) == -1) {
sudo_warn(U_("unable to read the clock"));
goto cleanup;
}
@@ -613,7 +615,7 @@ sudo_edit(struct command_details *command_details)
command_details->groups = user_details.groups;
command_details->argv = nargv;
rval = run_command(command_details);
if (gettimeofday(&times[1], NULL) == -1) {
if (sudo_gettime_real(&times[1]) == -1) {
sudo_warn(U_("unable to read the clock"));
goto cleanup;
}