/*
 * /proc/uid support
 */

#include <linux/cpufreq_times.h>
#include <linux/fs.h>
#include <linux/hashtable.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/rtmutex.h>
#include <linux/sched.h>
#include <linux/seq_file.h>
#include <linux/slab.h>
#include "internal.h"

static struct proc_dir_entry *proc_uid;

#define UID_HASH_BITS 10

static DECLARE_HASHTABLE(proc_uid_hash_table, UID_HASH_BITS);

/*
 * use rt_mutex here to avoid priority inversion between high-priority readers
 * of these files and tasks calling proc_register_uid().
 */
static DEFINE_RT_MUTEX(proc_uid_lock); /* proc_uid_hash_table */

struct uid_hash_entry {
	uid_t uid;
	struct hlist_node hash;
};

/* Caller must hold proc_uid_lock */
static bool uid_hash_entry_exists_locked(uid_t uid)
{
	struct uid_hash_entry *entry;

	hash_for_each_possible(proc_uid_hash_table, entry, hash, uid) {
		if (entry->uid == uid)
			return true;
	}
	return false;
}

void proc_register_uid(kuid_t kuid)
{
	struct uid_hash_entry *entry;
	bool exists;
	uid_t uid = from_kuid_munged(current_user_ns(), kuid);

	rt_mutex_lock(&proc_uid_lock);
	exists = uid_hash_entry_exists_locked(uid);
	rt_mutex_unlock(&proc_uid_lock);
	if (exists)
		return;

	entry = kzalloc(sizeof(struct uid_hash_entry), GFP_KERNEL);
	if (!entry)
		return;
	entry->uid = uid;

	rt_mutex_lock(&proc_uid_lock);
	if (uid_hash_entry_exists_locked(uid))
		kfree(entry);
	else
		hash_add(proc_uid_hash_table, &entry->hash, uid);
	rt_mutex_unlock(&proc_uid_lock);
}

struct uid_entry {
	const char *name;
	int len;
	umode_t mode;
	const struct inode_operations *iop;
	const struct file_operations *fop;
};

#define NOD(NAME, MODE, IOP, FOP) {			\
	.name	= (NAME),				\
	.len	= sizeof(NAME) - 1,			\
	.mode	= MODE,					\
	.iop	= IOP,					\
	.fop	= FOP,					\
}

#ifdef CONFIG_CPU_FREQ_TIMES
static const struct file_operations proc_uid_time_in_state_operations = {
	.open		= single_uid_time_in_state_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};
#endif

static const struct uid_entry uid_base_stuff[] = {
#ifdef CONFIG_CPU_FREQ_TIMES
	NOD("time_in_state", 0444, NULL, &proc_uid_time_in_state_operations),
#endif
};

static const struct inode_operations proc_uid_def_inode_operations = {
	.setattr	= proc_setattr,
};

static struct inode *proc_uid_make_inode(struct super_block *sb, kuid_t kuid)
{
	struct inode *inode;

	inode = new_inode(sb);
	if (!inode)
		return NULL;

	inode->i_ino = get_next_ino();
	inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
	inode->i_op = &proc_uid_def_inode_operations;
	inode->i_uid = kuid;

	return inode;
}

static int proc_uident_instantiate(struct inode *dir, struct dentry *dentry,
				   struct task_struct *unused, const void *ptr)
{
	const struct uid_entry *u = ptr;
	struct inode *inode;

	inode = proc_uid_make_inode(dir->i_sb, dir->i_uid);
	if (!inode)
		return -ENOENT;

	inode->i_mode = u->mode;
	if (S_ISDIR(inode->i_mode))
		set_nlink(inode, 2);
	if (u->iop)
		inode->i_op = u->iop;
	if (u->fop)
		inode->i_fop = u->fop;
	d_add(dentry, inode);
	return 0;
}

static struct dentry *proc_uid_base_lookup(struct inode *dir,
					   struct dentry *dentry,
					   unsigned int flags)
{
	const struct uid_entry *u, *last;
	unsigned int nents = ARRAY_SIZE(uid_base_stuff);

	if (nents == 0)
		return ERR_PTR(-ENOENT);

	last = &uid_base_stuff[nents - 1];
	for (u = uid_base_stuff; u <= last; u++) {
		if (u->len != dentry->d_name.len)
			continue;
		if (!memcmp(dentry->d_name.name, u->name, u->len))
			break;
	}
	if (u > last)
		return ERR_PTR(-ENOENT);

	return ERR_PTR(proc_uident_instantiate(dir, dentry, NULL, u));
}

static int proc_uid_base_readdir(struct file *file, struct dir_context *ctx)
{
	unsigned int nents = ARRAY_SIZE(uid_base_stuff);
	const struct uid_entry *u;

	if (!dir_emit_dots(file, ctx))
		return 0;

	if (ctx->pos >= nents + 2)
		return 0;

	for (u = uid_base_stuff + (ctx->pos - 2);
	     u <= uid_base_stuff + nents - 1; u++) {
		if (!proc_fill_cache(file, ctx, u->name, u->len,
				     proc_uident_instantiate, NULL, u))
			break;
		ctx->pos++;
	}

	return 0;
}

static const struct inode_operations proc_uid_base_inode_operations = {
	.lookup		= proc_uid_base_lookup,
	.setattr	= proc_setattr,
};

static const struct file_operations proc_uid_base_operations = {
	.read		= generic_read_dir,
	.iterate	= proc_uid_base_readdir,
	.llseek		= default_llseek,
};

static int proc_uid_instantiate(struct inode *dir, struct dentry *dentry,
				struct task_struct *unused, const void *ptr)
{
	unsigned int i, len;
	nlink_t nlinks;
	kuid_t *kuid = (kuid_t *)ptr;
	struct inode *inode = proc_uid_make_inode(dir->i_sb, *kuid);

	if (!inode)
		return -ENOENT;

	inode->i_mode = S_IFDIR | 0555;
	inode->i_op = &proc_uid_base_inode_operations;
	inode->i_fop = &proc_uid_base_operations;
	inode->i_flags |= S_IMMUTABLE;

	nlinks = 2;
	len = ARRAY_SIZE(uid_base_stuff);
	for (i = 0; i < len; ++i) {
		if (S_ISDIR(uid_base_stuff[i].mode))
			++nlinks;
	}
	set_nlink(inode, nlinks);

	d_add(dentry, inode);

	return 0;
}

static int proc_uid_readdir(struct file *file, struct dir_context *ctx)
{
	int last_shown, i;
	unsigned long bkt;
	struct uid_hash_entry *entry;

	if (!dir_emit_dots(file, ctx))
		return 0;

	i = 0;
	last_shown = ctx->pos - 2;
	rt_mutex_lock(&proc_uid_lock);
	hash_for_each(proc_uid_hash_table, bkt, entry, hash) {
		int len;
		char buf[PROC_NUMBUF];

		if (i < last_shown)
			continue;
		len = snprintf(buf, sizeof(buf), "%u", entry->uid);
		if (!proc_fill_cache(file, ctx, buf, len,
				     proc_uid_instantiate, NULL, &entry->uid))
			break;
		i++;
		ctx->pos++;
	}
	rt_mutex_unlock(&proc_uid_lock);
	return 0;
}

static struct dentry *proc_uid_lookup(struct inode *dir, struct dentry *dentry,
				      unsigned int flags)
{
	int result = -ENOENT;

	uid_t uid = name_to_int(&dentry->d_name);
	bool uid_exists;

	rt_mutex_lock(&proc_uid_lock);
	uid_exists = uid_hash_entry_exists_locked(uid);
	rt_mutex_unlock(&proc_uid_lock);
	if (uid_exists) {
		kuid_t kuid = make_kuid(current_user_ns(), uid);

		result = proc_uid_instantiate(dir, dentry, NULL, &kuid);
	}
	return ERR_PTR(result);
}

static const struct file_operations proc_uid_operations = {
	.read		= generic_read_dir,
	.iterate	= proc_uid_readdir,
	.llseek		= default_llseek,
};

static const struct inode_operations proc_uid_inode_operations = {
	.lookup		= proc_uid_lookup,
	.setattr	= proc_setattr,
};

int __init proc_uid_init(void)
{
	proc_uid = proc_mkdir("uid", NULL);
	if (!proc_uid)
		return -ENOMEM;
	proc_uid->proc_iops = &proc_uid_inode_operations;
	proc_uid->proc_fops = &proc_uid_operations;

	return 0;
}
