// SPDX-License-Identifier: GPL-2.0-or-later
/* AFS security handling
 *
 * Copyright (C) 2007, 2017 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 */

#include <linux/init.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/ctype.h>
#include <linux/sched.h>
#include <linux/hashtable.h>
#include <keys/rxrpc-type.h>
#include "internal.h"

static DEFINE_HASHTABLE(afs_permits_cache, 10);
static DEFINE_SPINLOCK(afs_permits_lock);

/*
 * get a key
 */
struct key *afs_request_key(struct afs_cell *cell)
{
	struct key *key;

	_enter("{%x}", key_serial(cell->anonymous_key));

	_debug("key %s", cell->anonymous_key->description);
	key = request_key(&key_type_rxrpc, cell->anonymous_key->description,
			  NULL);
	if (IS_ERR(key)) {
		if (PTR_ERR(key) != -ENOKEY) {
			_leave(" = %ld", PTR_ERR(key));
			return key;
		}

		/* act as anonymous user */
		_leave(" = {%x} [anon]", key_serial(cell->anonymous_key));
		return key_get(cell->anonymous_key);
	} else {
		/* act as authorised user */
		_leave(" = {%x} [auth]", key_serial(key));
		return key;
	}
}

/*
 * Dispose of a list of permits.
 */
static void afs_permits_rcu(struct rcu_head *rcu)
{
	struct afs_permits *permits =
		container_of(rcu, struct afs_permits, rcu);
	int i;

	for (i = 0; i < permits->nr_permits; i++)
		key_put(permits->permits[i].key);
	kfree(permits);
}

/*
 * Discard a permission cache.
 */
void afs_put_permits(struct afs_permits *permits)
{
	if (permits && refcount_dec_and_test(&permits->usage)) {
		spin_lock(&afs_permits_lock);
		hash_del_rcu(&permits->hash_node);
		spin_unlock(&afs_permits_lock);
		call_rcu(&permits->rcu, afs_permits_rcu);
	}
}

/*
 * Clear a permit cache on callback break.
 */
void afs_clear_permits(struct afs_vnode *vnode)
{
	struct afs_permits *permits;

	spin_lock(&vnode->lock);
	permits = rcu_dereference_protected(vnode->permit_cache,
					    lockdep_is_held(&vnode->lock));
	RCU_INIT_POINTER(vnode->permit_cache, NULL);
	spin_unlock(&vnode->lock);

	afs_put_permits(permits);
}

/*
 * Hash a list of permits.  Use simple addition to make it easy to add an extra
 * one at an as-yet indeterminate position in the list.
 */
static void afs_hash_permits(struct afs_permits *permits)
{
	unsigned long h = permits->nr_permits;
	int i;

	for (i = 0; i < permits->nr_permits; i++) {
		h += (unsigned long)permits->permits[i].key / sizeof(void *);
		h += permits->permits[i].access;
	}

	permits->h = h;
}

/*
 * Cache the CallerAccess result obtained from doing a fileserver operation
 * that returned a vnode status for a particular key.  If a callback break
 * occurs whilst the operation was in progress then we have to ditch the cache
 * as the ACL *may* have changed.
 */
void afs_cache_permit(struct afs_vnode *vnode, struct key *key,
		      unsigned int cb_break, struct afs_status_cb *scb)
{
	struct afs_permits *permits, *xpermits, *replacement, *zap, *new = NULL;
	afs_access_t caller_access = scb->status.caller_access;
	size_t size = 0;
	bool changed = false;
	int i, j;

	_enter("{%llx:%llu},%x,%x",
	       vnode->fid.vid, vnode->fid.vnode, key_serial(key), caller_access);

	rcu_read_lock();

	/* Check for the common case first: We got back the same access as last
	 * time we tried and already have it recorded.
	 */
	permits = rcu_dereference(vnode->permit_cache);
	if (permits) {
		if (!permits->invalidated) {
			for (i = 0; i < permits->nr_permits; i++) {
				if (permits->permits[i].key < key)
					continue;
				if (permits->permits[i].key > key)
					break;
				if (permits->permits[i].access != caller_access) {
					changed = true;
					break;
				}

				if (afs_cb_is_broken(cb_break, vnode,
						     rcu_dereference(vnode->cb_interest))) {
					changed = true;
					break;
				}

				/* The cache is still good. */
				rcu_read_unlock();
				return;
			}
		}

		changed |= permits->invalidated;
		size = permits->nr_permits;

		/* If this set of permits is now wrong, clear the permits
		 * pointer so that no one tries to use the stale information.
		 */
		if (changed) {
			spin_lock(&vnode->lock);
			if (permits != rcu_access_pointer(vnode->permit_cache))
				goto someone_else_changed_it_unlock;
			RCU_INIT_POINTER(vnode->permit_cache, NULL);
			spin_unlock(&vnode->lock);

			afs_put_permits(permits);
			permits = NULL;
			size = 0;
		}
	}

	if (afs_cb_is_broken(cb_break, vnode, rcu_dereference(vnode->cb_interest)))
		goto someone_else_changed_it;

	/* We need a ref on any permits list we want to copy as we'll have to
	 * drop the lock to do memory allocation.
	 */
	if (permits && !refcount_inc_not_zero(&permits->usage))
		goto someone_else_changed_it;

	rcu_read_unlock();

	/* Speculatively create a new list with the revised permission set.  We
	 * discard this if we find an extant match already in the hash, but
	 * it's easier to compare with memcmp this way.
	 *
	 * We fill in the key pointers at this time, but we don't get the refs
	 * yet.
	 */
	size++;
	new = kzalloc(sizeof(struct afs_permits) +
		      sizeof(struct afs_permit) * size, GFP_NOFS);
	if (!new)
		goto out_put;

	refcount_set(&new->usage, 1);
	new->nr_permits = size;
	i = j = 0;
	if (permits) {
		for (i = 0; i < permits->nr_permits; i++) {
			if (j == i && permits->permits[i].key > key) {
				new->permits[j].key = key;
				new->permits[j].access = caller_access;
				j++;
			}
			new->permits[j].key = permits->permits[i].key;
			new->permits[j].access = permits->permits[i].access;
			j++;
		}
	}

	if (j == i) {
		new->permits[j].key = key;
		new->permits[j].access = caller_access;
	}

	afs_hash_permits(new);

	/* Now see if the permit list we want is actually already available */
	spin_lock(&afs_permits_lock);

	hash_for_each_possible(afs_permits_cache, xpermits, hash_node, new->h) {
		if (xpermits->h != new->h ||
		    xpermits->invalidated ||
		    xpermits->nr_permits != new->nr_permits ||
		    memcmp(xpermits->permits, new->permits,
			   new->nr_permits * sizeof(struct afs_permit)) != 0)
			continue;

		if (refcount_inc_not_zero(&xpermits->usage)) {
			replacement = xpermits;
			goto found;
		}

		break;
	}

	for (i = 0; i < new->nr_permits; i++)
		key_get(new->permits[i].key);
	hash_add_rcu(afs_permits_cache, &new->hash_node, new->h);
	replacement = new;
	new = NULL;

found:
	spin_unlock(&afs_permits_lock);

	kfree(new);

	rcu_read_lock();
	spin_lock(&vnode->lock);
	zap = rcu_access_pointer(vnode->permit_cache);
	if (!afs_cb_is_broken(cb_break, vnode, rcu_dereference(vnode->cb_interest)) &&
	    zap == permits)
		rcu_assign_pointer(vnode->permit_cache, replacement);
	else
		zap = replacement;
	spin_unlock(&vnode->lock);
	rcu_read_unlock();
	afs_put_permits(zap);
out_put:
	afs_put_permits(permits);
	return;

someone_else_changed_it_unlock:
	spin_unlock(&vnode->lock);
someone_else_changed_it:
	/* Someone else changed the cache under us - don't recheck at this
	 * time.
	 */
	rcu_read_unlock();
	return;
}

/*
 * check with the fileserver to see if the directory or parent directory is
 * permitted to be accessed with this authorisation, and if so, what access it
 * is granted
 */
int afs_check_permit(struct afs_vnode *vnode, struct key *key,
		     afs_access_t *_access)
{
	struct afs_permits *permits;
	bool valid = false;
	int i, ret;

	_enter("{%llx:%llu},%x",
	       vnode->fid.vid, vnode->fid.vnode, key_serial(key));

	/* check the permits to see if we've got one yet */
	if (key == vnode->volume->cell->anonymous_key) {
		_debug("anon");
		*_access = vnode->status.anon_access;
		valid = true;
	} else {
		rcu_read_lock();
		permits = rcu_dereference(vnode->permit_cache);
		if (permits) {
			for (i = 0; i < permits->nr_permits; i++) {
				if (permits->permits[i].key < key)
					continue;
				if (permits->permits[i].key > key)
					break;

				*_access = permits->permits[i].access;
				valid = !permits->invalidated;
				break;
			}
		}
		rcu_read_unlock();
	}

	if (!valid) {
		/* Check the status on the file we're actually interested in
		 * (the post-processing will cache the result).
		 */
		_debug("no valid permit");

		ret = afs_fetch_status(vnode, key, false, _access);
		if (ret < 0) {
			*_access = 0;
			_leave(" = %d", ret);
			return ret;
		}
	}

	_leave(" = 0 [access %x]", *_access);
	return 0;
}

/*
 * check the permissions on an AFS file
 * - AFS ACLs are attached to directories only, and a file is controlled by its
 *   parent directory's ACL
 */
int afs_permission(struct inode *inode, int mask)
{
	struct afs_vnode *vnode = AFS_FS_I(inode);
	afs_access_t uninitialized_var(access);
	struct key *key;
	int ret;

	if (mask & MAY_NOT_BLOCK)
		return -ECHILD;

	_enter("{{%llx:%llu},%lx},%x,",
	       vnode->fid.vid, vnode->fid.vnode, vnode->flags, mask);

	key = afs_request_key(vnode->volume->cell);
	if (IS_ERR(key)) {
		_leave(" = %ld [key]", PTR_ERR(key));
		return PTR_ERR(key);
	}

	ret = afs_validate(vnode, key);
	if (ret < 0)
		goto error;

	/* check the permits to see if we've got one yet */
	ret = afs_check_permit(vnode, key, &access);
	if (ret < 0)
		goto error;

	/* interpret the access mask */
	_debug("REQ %x ACC %x on %s",
	       mask, access, S_ISDIR(inode->i_mode) ? "dir" : "file");

	if (S_ISDIR(inode->i_mode)) {
		if (mask & (MAY_EXEC | MAY_READ | MAY_CHDIR)) {
			if (!(access & AFS_ACE_LOOKUP))
				goto permission_denied;
		}
		if (mask & MAY_WRITE) {
			if (!(access & (AFS_ACE_DELETE | /* rmdir, unlink, rename from */
					AFS_ACE_INSERT))) /* create, mkdir, symlink, rename to */
				goto permission_denied;
		}
	} else {
		if (!(access & AFS_ACE_LOOKUP))
			goto permission_denied;
		if ((mask & MAY_EXEC) && !(inode->i_mode & S_IXUSR))
			goto permission_denied;
		if (mask & (MAY_EXEC | MAY_READ)) {
			if (!(access & AFS_ACE_READ))
				goto permission_denied;
			if (!(inode->i_mode & S_IRUSR))
				goto permission_denied;
		} else if (mask & MAY_WRITE) {
			if (!(access & AFS_ACE_WRITE))
				goto permission_denied;
			if (!(inode->i_mode & S_IWUSR))
				goto permission_denied;
		}
	}

	key_put(key);
	_leave(" = %d", ret);
	return ret;

permission_denied:
	ret = -EACCES;
error:
	key_put(key);
	_leave(" = %d", ret);
	return ret;
}

void __exit afs_clean_up_permit_cache(void)
{
	int i;

	for (i = 0; i < HASH_SIZE(afs_permits_cache); i++)
		WARN_ON_ONCE(!hlist_empty(&afs_permits_cache[i]));

}
