mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-11-22 19:41:04 +01:00
tzcode: Implement timezone change detection
Implement optional timezone change detection for local time libc functions. This is disabled by default; set WITH_DETECT_TZ_CHANGES to build it. Reviewed By: imp Sponsored by: NetApp, Inc. Sponsored by: Klara, Inc. X-NetApp-PR: #47 Differential Revision: https://reviews.freebsd.org/D30183
This commit is contained in:
parent
b9df18d6e8
commit
ddedf2a11e
@ -354,6 +354,45 @@ settzname(void)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DETECT_TZ_CHANGES
|
||||
/*
|
||||
* Determine if there's a change in the timezone since the last time we checked.
|
||||
* Returns: -1 on error
|
||||
* 0 if the timezone has not changed
|
||||
* 1 if the timezone has changed
|
||||
*/
|
||||
static int
|
||||
change_in_tz(const char *name)
|
||||
{
|
||||
static char old_name[PATH_MAX];
|
||||
static struct stat old_sb;
|
||||
struct stat sb;
|
||||
int error;
|
||||
|
||||
error = stat(name, &sb);
|
||||
if (error != 0)
|
||||
return -1;
|
||||
|
||||
if (strcmp(name, old_name) != 0) {
|
||||
strlcpy(old_name, name, sizeof(old_name));
|
||||
old_sb = sb;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (sb.st_dev != old_sb.st_dev ||
|
||||
sb.st_ino != old_sb.st_ino ||
|
||||
sb.st_ctime != old_sb.st_ctime ||
|
||||
sb.st_mtime != old_sb.st_mtime) {
|
||||
old_sb = sb;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else /* !DETECT_TZ_CHANGES */
|
||||
#define change_in_tz(X) 0
|
||||
#endif /* !DETECT_TZ_CHANGES */
|
||||
|
||||
static int
|
||||
differ_by_repeat(const time_t t1, const time_t t0)
|
||||
{
|
||||
@ -379,6 +418,7 @@ register const int doextend;
|
||||
int stored;
|
||||
int nread;
|
||||
int res;
|
||||
int ret;
|
||||
union {
|
||||
struct tzhead tzhead;
|
||||
char buf[2 * sizeof(struct tzhead) +
|
||||
@ -427,6 +467,22 @@ register const int doextend;
|
||||
(void) strcat(fullname, name);
|
||||
name = fullname;
|
||||
}
|
||||
if (doextend == TRUE) {
|
||||
/*
|
||||
* Detect if the timezone file has changed. Check
|
||||
* 'doextend' to ignore TZDEFRULES; the change_in_tz()
|
||||
* function can only keep state for a single file.
|
||||
*/
|
||||
ret = change_in_tz(name);
|
||||
if (ret <= 0) {
|
||||
/*
|
||||
* Returns -1 if there was an error,
|
||||
* and 0 if the timezone had not changed.
|
||||
*/
|
||||
free(fullname);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if ((fid = _open(name, OPEN_MODE)) == -1) {
|
||||
free(fullname);
|
||||
return -1;
|
||||
@ -1209,12 +1265,43 @@ gmtload(struct state *const sp)
|
||||
(void) tzparse(gmt, sp, TRUE);
|
||||
}
|
||||
|
||||
#ifdef DETECT_TZ_CHANGES
|
||||
static int
|
||||
recheck_tzdata()
|
||||
{
|
||||
static time_t last_checked;
|
||||
struct timespec now;
|
||||
time_t current_time;
|
||||
int error;
|
||||
|
||||
/*
|
||||
* We want to recheck the timezone file every 61 sec.
|
||||
*/
|
||||
error = clock_gettime(CLOCK_MONOTONIC, &now);
|
||||
if (error <= 0) {
|
||||
/* XXX: Can we somehow report this? */
|
||||
return 0;
|
||||
}
|
||||
|
||||
current_time = now.tv_sec;
|
||||
if ((current_time - last_checked > 61) ||
|
||||
(last_checked > current_time)) {
|
||||
last_checked = current_time;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else /* !DETECT_TZ_CHANGES */
|
||||
#define recheck_tzdata() 0
|
||||
#endif /* !DETECT_TZ_CHANGES */
|
||||
|
||||
static void
|
||||
tzsetwall_basic(int rdlocked)
|
||||
{
|
||||
if (!rdlocked)
|
||||
_RWLOCK_RDLOCK(&lcl_rwlock);
|
||||
if (lcl_is_set < 0) {
|
||||
if (lcl_is_set < 0 && recheck_tzdata() == 0) {
|
||||
if (!rdlocked)
|
||||
_RWLOCK_UNLOCK(&lcl_rwlock);
|
||||
return;
|
||||
|
@ -12,6 +12,10 @@ CFLAGS+= -I${SRCTOP}/contrib/tzcode/stdtime -I${LIBC_SRCTOP}/stdtime
|
||||
|
||||
CFLAGS.localtime.c= -fwrapv
|
||||
|
||||
.if ${MK_DETECT_TZ_CHANGES} != "no"
|
||||
CFLAGS+= -DDETECT_TZ_CHANGES
|
||||
.endif
|
||||
|
||||
MAN+= ctime.3 strftime.3 strptime.3 time2posix.3
|
||||
MAN+= tzfile.5
|
||||
|
||||
|
@ -196,6 +196,7 @@ __DEFAULT_NO_OPTIONS = \
|
||||
BHYVE_SNAPSHOT \
|
||||
CLANG_EXTRAS \
|
||||
CLANG_FORMAT \
|
||||
DETECT_TZ_CHANGES \
|
||||
DTRACE_TESTS \
|
||||
EXPERIMENTAL \
|
||||
HESIOD \
|
||||
|
2
tools/build/options/WITH_DETECT_TZ_CHANGES
Normal file
2
tools/build/options/WITH_DETECT_TZ_CHANGES
Normal file
@ -0,0 +1,2 @@
|
||||
.\" $FreeBSD$
|
||||
Make the time handling code detect changes to the timezone files.
|
Loading…
Reference in New Issue
Block a user