Changes all the uses of time_t for the structs key
and key_preparsed_payload to time64_t. This also
involves the functions that use them in security/keys.
This is to handle the y2038 problem where time_t will
overflow in 2038.

Also since time_t was a long int and time64_t is long long,
uses of LONG_MAX and TIME_T_MAX were replaced by S64_MAX.

Signed-off-by: Arnd Bergmann <[email protected]>
Signed-off-by: Aya Mahfouz <[email protected]>
---
Changelog:
v1: The changes were originally made by Arnd Bergmann in
relation to time_t. I've broken down a patch sent to me 
into two independent patches.

 include/linux/key-type.h     |  2 +-
 include/linux/key.h          |  6 +++---
 security/keys/gc.c           | 23 ++++++++++++-----------
 security/keys/internal.h     |  8 ++++----
 security/keys/key.c          | 24 +++++++++---------------
 security/keys/keyring.c      | 18 +++++++++---------
 security/keys/permission.c   |  3 +--
 security/keys/proc.c         |  8 ++++----
 security/keys/process_keys.c |  2 +-
 9 files changed, 44 insertions(+), 50 deletions(-)

diff --git a/include/linux/key-type.h b/include/linux/key-type.h
index 7463355..2c844ae 100644
--- a/include/linux/key-type.h
+++ b/include/linux/key-type.h
@@ -44,7 +44,7 @@ struct key_preparsed_payload {
        const void      *data;          /* Raw data */
        size_t          datalen;        /* Raw datalen */
        size_t          quotalen;       /* Quota length for proposed payload */
-       time_t          expiry;         /* Expiry time of key */
+       time64_t        expiry;         /* Expiry time of key */
        bool            trusted;        /* True if key is trusted */
 };
 
diff --git a/include/linux/key.h b/include/linux/key.h
index 66f7052..6f69a25 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -145,10 +145,10 @@ struct key {
        struct key_user         *user;          /* owner of this key */
        void                    *security;      /* security data for this key */
        union {
-               time_t          expiry;         /* time at which key expires 
(or 0) */
-               time_t          revoked_at;     /* time at which key was 
revoked */
+               time64_t        expiry;         /* time at which key expires 
(or 0) */
+               time64_t        revoked_at;     /* time at which key was 
revoked */
        };
-       time_t                  last_used_at;   /* last time used for LRU 
keyring discard */
+       time64_t                last_used_at;   /* last time used for LRU 
keyring discard */
        kuid_t                  uid;
        kgid_t                  gid;
        key_perm_t              perm;           /* access permissions */
diff --git a/security/keys/gc.c b/security/keys/gc.c
index addf060..a467a61 100644
--- a/security/keys/gc.c
+++ b/security/keys/gc.c
@@ -32,7 +32,7 @@ DECLARE_WORK(key_gc_work, key_garbage_collector);
 static void key_gc_timer_func(unsigned long);
 static DEFINE_TIMER(key_gc_timer, key_gc_timer_func, 0, 0);
 
-static time_t key_gc_next_run = LONG_MAX;
+static time64_t key_gc_next_run = S64_MAX;
 static struct key_type *key_gc_dead_keytype;
 
 static unsigned long key_gc_flags;
@@ -53,12 +53,12 @@ struct key_type key_type_dead = {
  * Schedule a garbage collection run.
  * - time precision isn't particularly important
  */
-void key_schedule_gc(time_t gc_at)
+void key_schedule_gc(time64_t gc_at)
 {
        unsigned long expires;
-       time_t now = current_kernel_time().tv_sec;
+       time64_t now = ktime_get_real_seconds();
 
-       kenter("%ld", gc_at - now);
+       kenter("%ld", (long)(gc_at - now));
 
        if (gc_at <= now || test_bit(KEY_GC_REAP_KEYTYPE, &key_gc_flags)) {
                kdebug("IMMEDIATE");
@@ -87,7 +87,7 @@ void key_schedule_gc_links(void)
 static void key_gc_timer_func(unsigned long data)
 {
        kenter("");
-       key_gc_next_run = LONG_MAX;
+       key_gc_next_run = S64_MAX;
        key_schedule_gc_links();
 }
 
@@ -186,11 +186,11 @@ static void key_garbage_collector(struct work_struct 
*work)
 
        struct rb_node *cursor;
        struct key *key;
-       time_t new_timer, limit;
+       time64_t new_timer, limit;
 
        kenter("[%lx,%x]", key_gc_flags, gc_state);
 
-       limit = current_kernel_time().tv_sec;
+       limit = ktime_get_real_seconds();
        if (limit > key_gc_delay)
                limit -= key_gc_delay;
        else
@@ -206,7 +206,7 @@ static void key_garbage_collector(struct work_struct *work)
                gc_state |= KEY_GC_REAPING_DEAD_1;
        kdebug("new pass %x", gc_state);
 
-       new_timer = LONG_MAX;
+       new_timer = S64_MAX;
 
        /* As only this function is permitted to remove things from the key
         * serial tree, if cursor is non-NULL then it will always point to a
@@ -234,8 +234,9 @@ continue_scanning:
 
                if (gc_state & KEY_GC_SET_TIMER) {
                        if (key->expiry > limit && key->expiry < new_timer) {
-                               kdebug("will expire %x in %ld",
-                                      key_serial(key), key->expiry - limit);
+                               kdebug("will expire %x in %lld",
+                                      key_serial(key),
+                                      (s64)(key->expiry - limit));
                                new_timer = key->expiry;
                        }
                }
@@ -275,7 +276,7 @@ maybe_resched:
         */
        kdebug("pass complete");
 
-       if (gc_state & KEY_GC_SET_TIMER && new_timer != (time_t)LONG_MAX) {
+       if (gc_state & KEY_GC_SET_TIMER && new_timer != (time64_t)S64_MAX) {
                new_timer += key_gc_delay;
                key_schedule_gc(new_timer);
        }
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 5105c2c..5f4f007 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -125,7 +125,7 @@ struct keyring_search_context {
        int                     skipped_ret;
        bool                    possessed;
        key_ref_t               result;
-       struct timespec         now;
+       time64_t                now;
 };
 
 extern bool key_default_cmp(const struct key *key,
@@ -164,8 +164,8 @@ extern void key_change_session_keyring(struct callback_head 
*twork);
 
 extern struct work_struct key_gc_work;
 extern unsigned key_gc_delay;
-extern void keyring_gc(struct key *keyring, time_t limit);
-extern void key_schedule_gc(time_t gc_at);
+extern void keyring_gc(struct key *keyring, time64_t limit);
+extern void key_schedule_gc(time64_t gc_at);
 extern void key_schedule_gc_links(void);
 extern void key_gc_keytype(struct key_type *ktype);
 
@@ -204,7 +204,7 @@ extern struct key 
*key_get_instantiation_authkey(key_serial_t target_id);
 /*
  * Determine whether a key is dead.
  */
-static inline bool key_is_dead(const struct key *key, time_t limit)
+static inline bool key_is_dead(const struct key *key, time64_t limit)
 {
        return
                key->flags & ((1 << KEY_FLAG_DEAD) |
diff --git a/security/keys/key.c b/security/keys/key.c
index ab7997d..d134a26 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -436,7 +436,7 @@ static int __key_instantiate_and_link(struct key *key,
                        if (authkey)
                                key_revoke(authkey);
 
-                       if (prep->expiry != TIME_T_MAX) {
+                       if (prep->expiry != S64_MAX) {
                                key->expiry = prep->expiry;
                                key_schedule_gc(prep->expiry + key_gc_delay);
                        }
@@ -482,7 +482,7 @@ int key_instantiate_and_link(struct key *key,
        prep.data = data;
        prep.datalen = datalen;
        prep.quotalen = key->type->def_datalen;
-       prep.expiry = TIME_T_MAX;
+       prep.expiry = S64_MAX;
        if (key->type->preparse) {
                ret = key->type->preparse(&prep);
                if (ret < 0)
@@ -536,7 +536,6 @@ int key_reject_and_link(struct key *key,
                        struct key *authkey)
 {
        struct assoc_array_edit *edit;
-       struct timespec now;
        int ret, awaken, link_ret = 0;
 
        key_check(key);
@@ -558,8 +557,7 @@ int key_reject_and_link(struct key *key,
                smp_wmb();
                set_bit(KEY_FLAG_NEGATIVE, &key->flags);
                set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
-               now = current_kernel_time();
-               key->expiry = now.tv_sec + timeout;
+               key->expiry = ktime_get_real_seconds() + timeout;
                key_schedule_gc(key->expiry + key_gc_delay);
 
                if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags))
@@ -678,15 +676,13 @@ found_kernel_type:
 
 void key_set_timeout(struct key *key, unsigned timeout)
 {
-       struct timespec now;
-       time_t expiry = 0;
+       time64_t expiry = 0;
 
        /* make the changes with the locks held to prevent races */
        down_write(&key->sem);
 
        if (timeout > 0) {
-               now = current_kernel_time();
-               expiry = now.tv_sec + timeout;
+               expiry = ktime_get_real_seconds() + timeout;
        }
 
        key->expiry = expiry;
@@ -814,7 +810,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
        prep.datalen = plen;
        prep.quotalen = index_key.type->def_datalen;
        prep.trusted = flags & KEY_ALLOC_TRUSTED;
-       prep.expiry = TIME_T_MAX;
+       prep.expiry = S64_MAX;
        if (index_key.type->preparse) {
                ret = index_key.type->preparse(&prep);
                if (ret < 0) {
@@ -945,7 +941,7 @@ int key_update(key_ref_t key_ref, const void *payload, 
size_t plen)
        prep.data = payload;
        prep.datalen = plen;
        prep.quotalen = key->type->def_datalen;
-       prep.expiry = TIME_T_MAX;
+       prep.expiry = S64_MAX;
        if (key->type->preparse) {
                ret = key->type->preparse(&prep);
                if (ret < 0)
@@ -979,8 +975,7 @@ EXPORT_SYMBOL(key_update);
  */
 void key_revoke(struct key *key)
 {
-       struct timespec now;
-       time_t time;
+       time64_t time;
 
        key_check(key);
 
@@ -995,8 +990,7 @@ void key_revoke(struct key *key)
                key->type->revoke(key);
 
        /* set the death time to no more than the expiry time */
-       now = current_kernel_time();
-       time = now.tv_sec;
+       time = ktime_get_real_seconds();
        if (key->revoked_at == 0 || key->revoked_at > time) {
                key->revoked_at = time;
                key_schedule_gc(key->revoked_at + key_gc_delay);
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index f931ccf..a272386 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -545,7 +545,7 @@ static int keyring_search_iterator(const void *object, void 
*iterator_data)
                        goto skipped;
                }
 
-               if (key->expiry && ctx->now.tv_sec >= key->expiry) {
+               if (key->expiry && ctx->now >= key->expiry) {
                        if (!(ctx->flags & KEYRING_SEARCH_SKIP_EXPIRED))
                                ctx->result = ERR_PTR(-EKEYEXPIRED);
                        kleave(" = %d [expire]", ctx->skipped_ret);
@@ -806,10 +806,10 @@ found:
        key = key_ref_to_ptr(ctx->result);
        key_check(key);
        if (!(ctx->flags & KEYRING_SEARCH_NO_UPDATE_TIME)) {
-               key->last_used_at = ctx->now.tv_sec;
-               keyring->last_used_at = ctx->now.tv_sec;
+               key->last_used_at = ctx->now;
+               keyring->last_used_at = ctx->now;
                while (sp > 0)
-                       stack[--sp].keyring->last_used_at = ctx->now.tv_sec;
+                       stack[--sp].keyring->last_used_at = ctx->now;
        }
        kleave(" = true");
        return true;
@@ -870,7 +870,7 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
        }
 
        rcu_read_lock();
-       ctx->now = current_kernel_time();
+       ctx->now = ktime_get_real_seconds();
        if (search_nested_keyrings(keyring, ctx))
                __key_get(key_ref_to_ptr(ctx->result));
        rcu_read_unlock();
@@ -1011,7 +1011,7 @@ struct key *find_keyring_by_name(const char *name, bool 
skip_perm_check)
                         * (ie. it has a zero usage count) */
                        if (!atomic_inc_not_zero(&keyring->usage))
                                continue;
-                       keyring->last_used_at = current_kernel_time().tv_sec;
+                       keyring->last_used_at = ktime_get_real_seconds();
                        goto out;
                }
        }
@@ -1342,7 +1342,7 @@ static void keyring_revoke(struct key *keyring)
 static bool keyring_gc_select_iterator(void *object, void *iterator_data)
 {
        struct key *key = keyring_ptr_to_key(object);
-       time_t *limit = iterator_data;
+       time64_t *limit = iterator_data;
 
        if (key_is_dead(key, *limit))
                return false;
@@ -1353,7 +1353,7 @@ static bool keyring_gc_select_iterator(void *object, void 
*iterator_data)
 static int keyring_gc_check_iterator(const void *object, void *iterator_data)
 {
        const struct key *key = keyring_ptr_to_key(object);
-       time_t *limit = iterator_data;
+       time64_t *limit = iterator_data;
 
        key_check(key);
        return key_is_dead(key, *limit);
@@ -1365,7 +1365,7 @@ static int keyring_gc_check_iterator(const void *object, 
void *iterator_data)
  * Not called with any locks held.  The keyring's key struct will not be
  * deallocated under us as only our caller may deallocate it.
  */
-void keyring_gc(struct key *keyring, time_t limit)
+void keyring_gc(struct key *keyring, time64_t limit)
 {
        int result;
 
diff --git a/security/keys/permission.c b/security/keys/permission.c
index 732cc0b..507b1d41 100644
--- a/security/keys/permission.c
+++ b/security/keys/permission.c
@@ -100,8 +100,7 @@ int key_validate(const struct key *key)
 
        /* check it hasn't expired */
        if (key->expiry) {
-               struct timespec now = current_kernel_time();
-               if (now.tv_sec >= key->expiry)
+               if (ktime_get_real_seconds() >= key->expiry)
                        return -EKEYEXPIRED;
        }
 
diff --git a/security/keys/proc.c b/security/keys/proc.c
index f0611a6..f3c20aa 100644
--- a/security/keys/proc.c
+++ b/security/keys/proc.c
@@ -178,7 +178,7 @@ static int proc_keys_show(struct seq_file *m, void *v)
 {
        struct rb_node *_p = v;
        struct key *key = rb_entry(_p, struct key, serial_node);
-       struct timespec now;
+       time64_t now;
        unsigned long timo;
        key_ref_t key_ref, skey_ref;
        char xbuf[12];
@@ -216,17 +216,17 @@ static int proc_keys_show(struct seq_file *m, void *v)
        if (rc < 0)
                return 0;
 
-       now = current_kernel_time();
+       now = ktime_get_real_seconds();
 
        rcu_read_lock();
 
        /* come up with a suitable timeout value */
        if (key->expiry == 0) {
                memcpy(xbuf, "perm", 5);
-       } else if (now.tv_sec >= key->expiry) {
+       } else if (now >= key->expiry) {
                memcpy(xbuf, "expd", 5);
        } else {
-               timo = key->expiry - now.tv_sec;
+               timo = key->expiry - now;
 
                if (timo < 60)
                        sprintf(xbuf, "%lus", timo);
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index a3f85d2..7acede7 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -721,7 +721,7 @@ try_again:
        if (ret < 0)
                goto invalid_key;
 
-       key->last_used_at = current_kernel_time().tv_sec;
+       key->last_used_at = ktime_get_real_seconds();
 
 error:
        put_cred(ctx.cred);
-- 
2.4.3


-- 
Kind Regards,
Aya Saif El-yazal Mahfouz
_______________________________________________
Y2038 mailing list
[email protected]
https://lists.linaro.org/mailman/listinfo/y2038

Reply via email to