From 0e7723e75fe7432974b3f6995b0b72b5c0c1184c Mon Sep 17 00:00:00 2001 From: Craig Barnes Date: Sun, 23 Aug 2020 03:08:35 +0100 Subject: [PATCH] csi: avoid using memcmp() to compare timespec structs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This struct may contain padding bytes, whose values are indeterminate after any store operation[1]. It may also contain unnamed members, whose values are always indeterminate[2]. Using memcmp() isn't a reliable way to compare structs where either of these may be present. [1]: ISO/IEC 9899:1999 §6.2.6.1, paragraph 6 [2]: ISO/IEC 9899:1999 §6.7.8, paragraph 9 See also: * https://wiki.sei.cmu.edu/confluence/display/c/EXP42-C.+Do+not+compare+padding+data * https://sourceware.org/git/?p=glibc.git;a=blob;f=time/bits/types/struct_timespec.h;hb=756c306502498f9 --- csi.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/csi.c b/csi.c index 657f6628..53a90805 100644 --- a/csi.c +++ b/csi.c @@ -544,6 +544,12 @@ decrst(struct terminal *term, unsigned param) decset_decrst(term, param, false); } +static bool +timespecs_equal(const struct timespec *a, const struct timespec *b) +{ + return a->tv_sec == b->tv_sec && a->tv_nsec == b->tv_nsec; +} + static void xtsave(struct terminal *term, unsigned param) { @@ -561,10 +567,10 @@ xtsave(struct terminal *term, unsigned param) if (timerfd_gettime(term->cursor_blink.fd, ¤t_value) < 0) LOG_WARN("xtsave: failed to read cursor blink timer: %s", strerror(errno)); else { - const struct timespec zero = {}; + const struct timespec zero = {.tv_sec = 0, .tv_nsec = 0}; term->xtsave.cursor_blink = - !(memcmp(¤t_value.it_interval, &zero, sizeof(zero)) == 0 && - memcmp(¤t_value.it_value, &zero, sizeof(zero)) == 0); + !(timespecs_equal(¤t_value.it_interval, &zero) && + timespecs_equal(¤t_value.it_value, &zero)); } break; }