Merge branch 'next-keys' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security

Pull keys update from James Morris:
 "There's nothing too controversial here:

   - Doc fix for keyctl_read().

   - time_t -> time64_t replacement.

   - Set the module licence on things to prevent tainting"

* 'next-keys' of git://git.kernel.org/pub/scm/linux/kernel/git/jmorris/linux-security:
  pkcs7: Set the module licence to prevent tainting
  security: keys: Replace time_t with time64_t for struct key_preparsed_payload
  security: keys: Replace time_t/timespec with time64_t
  KEYS: fix in-kernel documentation for keyctl_read()
This commit is contained in:
Linus Torvalds 2017-11-23 20:51:27 -10:00
Родитель 26064dea2d ce44cd8dfc
Коммит dab0badc87
14 изменённых файлов: 66 добавлений и 65 удалений

Просмотреть файл

@ -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);