Keys devel
-----BEGIN PGP SIGNATURE----- iQIVAwUAWhc/3fSw1s6N8H32AQLJxQ/9Gw5ns9bipLQ5VeXjgQjY6U39lHWD7z0e cz1jYsqOGvWXqoHZumK6fB0NorYZ3EEiWTVqNkpTv1p5ZIJe612G3oe5SOTn2gA5 1X4qb/QMCr12TIv/R40mXuEsBUZZaUvxK5G7L7/Ty8a9iC+Pp3Tr009ThPvhfDMc RRP5MHxPghat+jwRcBjMz3ndQCkoTIlR9qichzQcndv5yywASQFxQsHEeG0tK48j NvicJawsr+0kZ2xqpRjRRJ/aQ+lMpI3SLsaUJBbIf6IYFs+i++OUkwAv0WYG0RZa xGjQBaaSmXPp48akIeModsp3SgNwBFpbTiXJR8hdGYjJNaaMNGD5HGQ539Ij+Wpf YHTIsdqw3xfFH/FoHMOesF/h/uMoA1NAMFAy/gGHxRRGNIk0wERHdTpdFUODIx9E NJk2fwBYpO+uRntgcmt9F3S9+YBzxACHYNmjvtbvUwjkr/hnl6jincTmlkmR9Fgl HYy+RcBb9A19wRYnZ5wDFOyk3sua7iq4ZBq0dbpYtSOtR9q4RtFw9wfsT8OoQMKz aBBn8AiV2ak+Qu00MFCyqj3jUoWa/8qzy6/57nWNsqoJTBMD0uI5UY4liTBGeq3g m02uVqtZgwjeBxUmMh8IxZDntVRZChGgvmifwOzb/BUV8oaOiy4aiQjONSdQBeP6 j9SDBLRH/PY= =wuVV -----END PGP SIGNATURE----- Merge tag 'keys-next-20171123' of git://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs into next-keys Merge keys subsystem changes from David Howells, for v4.15.
This commit is contained in:
commit
ce44cd8dfc
14 changed files with 66 additions and 65 deletions
|
@ -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::
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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>
|
||||
|
@ -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 */
|
||||
|
|
|
@ -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");
|
||||
|
||||
/*
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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>
|
||||
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
@ -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");
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -235,7 +235,7 @@ continue_scanning:
|
|||
|
||||
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;
|
||||
}
|
||||
|
@ -276,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)TIME64_MAX) {
|
||||
new_timer += key_gc_delay;
|
||||
key_schedule_gc(new_timer);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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) |
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
|
@ -710,16 +708,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;
|
||||
}
|
||||
if (timeout > 0)
|
||||
expiry = ktime_get_real_seconds() + timeout;
|
||||
|
||||
key->expiry = expiry;
|
||||
key_schedule_gc(key->expiry + key_gc_delay);
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
|
|
@ -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))) {
|
||||
|
@ -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);
|
||||
|
@ -834,10 +834,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;
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -178,13 +178,12 @@ 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;
|
||||
time_t expiry;
|
||||
unsigned long timo;
|
||||
unsigned long flags;
|
||||
key_ref_t key_ref, skey_ref;
|
||||
time64_t now, expiry;
|
||||
char xbuf[16];
|
||||
short state;
|
||||
u64 timo;
|
||||
int rc;
|
||||
|
||||
struct keyring_search_context ctx = {
|
||||
|
@ -215,7 +214,7 @@ 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();
|
||||
|
||||
|
@ -223,21 +222,21 @@ static int proc_keys_show(struct seq_file *m, void *v)
|
|||
expiry = READ_ONCE(key->expiry);
|
||||
if (expiry == 0) {
|
||||
memcpy(xbuf, "perm", 5);
|
||||
} else if (now.tv_sec >= expiry) {
|
||||
} else if (now >= expiry) {
|
||||
memcpy(xbuf, "expd", 5);
|
||||
} else {
|
||||
timo = expiry - now.tv_sec;
|
||||
timo = expiry - now;
|
||||
|
||||
if (timo < 60)
|
||||
sprintf(xbuf, "%lus", timo);
|
||||
sprintf(xbuf, "%llus", timo);
|
||||
else if (timo < 60*60)
|
||||
sprintf(xbuf, "%lum", timo / 60);
|
||||
sprintf(xbuf, "%llum", div_u64(timo, 60));
|
||||
else if (timo < 60*60*24)
|
||||
sprintf(xbuf, "%luh", timo / (60*60));
|
||||
sprintf(xbuf, "%lluh", div_u64(timo, 60 * 60));
|
||||
else if (timo < 60*60*24*7)
|
||||
sprintf(xbuf, "%lud", timo / (60*60*24));
|
||||
sprintf(xbuf, "%llud", div_u64(timo, 60 * 60 * 24));
|
||||
else
|
||||
sprintf(xbuf, "%luw", timo / (60*60*24*7));
|
||||
sprintf(xbuf, "%lluw", div_u64(timo, 60 * 60 * 24 * 7));
|
||||
}
|
||||
|
||||
state = key_read_state(key);
|
||||
|
|
|
@ -738,7 +738,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);
|
||||
|
|
Loading…
Reference in a new issue