/*
 * security/tomoyo/realpath.c
 *
 * Get the canonicalized absolute pathnames. The basis for TOMOYO.
 *
 * Copyright (C) 2005-2009  NTT DATA CORPORATION
 *
 * Version: 2.2.0-pre   2009/02/01
 *
 */

#include <linux/types.h>
#include <linux/mount.h>
#include <linux/mnt_namespace.h>
#include "common.h"
#include "realpath.h"

/**
 * tomoyo_encode: Convert binary string to ascii string.
 *
 * @buffer:  Buffer for ASCII string.
 * @buflen:  Size of @buffer.
 * @str:     Binary string.
 *
 * Returns 0 on success, -ENOMEM otherwise.
 */
int tomoyo_encode(char *buffer, int buflen, const char *str)
{
	while (1) {
		const unsigned char c = *(unsigned char *) str++;

		if (tomoyo_is_valid(c)) {
			if (--buflen <= 0)
				break;
			*buffer++ = (char) c;
			if (c != '\\')
				continue;
			if (--buflen <= 0)
				break;
			*buffer++ = (char) c;
			continue;
		}
		if (!c) {
			if (--buflen <= 0)
				break;
			*buffer = '\0';
			return 0;
		}
		buflen -= 4;
		if (buflen <= 0)
			break;
		*buffer++ = '\\';
		*buffer++ = (c >> 6) + '0';
		*buffer++ = ((c >> 3) & 7) + '0';
		*buffer++ = (c & 7) + '0';
	}
	return -ENOMEM;
}

/**
 * tomoyo_realpath_from_path2 - Returns realpath(3) of the given dentry but ignores chroot'ed root.
 *
 * @path:        Pointer to "struct path".
 * @newname:     Pointer to buffer to return value in.
 * @newname_len: Size of @newname.
 *
 * Returns 0 on success, negative value otherwise.
 *
 * If dentry is a directory, trailing '/' is appended.
 * Characters out of 0x20 < c < 0x7F range are converted to
 * \ooo style octal string.
 * Character \ is converted to \\ string.
 */
int tomoyo_realpath_from_path2(struct path *path, char *newname,
			       int newname_len)
{
	int error = -ENOMEM;
	struct dentry *dentry = path->dentry;
	char *sp;

	if (!dentry || !path->mnt || !newname || newname_len <= 2048)
		return -EINVAL;
	if (dentry->d_op && dentry->d_op->d_dname) {
		/* For "socket:[\$]" and "pipe:[\$]". */
		static const int offset = 1536;
		sp = dentry->d_op->d_dname(dentry, newname + offset,
					   newname_len - offset);
	} else {
		/* Taken from d_namespace_path(). */
		struct path root;
		struct path ns_root = { };
		struct path tmp;

		read_lock(&current->fs->lock);
		root = current->fs->root;
		path_get(&root);
		read_unlock(&current->fs->lock);
		spin_lock(&vfsmount_lock);
		if (root.mnt && root.mnt->mnt_ns)
			ns_root.mnt = mntget(root.mnt->mnt_ns->root);
		if (ns_root.mnt)
			ns_root.dentry = dget(ns_root.mnt->mnt_root);
		spin_unlock(&vfsmount_lock);
		spin_lock(&dcache_lock);
		tmp = ns_root;
		sp = __d_path(path, &tmp, newname, newname_len);
		spin_unlock(&dcache_lock);
		path_put(&root);
		path_put(&ns_root);
	}
	if (IS_ERR(sp))
		error = PTR_ERR(sp);
	else
		error = tomoyo_encode(newname, sp - newname, sp);
	/* Append trailing '/' if dentry is a directory. */
	if (!error && dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode)
	    && *newname) {
		sp = newname + strlen(newname);
		if (*(sp - 1) != '/') {
			if (sp < newname + newname_len - 4) {
				*sp++ = '/';
				*sp = '\0';
			} else {
				error = -ENOMEM;
			}
		}
	}
	if (error)
		printk(KERN_WARNING "tomoyo_realpath: Pathname too long.\n");
	return error;
}

/**
 * tomoyo_realpath_from_path - Returns realpath(3) of the given pathname but ignores chroot'ed root.
 *
 * @path: Pointer to "struct path".
 *
 * Returns the realpath of the given @path on success, NULL otherwise.
 *
 * These functions use tomoyo_alloc(), so the caller must call tomoyo_free()
 * if these functions didn't return NULL.
 */
char *tomoyo_realpath_from_path(struct path *path)
{
	char *buf = tomoyo_alloc(sizeof(struct tomoyo_page_buffer));

	BUILD_BUG_ON(sizeof(struct tomoyo_page_buffer)
		     <= TOMOYO_MAX_PATHNAME_LEN - 1);
	if (!buf)
		return NULL;
	if (tomoyo_realpath_from_path2(path, buf,
				       TOMOYO_MAX_PATHNAME_LEN - 1) == 0)
		return buf;
	tomoyo_free(buf);
	return NULL;
}

/**
 * tomoyo_realpath - Get realpath of a pathname.
 *
 * @pathname: The pathname to solve.
 *
 * Returns the realpath of @pathname on success, NULL otherwise.
 */
char *tomoyo_realpath(const char *pathname)
{
	struct nameidata nd;

	if (pathname && path_lookup(pathname, LOOKUP_FOLLOW, &nd) == 0) {
		char *buf = tomoyo_realpath_from_path(&nd.path);
		path_put(&nd.path);
		return buf;
	}
	return NULL;
}

/**
 * tomoyo_realpath_nofollow - Get realpath of a pathname.
 *
 * @pathname: The pathname to solve.
 *
 * Returns the realpath of @pathname on success, NULL otherwise.
 */
char *tomoyo_realpath_nofollow(const char *pathname)
{
	struct nameidata nd;

	if (pathname && path_lookup(pathname, 0, &nd) == 0) {
		char *buf = tomoyo_realpath_from_path(&nd.path);
		path_put(&nd.path);
		return buf;
	}
	return NULL;
}

/* Memory allocated for non-string data. */
static unsigned int tomoyo_allocated_memory_for_elements;
/* Quota for holding non-string data. */
static unsigned int tomoyo_quota_for_elements;

/**
 * tomoyo_alloc_element - Allocate permanent memory for structures.
 *
 * @size: Size in bytes.
 *
 * Returns pointer to allocated memory on success, NULL otherwise.
 *
 * Memory has to be zeroed.
 * The RAM is chunked, so NEVER try to kfree() the returned pointer.
 */
void *tomoyo_alloc_element(const unsigned int size)
{
	static char *buf;
	static DEFINE_MUTEX(lock);
	static unsigned int buf_used_len = PATH_MAX;
	char *ptr = NULL;
	/*Assumes sizeof(void *) >= sizeof(long) is true. */
	const unsigned int word_aligned_size
		= roundup(size, max(sizeof(void *), sizeof(long)));
	if (word_aligned_size > PATH_MAX)
		return NULL;
	/***** EXCLUSIVE SECTION START *****/
	mutex_lock(&lock);
	if (buf_used_len + word_aligned_size > PATH_MAX) {
		if (!tomoyo_quota_for_elements ||
		    tomoyo_allocated_memory_for_elements
		    + PATH_MAX <= tomoyo_quota_for_elements)
			ptr = kzalloc(PATH_MAX, GFP_KERNEL);
		if (!ptr) {
			printk(KERN_WARNING "ERROR: Out of memory "
			       "for tomoyo_alloc_element().\n");
			if (!tomoyo_policy_loaded)
				panic("MAC Initialization failed.\n");
		} else {
			buf = ptr;
			tomoyo_allocated_memory_for_elements += PATH_MAX;
			buf_used_len = word_aligned_size;
			ptr = buf;
		}
	} else if (word_aligned_size) {
		int i;
		ptr = buf + buf_used_len;
		buf_used_len += word_aligned_size;
		for (i = 0; i < word_aligned_size; i++) {
			if (!ptr[i])
				continue;
			printk(KERN_ERR "WARNING: Reserved memory was tainted! "
			       "The system might go wrong.\n");
			ptr[i] = '\0';
		}
	}
	mutex_unlock(&lock);
	/***** EXCLUSIVE SECTION END *****/
	return ptr;
}

/* Memory allocated for string data in bytes. */
static unsigned int tomoyo_allocated_memory_for_savename;
/* Quota for holding string data in bytes. */
static unsigned int tomoyo_quota_for_savename;

/*
 * TOMOYO uses this hash only when appending a string into the string
 * table. Frequency of appending strings is very low. So we don't need
 * large (e.g. 64k) hash size. 256 will be sufficient.
 */
#define TOMOYO_MAX_HASH 256

/* Structure for string data. */
struct tomoyo_name_entry {
	struct list_head list;
	struct tomoyo_path_info entry;
};

/* Structure for available memory region. */
struct tomoyo_free_memory_block_list {
	struct list_head list;
	char *ptr;             /* Pointer to a free area. */
	int len;               /* Length of the area.     */
};

/*
 * The list for "struct tomoyo_name_entry".
 *
 * This list is updated only inside tomoyo_save_name(), thus
 * no global mutex exists.
 */
static struct list_head tomoyo_name_list[TOMOYO_MAX_HASH];

/**
 * tomoyo_save_name - Allocate permanent memory for string data.
 *
 * @name: The string to store into the permernent memory.
 *
 * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise.
 *
 * The RAM is shared, so NEVER try to modify or kfree() the returned name.
 */
const struct tomoyo_path_info *tomoyo_save_name(const char *name)
{
	static LIST_HEAD(fmb_list);
	static DEFINE_MUTEX(lock);
	struct tomoyo_name_entry *ptr;
	unsigned int hash;
	/* fmb contains available size in bytes.
	   fmb is removed from the fmb_list when fmb->len becomes 0. */
	struct tomoyo_free_memory_block_list *fmb;
	int len;
	char *cp;

	if (!name)
		return NULL;
	len = strlen(name) + 1;
	if (len > TOMOYO_MAX_PATHNAME_LEN) {
		printk(KERN_WARNING "ERROR: Name too long "
		       "for tomoyo_save_name().\n");
		return NULL;
	}
	hash = full_name_hash((const unsigned char *) name, len - 1);
	/***** EXCLUSIVE SECTION START *****/
	mutex_lock(&lock);
	list_for_each_entry(ptr, &tomoyo_name_list[hash % TOMOYO_MAX_HASH],
			     list) {
		if (hash == ptr->entry.hash && !strcmp(name, ptr->entry.name))
			goto out;
	}
	list_for_each_entry(fmb, &fmb_list, list) {
		if (len <= fmb->len)
			goto ready;
	}
	if (!tomoyo_quota_for_savename ||
	    tomoyo_allocated_memory_for_savename + PATH_MAX
	    <= tomoyo_quota_for_savename)
		cp = kzalloc(PATH_MAX, GFP_KERNEL);
	else
		cp = NULL;
	fmb = kzalloc(sizeof(*fmb), GFP_KERNEL);
	if (!cp || !fmb) {
		kfree(cp);
		kfree(fmb);
		printk(KERN_WARNING "ERROR: Out of memory "
		       "for tomoyo_save_name().\n");
		if (!tomoyo_policy_loaded)
			panic("MAC Initialization failed.\n");
		ptr = NULL;
		goto out;
	}
	tomoyo_allocated_memory_for_savename += PATH_MAX;
	list_add(&fmb->list, &fmb_list);
	fmb->ptr = cp;
	fmb->len = PATH_MAX;
 ready:
	ptr = tomoyo_alloc_element(sizeof(*ptr));
	if (!ptr)
		goto out;
	ptr->entry.name = fmb->ptr;
	memmove(fmb->ptr, name, len);
	tomoyo_fill_path_info(&ptr->entry);
	fmb->ptr += len;
	fmb->len -= len;
	list_add_tail(&ptr->list, &tomoyo_name_list[hash % TOMOYO_MAX_HASH]);
	if (fmb->len == 0) {
		list_del(&fmb->list);
		kfree(fmb);
	}
 out:
	mutex_unlock(&lock);
	/***** EXCLUSIVE SECTION END *****/
	return ptr ? &ptr->entry : NULL;
}

/**
 * tomoyo_realpath_init - Initialize realpath related code.
 */
void __init tomoyo_realpath_init(void)
{
	int i;

	BUILD_BUG_ON(TOMOYO_MAX_PATHNAME_LEN > PATH_MAX);
	for (i = 0; i < TOMOYO_MAX_HASH; i++)
		INIT_LIST_HEAD(&tomoyo_name_list[i]);
	INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list);
	tomoyo_kernel_domain.domainname = tomoyo_save_name(TOMOYO_ROOT_NAME);
	list_add_tail(&tomoyo_kernel_domain.list, &tomoyo_domain_list);
	down_read(&tomoyo_domain_list_lock);
	if (tomoyo_find_domain(TOMOYO_ROOT_NAME) != &tomoyo_kernel_domain)
		panic("Can't register tomoyo_kernel_domain");
	up_read(&tomoyo_domain_list_lock);
}

/* Memory allocated for temporary purpose. */
static atomic_t tomoyo_dynamic_memory_size;

/**
 * tomoyo_alloc - Allocate memory for temporary purpose.
 *
 * @size: Size in bytes.
 *
 * Returns pointer to allocated memory on success, NULL otherwise.
 */
void *tomoyo_alloc(const size_t size)
{
	void *p = kzalloc(size, GFP_KERNEL);
	if (p)
		atomic_add(ksize(p), &tomoyo_dynamic_memory_size);
	return p;
}

/**
 * tomoyo_free - Release memory allocated by tomoyo_alloc().
 *
 * @p: Pointer returned by tomoyo_alloc(). May be NULL.
 *
 * Returns nothing.
 */
void tomoyo_free(const void *p)
{
	if (p) {
		atomic_sub(ksize(p), &tomoyo_dynamic_memory_size);
		kfree(p);
	}
}

/**
 * tomoyo_read_memory_counter - Check for memory usage in bytes.
 *
 * @head: Pointer to "struct tomoyo_io_buffer".
 *
 * Returns memory usage.
 */
int tomoyo_read_memory_counter(struct tomoyo_io_buffer *head)
{
	if (!head->read_eof) {
		const unsigned int shared
			= tomoyo_allocated_memory_for_savename;
		const unsigned int private
			= tomoyo_allocated_memory_for_elements;
		const unsigned int dynamic
			= atomic_read(&tomoyo_dynamic_memory_size);
		char buffer[64];

		memset(buffer, 0, sizeof(buffer));
		if (tomoyo_quota_for_savename)
			snprintf(buffer, sizeof(buffer) - 1,
				 "   (Quota: %10u)",
				 tomoyo_quota_for_savename);
		else
			buffer[0] = '\0';
		tomoyo_io_printf(head, "Shared:  %10u%s\n", shared, buffer);
		if (tomoyo_quota_for_elements)
			snprintf(buffer, sizeof(buffer) - 1,
				 "   (Quota: %10u)",
				 tomoyo_quota_for_elements);
		else
			buffer[0] = '\0';
		tomoyo_io_printf(head, "Private: %10u%s\n", private, buffer);
		tomoyo_io_printf(head, "Dynamic: %10u\n", dynamic);
		tomoyo_io_printf(head, "Total:   %10u\n",
				 shared + private + dynamic);
		head->read_eof = true;
	}
	return 0;
}

/**
 * tomoyo_write_memory_quota - Set memory quota.
 *
 * @head: Pointer to "struct tomoyo_io_buffer".
 *
 * Returns 0.
 */
int tomoyo_write_memory_quota(struct tomoyo_io_buffer *head)
{
	char *data = head->write_buf;
	unsigned int size;

	if (sscanf(data, "Shared: %u", &size) == 1)
		tomoyo_quota_for_savename = size;
	else if (sscanf(data, "Private: %u", &size) == 1)
		tomoyo_quota_for_elements = size;
	return 0;
}
