Skip to content

Commit

Permalink
Merge tag 'keys-next-20171123' of git://git.kernel.org/pub/scm/linux/…
Browse files Browse the repository at this point in the history
…kernel/git/dhowells/linux-fs into next-keys

Merge keys subsystem changes from David Howells, for v4.15.
  • Loading branch information
James Morris committed Nov 24, 2017
2 parents 5a78775 + 1e684d3 commit ce44cd8
Show file tree
Hide file tree
Showing 14 changed files with 66 additions and 65 deletions.
10 changes: 5 additions & 5 deletions Documentation/security/keys/core.rst
Original file line number Diff line number Diff line change
Expand Up @@ -628,12 +628,12 @@ The keyctl syscall functions are:
defined key type will return its data as is. If a key type does not
implement this function, error EOPNOTSUPP will result.

As much of the data as can be fitted into the buffer will be copied to
userspace if the buffer pointer is not NULL.

On a successful return, the function will always return the amount of data
available rather than the amount copied.
If the specified buffer is too small, then the size of the buffer required
will be returned. Note that in this case, the contents of the buffer may
have been overwritten in some undefined way.

Otherwise, on success, the function will return the amount of data copied
into the buffer.

* Instantiate a partially constructed key::

Expand Down
1 change: 1 addition & 0 deletions crypto/asymmetric_keys/pkcs7_key_type.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("PKCS#7 testing key type");
MODULE_AUTHOR("Red Hat, Inc.");

static unsigned pkcs7_usage;
module_param_named(usage, pkcs7_usage, uint, S_IWUSR | S_IRUGO);
Expand Down
5 changes: 5 additions & 0 deletions crypto/asymmetric_keys/pkcs7_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

#define pr_fmt(fmt) "PKCS7: "fmt
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/export.h>
#include <linux/slab.h>
#include <linux/err.h>
Expand All @@ -19,6 +20,10 @@
#include "pkcs7_parser.h"
#include "pkcs7-asn1.h"

MODULE_DESCRIPTION("PKCS#7 parser");
MODULE_AUTHOR("Red Hat, Inc.");
MODULE_LICENSE("GPL");

struct pkcs7_parse_context {
struct pkcs7_message *msg; /* Message being constructed */
struct pkcs7_signed_info *sinfo; /* SignedInfo being constructed */
Expand Down
2 changes: 2 additions & 0 deletions crypto/asymmetric_keys/public_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include <crypto/public_key.h>
#include <crypto/akcipher.h>

MODULE_DESCRIPTION("In-software asymmetric public-key subtype");
MODULE_AUTHOR("Red Hat, Inc.");
MODULE_LICENSE("GPL");

/*
Expand Down
1 change: 1 addition & 0 deletions crypto/asymmetric_keys/x509_public_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -275,4 +275,5 @@ module_init(x509_key_init);
module_exit(x509_key_exit);

MODULE_DESCRIPTION("X.509 certificate parser");
MODULE_AUTHOR("Red Hat, Inc.");
MODULE_LICENSE("GPL");
2 changes: 1 addition & 1 deletion include/linux/key-type.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
} __randomize_layout;

typedef int (*request_key_actor_t)(struct key_construction *key,
Expand Down
7 changes: 4 additions & 3 deletions include/linux/key.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <linux/atomic.h>
#include <linux/assoc_array.h>
#include <linux/refcount.h>
#include <linux/time64.h>

#ifdef __KERNEL__
#include <linux/uidgid.h>
Expand Down Expand Up @@ -162,10 +163,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 */
Expand Down
20 changes: 10 additions & 10 deletions security/keys/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

static time_t key_gc_next_run = LONG_MAX;
static time64_t key_gc_next_run = TIME64_MAX;
static struct key_type *key_gc_dead_keytype;

static unsigned long key_gc_flags;
Expand All @@ -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("%lld", gc_at - now);

if (gc_at <= now || test_bit(KEY_GC_REAP_KEYTYPE, &key_gc_flags)) {
kdebug("IMMEDIATE");
Expand Down Expand Up @@ -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 = TIME64_MAX;
key_schedule_gc_links();
}

Expand Down Expand Up @@ -184,11 +184,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
Expand All @@ -204,7 +204,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 = TIME64_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
Expand Down Expand Up @@ -235,7 +235,7 @@ static void key_garbage_collector(struct work_struct *work)

if (gc_state & KEY_GC_SET_TIMER) {
if (key->expiry > limit && key->expiry < new_timer) {
kdebug("will expire %x in %ld",
kdebug("will expire %x in %lld",
key_serial(key), key->expiry - limit);
new_timer = key->expiry;
}
Expand Down Expand Up @@ -276,7 +276,7 @@ static void key_garbage_collector(struct work_struct *work)
*/
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)TIME64_MAX) {
new_timer += key_gc_delay;
key_schedule_gc(new_timer);
}
Expand Down
8 changes: 4 additions & 4 deletions security/keys/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,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,
Expand Down Expand Up @@ -169,10 +169,10 @@ 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 keyring_gc(struct key *keyring, time64_t limit);
extern void keyring_restriction_gc(struct key *keyring,
struct key_type *dead_type);
extern void key_schedule_gc(time_t gc_at);
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);

Expand Down Expand Up @@ -211,7 +211,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) |
Expand Down
27 changes: 10 additions & 17 deletions security/keys/key.c
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ static int __key_instantiate_and_link(struct key *key,
if (authkey)
key_revoke(authkey);

if (prep->expiry != TIME_T_MAX) {
if (prep->expiry != TIME64_MAX) {
key->expiry = prep->expiry;
key_schedule_gc(prep->expiry + key_gc_delay);
}
Expand Down Expand Up @@ -506,7 +506,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 = TIME64_MAX;
if (key->type->preparse) {
ret = key->type->preparse(&prep);
if (ret < 0)
Expand Down Expand Up @@ -570,7 +570,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);
Expand All @@ -593,8 +592,7 @@ int key_reject_and_link(struct key *key,
/* mark the key as being negatively instantiated */
atomic_inc(&key->user->nikeys);
mark_key_instantiated(key, -error);
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))
Expand Down Expand Up @@ -710,16 +708,13 @@ struct key_type *key_type_lookup(const char *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;
}
if (timeout > 0)
expiry = ktime_get_real_seconds() + timeout;

key->expiry = expiry;
key_schedule_gc(key->expiry + key_gc_delay);
Expand Down Expand Up @@ -850,7 +845,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
prep.data = payload;
prep.datalen = plen;
prep.quotalen = index_key.type->def_datalen;
prep.expiry = TIME_T_MAX;
prep.expiry = TIME64_MAX;
if (index_key.type->preparse) {
ret = index_key.type->preparse(&prep);
if (ret < 0) {
Expand Down Expand Up @@ -994,7 +989,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 = TIME64_MAX;
if (key->type->preparse) {
ret = key->type->preparse(&prep);
if (ret < 0)
Expand Down Expand Up @@ -1028,8 +1023,7 @@ EXPORT_SYMBOL(key_update);
*/
void key_revoke(struct key *key)
{
struct timespec now;
time_t time;
time64_t time;

key_check(key);

Expand All @@ -1044,8 +1038,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);
Expand Down
20 changes: 10 additions & 10 deletions security/keys/keyring.c
Original file line number Diff line number Diff line change
Expand Up @@ -565,7 +565,7 @@ static int keyring_search_iterator(const void *object, void *iterator_data)

/* skip invalidated, revoked and expired keys */
if (ctx->flags & KEYRING_SEARCH_DO_STATE_CHECK) {
time_t expiry = READ_ONCE(key->expiry);
time64_t expiry = READ_ONCE(key->expiry);

if (kflags & ((1 << KEY_FLAG_INVALIDATED) |
(1 << KEY_FLAG_REVOKED))) {
Expand All @@ -574,7 +574,7 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
goto skipped;
}

if (expiry && ctx->now.tv_sec >= expiry) {
if (expiry && ctx->now >= expiry) {
if (!(ctx->flags & KEYRING_SEARCH_SKIP_EXPIRED))
ctx->result = ERR_PTR(-EKEYEXPIRED);
kleave(" = %d [expire]", ctx->skipped_ret);
Expand Down Expand Up @@ -834,10 +834,10 @@ static bool search_nested_keyrings(struct key *keyring,
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;
Expand Down Expand Up @@ -898,7 +898,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();
Expand Down Expand Up @@ -1149,7 +1149,7 @@ struct key *find_keyring_by_name(const char *name, bool uid_keyring)
* (ie. it has a zero usage count) */
if (!refcount_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;
}
}
Expand Down Expand Up @@ -1489,7 +1489,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;
Expand All @@ -1500,7 +1500,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);
Expand All @@ -1512,7 +1512,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;

Expand Down
5 changes: 2 additions & 3 deletions security/keys/permission.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ EXPORT_SYMBOL(key_task_permission);
int key_validate(const struct key *key)
{
unsigned long flags = READ_ONCE(key->flags);
time_t expiry = READ_ONCE(key->expiry);
time64_t expiry = READ_ONCE(key->expiry);

if (flags & (1 << KEY_FLAG_INVALIDATED))
return -ENOKEY;
Expand All @@ -101,8 +101,7 @@ int key_validate(const struct key *key)

/* check it hasn't expired */
if (expiry) {
struct timespec now = current_kernel_time();
if (now.tv_sec >= expiry)
if (ktime_get_real_seconds() >= expiry)
return -EKEYEXPIRED;
}

Expand Down
Loading

0 comments on commit ce44cd8

Please sign in to comment.