diff options
author | Mike Gilbert <floppym@gentoo.org> | 2018-05-10 15:10:48 -0400 |
---|---|---|
committer | Sven Eden <yamakuzure@gmx.net> | 2018-08-24 16:47:08 +0200 |
commit | caa677e09fc31a31404ac8c65c6e621bdf28209b (patch) | |
tree | 0aac2be5f260f90d7878d9a46841ad2e7a2ad2d5 /src | |
parent | c8a26c0f044b3e57488483c0e0a17516ed96df85 (diff) |
basic: timezone_is_valid: check for magic bytes "TZif"
Fixes: https://github.com/systemd/systemd/issues/8905
Diffstat (limited to 'src')
-rw-r--r-- | src/basic/time-util.c | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/src/basic/time-util.c b/src/basic/time-util.c index f29e2bdb0..e9838a82a 100644 --- a/src/basic/time-util.c +++ b/src/basic/time-util.c @@ -21,11 +21,13 @@ #include "fd-util.h" #include "fileio.h" #include "fs-util.h" +//#include "io-util.h" #include "log.h" #include "macro.h" #include "parse-util.h" #include "path-util.h" //#include "process-util.h" +//#include "stat-util.h" #include "string-util.h" #include "strv.h" #include "time-util.h" @@ -1291,7 +1293,9 @@ int get_timezones(char ***ret) { bool timezone_is_valid(const char *name) { bool slash = false; const char *p, *t; - struct stat st; + _cleanup_close_ int fd = -1; + char buf[4]; + int r; if (isempty(name)) return false; @@ -1320,11 +1324,30 @@ bool timezone_is_valid(const char *name) { return false; t = strjoina("/usr/share/zoneinfo/", name); - if (stat(t, &st) < 0) + + fd = open(t, O_RDONLY|O_CLOEXEC); + if (fd < 0) { + log_debug_errno(errno, "Failed to open timezone file '%s': %m", t); + return false; + } + + r = fd_verify_regular(fd); + if (r < 0) { + log_debug_errno(r, "Timezone file '%s' is not a regular file: %m", t); return false; + } + + r = loop_read_exact(fd, buf, 4, false); + if (r < 0) { + log_debug_errno(r, "Failed to read from timezone file '%s': %m", t); + return false; + } - if (!S_ISREG(st.st_mode)) + /* Magic from tzfile(5) */ + if (memcmp(buf, "TZif", 4) != 0) { + log_debug("Timezone file '%s' has wrong magic bytes", t); return false; + } return true; } |