/* Key garbage collector
 *
 * Copyright (C) 2009 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public Licence
 * as published by the Free Software Foundation; either version
 * 2 of the Licence, or (at your option) any later version.
 */

#include <linux/module.h>
#include <keys/keyring-type.h>
#include "internal.h"

/*
 * Delay between key revocation/expiry in seconds
 */
unsigned key_gc_delay = 5 * 60;

/*
 * Reaper
 */
static void key_gc_timer_func(unsigned long);
static void key_garbage_collector(struct work_struct *);
static DEFINE_TIMER(key_gc_timer, key_gc_timer_func, 0, 0);
static DECLARE_WORK(key_gc_work, key_garbage_collector);
static key_serial_t key_gc_cursor; /* the last key the gc considered */
static bool key_gc_again;
static unsigned long key_gc_executing;
static time_t key_gc_next_run = LONG_MAX;
static time_t key_gc_new_timer;

/*
 * Schedule a garbage collection run.
 * - time precision isn't particularly important
 */
void key_schedule_gc(time_t gc_at)
{
	unsigned long expires;
	time_t now = current_kernel_time().tv_sec;

	kenter("%ld", gc_at - now);

	if (gc_at <= now) {
		schedule_work(&key_gc_work);
	} else if (gc_at < key_gc_next_run) {
		expires = jiffies + (gc_at - now) * HZ;
		mod_timer(&key_gc_timer, expires);
	}
}

/*
 * The garbage collector timer kicked off
 */
static void key_gc_timer_func(unsigned long data)
{
	kenter("");
	key_gc_next_run = LONG_MAX;
	schedule_work(&key_gc_work);
}

/*
 * Garbage collect pointers from a keyring.
 *
 * Return true if we altered the keyring.
 */
static bool key_gc_keyring(struct key *keyring, time_t limit)
	__releases(key_serial_lock)
{
	struct keyring_list *klist;
	struct key *key;
	int loop;

	kenter("%x", key_serial(keyring));

	if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
		goto dont_gc;

	/* scan the keyring looking for dead keys */
	rcu_read_lock();
	klist = rcu_dereference(keyring->payload.subscriptions);
	if (!klist)
		goto unlock_dont_gc;

	for (loop = klist->nkeys - 1; loop >= 0; loop--) {
		key = klist->keys[loop];
		if (test_bit(KEY_FLAG_DEAD, &key->flags) ||
		    (key->expiry > 0 && key->expiry <= limit))
			goto do_gc;
	}

unlock_dont_gc:
	rcu_read_unlock();
dont_gc:
	kleave(" = false");
	return false;

do_gc:
	rcu_read_unlock();
	key_gc_cursor = keyring->serial;
	key_get(keyring);
	spin_unlock(&key_serial_lock);
	keyring_gc(keyring, limit);
	key_put(keyring);
	kleave(" = true");
	return true;
}

/*
 * Garbage collector for keys.  This involves scanning the keyrings for dead,
 * expired and revoked keys that have overstayed their welcome
 */
static void key_garbage_collector(struct work_struct *work)
{
	struct rb_node *rb;
	key_serial_t cursor;
	struct key *key, *xkey;
	time_t new_timer = LONG_MAX, limit, now;

	now = current_kernel_time().tv_sec;
	kenter("[%x,%ld]", key_gc_cursor, key_gc_new_timer - now);

	if (test_and_set_bit(0, &key_gc_executing)) {
		key_schedule_gc(current_kernel_time().tv_sec + 1);
		kleave(" [busy; deferring]");
		return;
	}

	limit = now;
	if (limit > key_gc_delay)
		limit -= key_gc_delay;
	else
		limit = key_gc_delay;

	spin_lock(&key_serial_lock);

	if (unlikely(RB_EMPTY_ROOT(&key_serial_tree))) {
		spin_unlock(&key_serial_lock);
		clear_bit(0, &key_gc_executing);
		return;
	}

	cursor = key_gc_cursor;
	if (cursor < 0)
		cursor = 0;
	if (cursor > 0)
		new_timer = key_gc_new_timer;
	else
		key_gc_again = false;

	/* find the first key above the cursor */
	key = NULL;
	rb = key_serial_tree.rb_node;
	while (rb) {
		xkey = rb_entry(rb, struct key, serial_node);
		if (cursor < xkey->serial) {
			key = xkey;
			rb = rb->rb_left;
		} else if (cursor > xkey->serial) {
			rb = rb->rb_right;
		} else {
			rb = rb_next(rb);
			if (!rb)
				goto reached_the_end;
			key = rb_entry(rb, struct key, serial_node);
			break;
		}
	}

	if (!key)
		goto reached_the_end;

	/* trawl through the keys looking for keyrings */
	for (;;) {
		if (key->expiry > limit && key->expiry < new_timer) {
			kdebug("will expire %x in %ld",
			       key_serial(key), key->expiry - limit);
			new_timer = key->expiry;
		}

		if (key->type == &key_type_keyring &&
		    key_gc_keyring(key, limit))
			/* the gc had to release our lock so that the keyring
			 * could be modified, so we have to get it again */
			goto gc_released_our_lock;

		rb = rb_next(&key->serial_node);
		if (!rb)
			goto reached_the_end;
		key = rb_entry(rb, struct key, serial_node);
	}

gc_released_our_lock:
	kdebug("gc_released_our_lock");
	key_gc_new_timer = new_timer;
	key_gc_again = true;
	clear_bit(0, &key_gc_executing);
	schedule_work(&key_gc_work);
	kleave(" [continue]");
	return;

	/* when we reach the end of the run, we set the timer for the next one */
reached_the_end:
	kdebug("reached_the_end");
	spin_unlock(&key_serial_lock);
	key_gc_new_timer = new_timer;
	key_gc_cursor = 0;
	clear_bit(0, &key_gc_executing);

	if (key_gc_again) {
		/* there may have been a key that expired whilst we were
		 * scanning, so if we discarded any links we should do another
		 * scan */
		new_timer = now + 1;
		key_schedule_gc(new_timer);
	} else if (new_timer < LONG_MAX) {
		new_timer += key_gc_delay;
		key_schedule_gc(new_timer);
	}
	kleave(" [end]");
}
