Blame SOURCES/Limit-ticket-lifetime-to-2-31-1-seconds.patch

7055e9
From 31d5c854198ed91fc2bd0b9fb87ed0dcd5a40eb6 Mon Sep 17 00:00:00 2001
7055e9
From: Greg Hudson <ghudson@mit.edu>
7055e9
Date: Thu, 24 Aug 2017 16:00:33 -0400
7055e9
Subject: [PATCH] Limit ticket lifetime to 2^31-1 seconds
7055e9
7055e9
Although timestamps above 2^31-1 are now valid, intervals exceeding
7055e9
2^31-1 seconds may be treated incorrectly by comparison operations.
7055e9
7055e9
The initially computed interval in kdc_get_ticket_endtime() could be
7055e9
negative if the requested end time is far in the future, causing the
7055e9
function to yield an incorrect result.  (With the new larger value of
7055e9
kdc_infinity, this could specifically happen if a KDC-REQ contains a
7055e9
zero till field.)  Cap the interval at the maximum valid value.
7055e9
Reported by Weijun Wang.
7055e9
7055e9
Avoid delta comparisons in favor of timestamp comparions in
7055e9
krb5int_validate_times(), ksu's krb5_check_exp(), and clockskew
7055e9
checks.
7055e9
7055e9
Also use a y2038-safe timestamp comparison in set_request_times() when
7055e9
comparing the requested renewable end time to the requested ticket end
7055e9
time.
7055e9
7055e9
ticket: 8352
7055e9
(cherry picked from commit 54e58755368b58ba5894a14c1d02626da42d8003)
7055e9
---
7055e9
 src/clients/ksu/ccache.c       | 2 +-
7055e9
 src/include/k5-int.h           | 7 +++++++
7055e9
 src/kdc/kdc_util.c             | 7 ++++++-
7055e9
 src/kdc/replay.c               | 2 +-
7055e9
 src/kdc/t_replay.c             | 2 +-
7055e9
 src/lib/krb5/krb/gc_via_tkt.c  | 4 ++--
7055e9
 src/lib/krb5/krb/get_in_tkt.c  | 6 +++---
7055e9
 src/lib/krb5/krb/int-proto.h   | 3 ---
7055e9
 src/lib/krb5/krb/valid_times.c | 4 ++--
7055e9
 src/lib/krb5/os/timeofday.c    | 2 +-
7055e9
 10 files changed, 24 insertions(+), 15 deletions(-)
7055e9
7055e9
diff --git a/src/clients/ksu/ccache.c b/src/clients/ksu/ccache.c
7055e9
index 236313b7b..2a99521d4 100644
7055e9
--- a/src/clients/ksu/ccache.c
7055e9
+++ b/src/clients/ksu/ccache.c
7055e9
@@ -282,7 +282,7 @@ krb5_error_code krb5_check_exp(context, tkt_time)
7055e9
 
7055e9
     }
7055e9
 
7055e9
-    if (ts_delta(currenttime, tkt_time.endtime) > context->clockskew) {
7055e9
+    if (ts_after(currenttime, ts_incr(tkt_time.endtime, context->clockskew))) {
7055e9
         retval = KRB5KRB_AP_ERR_TKT_EXPIRED ;
7055e9
         return retval;
7055e9
     }
7055e9
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
7055e9
index 39ffb9568..e31004a7c 100644
7055e9
--- a/src/include/k5-int.h
7055e9
+++ b/src/include/k5-int.h
7055e9
@@ -2386,6 +2386,13 @@ ts_after(krb5_timestamp a, krb5_timestamp b)
7055e9
     return (uint32_t)a > (uint32_t)b;
7055e9
 }
7055e9
 
7055e9
+/* Return true if a and b are within d seconds. */
7055e9
+static inline krb5_boolean
7055e9
+ts_within(krb5_timestamp a, krb5_timestamp b, krb5_deltat d)
7055e9
+{
7055e9
+    return !ts_after(a, ts_incr(b, d)) && !ts_after(b, ts_incr(a, d));
7055e9
+}
7055e9
+
7055e9
 krb5_error_code KRB5_CALLCONV
7055e9
 krb5_get_credentials_for_user(krb5_context context, krb5_flags options,
7055e9
                               krb5_ccache ccache,
7055e9
diff --git a/src/kdc/kdc_util.c b/src/kdc/kdc_util.c
7055e9
index 5455e2a67..770163b94 100644
7055e9
--- a/src/kdc/kdc_util.c
7055e9
+++ b/src/kdc/kdc_util.c
7055e9
@@ -1759,14 +1759,19 @@ kdc_get_ticket_endtime(kdc_realm_t *kdc_active_realm,
7055e9
                        krb5_db_entry *server,
7055e9
                        krb5_timestamp *out_endtime)
7055e9
 {
7055e9
-    krb5_timestamp until, life;
7055e9
+    krb5_timestamp until;
7055e9
+    krb5_deltat life;
7055e9
 
7055e9
     if (till == 0)
7055e9
         till = kdc_infinity;
7055e9
 
7055e9
     until = ts_min(till, endtime);
7055e9
 
7055e9
+    /* Determine the requested lifetime, capped at the maximum valid time
7055e9
+     * interval. */
7055e9
     life = ts_delta(until, starttime);
7055e9
+    if (ts_after(until, starttime) && life < 0)
7055e9
+        life = INT32_MAX;
7055e9
 
7055e9
     if (client != NULL && client->max_life != 0)
7055e9
         life = min(life, client->max_life);
7055e9
diff --git a/src/kdc/replay.c b/src/kdc/replay.c
7055e9
index fab39cf88..caca783bf 100644
7055e9
--- a/src/kdc/replay.c
7055e9
+++ b/src/kdc/replay.c
7055e9
@@ -61,7 +61,7 @@ static size_t total_size = 0;
7055e9
 static krb5_ui_4 seed;
7055e9
 
7055e9
 #define STALE_TIME      (2*60)            /* two minutes */
7055e9
-#define STALE(ptr, now) (labs(ts_delta((ptr)->timein, now)) >= STALE_TIME)
7055e9
+#define STALE(ptr, now) (ts_after(now, ts_incr((ptr)->timein, STALE_TIME)))
7055e9
 
7055e9
 /* Return x rotated to the left by r bits. */
7055e9
 static inline krb5_ui_4
7055e9
diff --git a/src/kdc/t_replay.c b/src/kdc/t_replay.c
7055e9
index 1442e0e8c..bb7e2faff 100644
7055e9
--- a/src/kdc/t_replay.c
7055e9
+++ b/src/kdc/t_replay.c
7055e9
@@ -903,7 +903,7 @@ test_kdc_insert_lookaside_cache_expire(void **state)
7055e9
     assert_non_null(e);
7055e9
     e->num_hits = 5;
7055e9
 
7055e9
-    time_return(STALE_TIME, 0);
7055e9
+    time_return(STALE_TIME + 1, 0);
7055e9
     kdc_insert_lookaside(context, &req2, NULL);
7055e9
 
7055e9
     assert_null(K5_LIST_FIRST(&hash_table[req_hash1]));
7055e9
diff --git a/src/lib/krb5/krb/gc_via_tkt.c b/src/lib/krb5/krb/gc_via_tkt.c
7055e9
index cf1ea361f..5b9bb9573 100644
7055e9
--- a/src/lib/krb5/krb/gc_via_tkt.c
7055e9
+++ b/src/lib/krb5/krb/gc_via_tkt.c
7055e9
@@ -306,8 +306,8 @@ krb5int_process_tgs_reply(krb5_context context,
7055e9
         goto cleanup;
7055e9
 
7055e9
     if (!in_cred->times.starttime &&
7055e9
-        !in_clock_skew(context, dec_rep->enc_part2->times.starttime,
7055e9
-                       timestamp)) {
7055e9
+        !ts_within(dec_rep->enc_part2->times.starttime, timestamp,
7055e9
+                   context->clockskew)) {
7055e9
         retval = KRB5_KDCREP_SKEW;
7055e9
         goto cleanup;
7055e9
     }
7055e9
diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
7055e9
index 7178bd87b..ed15550f0 100644
7055e9
--- a/src/lib/krb5/krb/get_in_tkt.c
7055e9
+++ b/src/lib/krb5/krb/get_in_tkt.c
7055e9
@@ -269,8 +269,8 @@ verify_as_reply(krb5_context            context,
7055e9
             return retval;
7055e9
     } else {
7055e9
         if ((request->from == 0) &&
7055e9
-            !in_clock_skew(context, as_reply->enc_part2->times.starttime,
7055e9
-                           time_now))
7055e9
+            !ts_within(as_reply->enc_part2->times.starttime, time_now,
7055e9
+                       context->clockskew))
7055e9
             return (KRB5_KDCREP_SKEW);
7055e9
     }
7055e9
     return 0;
7055e9
@@ -781,7 +781,7 @@ set_request_times(krb5_context context, krb5_init_creds_context ctx)
7055e9
     if (ctx->renew_life > 0) {
7055e9
         /* Don't ask for a smaller renewable time than the lifetime. */
7055e9
         ctx->request->rtime = ts_incr(from, ctx->renew_life);
7055e9
-        if (ctx->request->rtime < ctx->request->till)
7055e9
+        if (ts_after(ctx->request->till, ctx->request->rtime))
7055e9
             ctx->request->rtime = ctx->request->till;
7055e9
         ctx->request->kdc_options &= ~KDC_OPT_RENEWABLE_OK;
7055e9
     } else {
7055e9
diff --git a/src/lib/krb5/krb/int-proto.h b/src/lib/krb5/krb/int-proto.h
7055e9
index 48bd9f8f7..9c746d05b 100644
7055e9
--- a/src/lib/krb5/krb/int-proto.h
7055e9
+++ b/src/lib/krb5/krb/int-proto.h
7055e9
@@ -83,9 +83,6 @@ krb5int_construct_matching_creds(krb5_context context, krb5_flags options,
7055e9
                                  krb5_creds *in_creds, krb5_creds *mcreds,
7055e9
                                  krb5_flags *fields);
7055e9
 
7055e9
-#define in_clock_skew(context, date, now)               \
7055e9
-    (labs(ts_delta(date, now)) < (context)->clockskew)
7055e9
-
7055e9
 #define IS_TGS_PRINC(p) ((p)->length == 2 &&                            \
7055e9
                          data_eq_string((p)->data[0], KRB5_TGS_NAME))
7055e9
 
7055e9
diff --git a/src/lib/krb5/krb/valid_times.c b/src/lib/krb5/krb/valid_times.c
7055e9
index 9e509b2dd..294761a88 100644
7055e9
--- a/src/lib/krb5/krb/valid_times.c
7055e9
+++ b/src/lib/krb5/krb/valid_times.c
7055e9
@@ -47,10 +47,10 @@ krb5int_validate_times(krb5_context context, krb5_ticket_times *times)
7055e9
     else
7055e9
         starttime = times->authtime;
7055e9
 
7055e9
-    if (ts_delta(starttime, currenttime) > context->clockskew)
7055e9
+    if (ts_after(starttime, ts_incr(currenttime, context->clockskew)))
7055e9
         return KRB5KRB_AP_ERR_TKT_NYV;  /* ticket not yet valid */
7055e9
 
7055e9
-    if (ts_delta(currenttime, times->endtime) > context->clockskew)
7055e9
+    if (ts_after(currenttime, ts_incr(times->endtime, context->clockskew)))
7055e9
         return KRB5KRB_AP_ERR_TKT_EXPIRED; /* ticket expired */
7055e9
 
7055e9
     return 0;
7055e9
diff --git a/src/lib/krb5/os/timeofday.c b/src/lib/krb5/os/timeofday.c
7055e9
index 887f24c22..d4e36b1c7 100644
7055e9
--- a/src/lib/krb5/os/timeofday.c
7055e9
+++ b/src/lib/krb5/os/timeofday.c
7055e9
@@ -60,7 +60,7 @@ krb5_check_clockskew(krb5_context context, krb5_timestamp date)
7055e9
     retval = krb5_timeofday(context, &currenttime);
7055e9
     if (retval)
7055e9
         return retval;
7055e9
-    if (labs(ts_delta(date, currenttime)) >= context->clockskew)
7055e9
+    if (!ts_within(date, currenttime, context->clockskew))
7055e9
         return KRB5KRB_AP_ERR_SKEW;
7055e9
 
7055e9
     return 0;