diff --git a/src/backend_chromium.c b/src/backend_chromium.c index 2a55151..e5b5ace 100644 --- a/src/backend_chromium.c +++ b/src/backend_chromium.c @@ -772,13 +772,8 @@ build_tsnode ( ts = &now; } - // XXX: May overflow if system time is badly wrong, - // but don't bother to check. time_t secs = ts->tv_sec + EPOCH_DIFF; int64_t microsecs = secs * 1000000 + ts->tv_nsec / 1000; - if (microsecs < 0) { - microsecs = 0; - } char buf[32]; int nbytes = snprintf(buf, sizeof(buf), "%" PRIi64, microsecs); @@ -1713,6 +1708,13 @@ static int backend_init ( uint32_t flags ) { + struct timespec now; + xgetrealtime(&now); + if (!valid_ts_sec(now.tv_sec)) { + log_puts("bad system time"); + return -1; + } + if (!(flags & BOOKMARKFS_BACKEND_LIB_READY)) { if (0 != bookmarkfs_lib_init()) { return -1; @@ -2517,10 +2519,16 @@ bookmark_set ( struct timespec const *times = val; json_t *ts_node; if (flags & BOOKMARK_FLAG(SET_ATIME)) { + if (!valid_ts_sec(times[0].tv_sec)) { + return -EINVAL; + } build_tsnode(×[0], &ts_node); json_object_sset_new(node, "date_last_used", ts_node); } if (flags & BOOKMARK_FLAG(SET_MTIME)) { + if (!valid_ts_sec(times[1].tv_sec)) { + return -EINVAL; + } build_tsnode(×[1], &ts_node); json_object_sset_new(node, "date_modified", ts_node); } diff --git a/src/backend_firefox.c b/src/backend_firefox.c index 3dd2eaa..c6fd8cc 100644 --- a/src/backend_firefox.c +++ b/src/backend_firefox.c @@ -2038,12 +2038,7 @@ static int64_t timespec_to_usecs ( struct timespec const *ts ) { - int64_t microsecs = ts->tv_sec * 1000000 + ts->tv_nsec / 1000; - - if (microsecs < 0) { - microsecs = 0; - } - return microsecs; + return ts->tv_sec * 1000000 + ts->tv_nsec / 1000; } static int @@ -3003,6 +2998,13 @@ static int backend_init ( uint32_t flags ) { + struct timespec now; + xgetrealtime(&now); + if (!valid_ts_sec(now.tv_sec)) { + log_puts("bad system time"); + return -1; + } + if (!(flags & BOOKMARKFS_BACKEND_LIB_READY) && !(flags & BOOKMARKFS_FRONTEND_MKFS) ) { @@ -3675,10 +3677,16 @@ bookmark_set ( if (flags & BOOKMARK_FLAG(SET_ATIME, SET_MTIME)) { struct timespec const *times = val; if (flags & BOOKMARK_FLAG(SET_ATIME)) { + if (!valid_ts_sec(times[0].tv_sec)) { + return -EINVAL; + } place_cols.last_visit_date = timespec_to_usecs(×[0]); --xattr_id; } if (flags & BOOKMARK_FLAG(SET_MTIME)) { + if (!valid_ts_sec(times[1].tv_sec)) { + return -EINVAL; + } bm_cols.last_modified = timespec_to_usecs(×[1]); } } else { diff --git a/src/backend_util.h b/src/backend_util.h index 72cbabb..a5fd413 100644 --- a/src/backend_util.h +++ b/src/backend_util.h @@ -57,6 +57,17 @@ #define FILENAME_BADLEN -2 #define FILENAME_DOTDOT -3 +/** + * The maximum valid seconds that a signed 64-bit integer can hold + * when converted to microseconds. + * + * Equals to `INT64_MAX / 1000000 - EPOCH_DIFF - 1`: + * - See the Chromium backend for `EPOCH_DIFF`. + * - Considering `tv_nsec`, subtract another second. + */ +#define TIMESPEC_SEC_MAX INT64_C(9211727563253) +#define valid_ts_sec(sec) ((sec) >= 0 && (sec) <= TIMESPEC_SEC_MAX) + /** * Opens the parent directory of a file, and stores its basename * to `basename_ptr`.