Yesterday’s changes inadvertently removed some support for the rarely-used SUPPRESS_TZDIR option. * localtime.c (SUPPRESS_TZDIR): Default to 0. (tzloadbody, tzset_unlocked) [SUPPRESS_TZDIR]: Suppress TZDIR in a few recently-added places. Prefer if to #if if either will do. --- localtime.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/localtime.c b/localtime.c index 32013247..67500312 100644 --- a/localtime.c +++ b/localtime.c @@ -209,6 +209,13 @@ static char const *utc = etc_utc + sizeof "Etc/" - 1; # define TZDEFRULESTRING ",M3.2.0,M11.1.0" #endif +/* If compiled with -DSUPPRESS_TZDIR, do not prepend TZDIR to relative TZ. + This is intended for specialized applications only, due to its + security implications. */ +#ifndef SUPPRESS_TZDIR +# define SUPPRESS_TZDIR 0 +#endif + /* Limit to time zone abbreviation length in proleptic TZ strings. This is distinct from TZ_MAX_CHARS, which limits TZif file contents. It defaults to 254, not 255, so that desigidx_type can be an unsigned char. @@ -581,7 +588,8 @@ tzloadbody(char const *name, struct state *sp, char tzloadflags, /* If the program is privileged, NAME is TZDEFAULT or subsidiary to TZDIR. Also, NAME is not a device. */ if (name[0] == '/' && strcmp(name, TZDEFAULT) != 0) { - if (strncmp(relname, tzdirslash, sizeof tzdirslash) == 0) + if (!SUPPRESS_TZDIR + && strncmp(relname, tzdirslash, sizeof tzdirslash) == 0) for (relname += sizeof tzdirslash; *relname == '/'; relname++) continue; else if (issetugid()) @@ -615,11 +623,7 @@ tzloadbody(char const *name, struct state *sp, char tzloadflags, } } -#ifdef SUPPRESS_TZDIR - /* Do not prepend TZDIR. This is intended for specialized - applications only, due to its security implications. */ -#else - if (name[0] != '/') { + if (!SUPPRESS_TZDIR && name[0] != '/') { if (sizeof lsp->fullname - sizeof tzdirslash <= strnlen(name, sizeof lsp->fullname - sizeof tzdirslash)) return ENAMETOOLONG; @@ -631,7 +635,6 @@ tzloadbody(char const *name, struct state *sp, char tzloadflags, strcpy(lsp->fullname + sizeof tzdirslash, name); name = lsp->fullname; } -#endif fid = open(name, (O_RDONLY | O_BINARY | O_CLOEXEC | O_CLOFORK | O_IGNORE_CTTY | O_NOCTTY)); @@ -1529,7 +1532,7 @@ tzset_unlocked(void) /* Abbreviate a string like "/usr/share/zoneinfo/America/Los_Angeles" to its shorter equivalent "America/Los_Angeles". */ - if (sizeof tzdirslash < namelen + if (!SUPPRESS_TZDIR && sizeof tzdirslash < namelen && memcmp(name, tzdirslash, sizeof tzdirslash) == 0) { char const *p = name + sizeof tzdirslash; while (*p == '/') -- 2.48.1