// 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);
static DEFINE_MUTEX(afs_key_lock);

/*
 * Allocate a key to use as a placeholder for anonymous user security.
 */
static int afs_alloc_anon_key(struct afs_cell *cell)
{
	struct key *key;

	mutex_lock(&afs_key_lock);
	key = cell->anonymous_key;
	if (!key) {
		key = rxrpc_get_null_key(cell->key_desc);
		if (!IS_ERR(key))
			cell->anonymous_key = key;
	}
	mutex_unlock(&afs_key_lock);

	if (IS_ERR(key))
		return PTR_ERR(key);

	_debug("anon key %p{%x}",
	       cell->anonymous_key, key_serial(cell->anonymous_key));
	return 0;
}

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

	_enter("{%s}", cell->key_desc);

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

		if (!cell->anonymous_key) {
			ret = afs_alloc_anon_key(cell);
			if (ret < 0)
				return ERR_PTR(ret);
		}

		/* 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;
	}
}

/*
 * Get a key when pathwalk is in rcuwalk mode.
 */
struct key *afs_request_key_rcu(struct afs_cell *cell)
{
	struct key *key;

	_enter("{%s}", cell->key_desc);

	_debug("key %s", cell->key_desc);
	key = request_key_net_rcu(&key_type_rxrpc, cell->key_desc,
				  cell->net->net);
	if (IS_ERR(key)) {
		if (PTR_ERR(key) != -ENOKEY) {
			_leave(" = %ld", PTR_ERR(key));
			return key;
		}

		/* act as anonymous user */
		if (!cell->anonymous_key)
			return NULL; /* Need to allocate */
		_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)) {
					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))
		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_flex(*new, permits, 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) && 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;
}

static bool afs_check_permit_rcu(struct afs_vnode *vnode, struct key *key,
				 afs_access_t *_access)
{
	const struct afs_permits *permits;
	int i;

	_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) {
		*_access = vnode->status.anon_access;
		_leave(" = t [anon %x]", *_access);
		return true;
	}

	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;
			_leave(" = %u [perm %x]", !permits->invalidated, *_access);
			return !permits->invalidated;
		}
	}

	_leave(" = f");
	return false;
}

/*
 * 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 mnt_idmap *idmap, struct inode *inode,
		   int mask)
{
	struct afs_vnode *vnode = AFS_FS_I(inode);
	afs_access_t access;
	struct key *key;
	int ret = 0;

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

	if (mask & MAY_NOT_BLOCK) {
		key = afs_request_key_rcu(vnode->volume->cell);
		if (IS_ERR_OR_NULL(key))
			return -ECHILD;

		ret = -ECHILD;
		if (!afs_check_validity(vnode) ||
		    !afs_check_permit_rcu(vnode, key, &access))
			goto error;
	} else {
		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");

	ret = 0;
	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]));

}
