krb5 commit: Make rcache file2 code slightly more robust
Greg Hudson
ghudson at mit.edu
Mon Jun 10 10:54:55 EDT 2019
https://github.com/krb5/krb5/commit/ce8d619429255e0c1483d7fce3dffdc93baaac20
commit ce8d619429255e0c1483d7fce3dffdc93baaac20
Author: Greg Hudson <ghudson at mit.edu>
Date: Sat Jun 1 15:08:24 2019 -0400
Make rcache file2 code slightly more robust
In rc_file2.c:store(), when making note of available records,
explicitly check for an empty record (r1stamp or t2stamp is 0), to
more closely match the check for terminating the search. This
silences a Coverity false positive, as Coverity does not assume that
now > skew as it would be in practice.
To preserve code readability, shorten some variable names, add an
expired() inline helper function, and add comments.
src/lib/krb5/rcache/rc_file2.c | 30 +++++++++++++++++++++---------
1 files changed, 21 insertions(+), 9 deletions(-)
diff --git a/src/lib/krb5/rcache/rc_file2.c b/src/lib/krb5/rcache/rc_file2.c
index 6519cc3..10f9a92 100644
--- a/src/lib/krb5/rcache/rc_file2.c
+++ b/src/lib/krb5/rcache/rc_file2.c
@@ -123,6 +123,14 @@ write_record(int fd, off_t offset, const uint8_t tag[TAG_LEN],
return 0;
}
+/* Return true if timestamp is expired, for the current timestamp (now) and
+ * allowable clock skew. */
+static inline krb5_boolean
+expired(uint32_t timestamp, uint32_t now, uint32_t skew)
+{
+ return ts_after(now, ts_incr(timestamp, skew));
+}
+
/* Check and store a record into an open and locked file. fd is assumed to be
* at offset 0. */
static krb5_error_code
@@ -134,8 +142,8 @@ store(krb5_context context, int fd, const uint8_t tag[TAG_LEN], uint32_t now,
off_t table_offset = -1, nrecords = 0, avail_offset = -1, record_offset;
ssize_t st;
int ind, nread;
- uint8_t seed[K5_HASH_SEED_LEN], rec1_tag[TAG_LEN], rec2_tag[TAG_LEN];
- uint32_t rec1_stamp, rec2_stamp;
+ uint8_t seed[K5_HASH_SEED_LEN], r1tag[TAG_LEN], r2tag[TAG_LEN];
+ uint32_t r1stamp, r2stamp;
/* Read or generate the hash seed. */
st = read(fd, seed, sizeof(seed));
@@ -161,23 +169,27 @@ store(krb5_context context, int fd, const uint8_t tag[TAG_LEN], uint32_t now,
ind = k5_siphash24(tag, TAG_LEN, seed) % nrecords;
record_offset = table_offset + ind * RECORD_LEN;
- ret = read_records(fd, record_offset, rec1_tag, &rec1_stamp, rec2_tag,
- &rec2_stamp, &nread);
+ ret = read_records(fd, record_offset, r1tag, &r1stamp, r2tag, &r2stamp,
+ &nread);
if (ret)
return ret;
- if ((nread >= 1 && memcmp(rec1_tag, tag, TAG_LEN) == 0) ||
- (nread == 2 && memcmp(rec2_tag, tag, TAG_LEN) == 0))
+ if ((nread >= 1 && memcmp(r1tag, tag, TAG_LEN) == 0) ||
+ (nread == 2 && memcmp(r2tag, tag, TAG_LEN) == 0))
return KRB5KRB_AP_ERR_REPEAT;
+ /* Make note of the first record available for writing (empty, beyond
+ * the end of the file, or expired). */
if (avail_offset == -1) {
- if (nread == 0 || ts_after(now, ts_incr(rec1_stamp, skew)))
+ if (nread == 0 || !r1stamp || expired(r1stamp, now, skew))
avail_offset = record_offset;
- else if (nread == 1 || ts_after(now, ts_incr(rec2_stamp, skew)))
+ else if (nread == 1 || !r2stamp || expired(r2stamp, now, skew))
avail_offset = record_offset + RECORD_LEN;
}
- if (nread < 2 || rec1_stamp == 0 || rec2_stamp == 0)
+ /* Stop searching if we encountered an empty record or one beyond the
+ * end of the file, as tag would have been written there previously. */
+ if (nread < 2 || !r1stamp || !r2stamp)
return write_record(fd, avail_offset, tag, now);
/* Use a different hash seed for the next table we search. */
More information about the cvs-krb5
mailing list