// SPDX-License-Identifier: GPL-2.0
/*
 * Container Security Monitor module
 *
 * Copyright (c) 2018 Google, Inc
 */

#include "monitor.h"

#include <linux/atomic.h>
#include <linux/audit.h>
#include <linux/file.h>
#include <linux/highmem.h>
#include <linux/mempool.h>
#include <linux/mm.h>
#include <linux/mount.h>
#include <linux/notifier.h>
#include <linux/net.h>
#include <linux/path.h>
#include <linux/pid.h>
#include <linux/pid_namespace.h>
#include <linux/random.h>
#include <linux/rcupdate.h>
#include <linux/sched.h>
#include <linux/sched/signal.h>
#include <linux/sched/task.h>
#include <linux/slab.h>
#include <linux/socket.h>
#include <linux/timekeeping.h>
#include <linux/vmalloc.h>
#include <linux/workqueue.h>
#include <linux/xattr.h>
#include <net/ipv6.h>
#include <net/sock.h>
#include <net/tcp.h>
#include <overlayfs/overlayfs.h>
#include <uapi/linux/magic.h>
#include <uapi/asm/mman.h>

/* Configuration options for execute collector. */
struct execute_config csm_execute_config;

/* unique atomic value for the machine boot instance */
static atomic_t machine_rand = ATOMIC_INIT(0);

/* sequential container identifier */
static atomic_t contid = ATOMIC_INIT(0);

/* Generation id for each enumeration invocation. */
static atomic_t enumeration_count = ATOMIC_INIT(0);

struct file_provenance {
	/* pid of the process doing the first write. */
	pid_t tgid;
	/* start_time of the process to uniquely identify it. */
	u64 start_time;
};

struct csm_enumerate_processes_work_data {
	struct work_struct work;
	int enumeration_count;
};

static void *kmap_argument_stack(struct linux_binprm *bprm, void **ctx)
{
	char *argv;
	int err;
	unsigned long i, pos, count;
	void *map;
	struct page *page;

	/* vma_pages() returns the number of pages reserved for the stack */
	count = vma_pages(bprm->vma);

	if (likely(count == 1)) {
		err = get_user_pages_remote(bprm->mm, bprm->p, 1,
					    FOLL_FORCE, &page, NULL);
		if (err != 1)
			return NULL;

		argv = kmap(page);
		*ctx = page;
	} else {
		/*
		 * If more than one pages is needed, copy all of them to a set
		 * of pages. Parsing the argument across kmap pages in different
		 * addresses would make it impractical.
		 */
		argv = vmalloc(count * PAGE_SIZE);
		if (!argv)
			return NULL;

		for (i = 0; i < count; i++) {
			pos = ALIGN_DOWN(bprm->p, PAGE_SIZE) + i * PAGE_SIZE;
			err = get_user_pages_remote(bprm->mm, pos, 1,
						    FOLL_FORCE, &page, NULL);
			if (err <= 0) {
				vfree(argv);
				return NULL;
			}

			map = kmap(page);
			memcpy(argv + i * PAGE_SIZE, map, PAGE_SIZE);
			kunmap(page);
			put_page(page);
		}
		*ctx = bprm;
	}

	return argv;
}

static void kunmap_argument_stack(struct linux_binprm *bprm, void *addr,
				  void *ctx)
{
	struct page *page;

	if (!addr)
		return;

	if (likely(vma_pages(bprm->vma) == 1)) {
		page = (struct page *)ctx;
		kunmap(page);
		put_page(ctx);
	} else {
		vfree(addr);
	}
}

static char *find_array_next_entry(char *array, unsigned long *offset,
				   unsigned long end)
{
	char *entry;
	unsigned long off = *offset;

	if (off >= end)
		return NULL;

	/* Check the entry is null terminated and in bound */
	entry = array + off;
	while (array[off]) {
		if (++off >= end)
			return NULL;
	}

	/* Pass the null byte for the next iteration */
	*offset = off + 1;

	return entry;
}

struct string_arr_ctx {
	struct linux_binprm *bprm;
	void *stack;
};

static size_t get_config_limit(size_t *config_ptr)
{
	lockdep_assert_held_read(&csm_rwsem_config);

	/*
	 * If execute is not enabled, do not capture arguments.
	 * The event proto won't be sent anyway.
	 */
	if (!csm_execute_enabled)
		return 0;

	return *config_ptr;
}

static bool encode_current_argv(pb_ostream_t *stream, const pb_field_t *field,
				void * const *arg)
{
	struct string_arr_ctx *ctx = (struct string_arr_ctx *)*arg;
	int i;
	struct linux_binprm *bprm = ctx->bprm;
	unsigned long offset = bprm->p % PAGE_SIZE;
	unsigned long end = vma_pages(bprm->vma) * PAGE_SIZE;
	char *argv = ctx->stack;
	char *entry;
	size_t limit, used = 0;
	ssize_t ret;

	limit = get_config_limit(&csm_execute_config.argv_limit);
	if (!limit)
		return true;

	for (i = 0; i < bprm->argc; i++) {
		entry = find_array_next_entry(argv, &offset, end);
		if (!entry)
			return false;

		ret = pb_encode_string_field_limit(stream, field,
						   (void * const *)&entry,
						   limit - used);
		if (ret < 0)
			return false;

		used += ret;

		if (used >= limit)
			break;
	}

	return true;
}

static bool check_envp_allowlist(char *envp)
{
	bool ret = false;
	char *strs, *equal;
	size_t str_size, equal_pos;

	/* If execute is not enabled, skip all. */
	if (!csm_execute_enabled)
		goto out;

	/* No filter, allow all. */
	strs = csm_execute_config.envp_allowlist;
	if (!strs) {
		ret = true;
		goto out;
	}

	/*
	 * Identify the key=value separation.
	 * If none exists use the whole string as a key.
	 */
	equal = strchr(envp, '=');
	equal_pos = equal ? (equal - envp) : strlen(envp);

	/* Default to skip if no match found. */
	ret = false;

	do {
		str_size = strlen(strs);

		/*
		 * If the filter length align with the key value equal sign,
		 * it might be a match, check the key value.
		 */
		if (str_size == equal_pos &&
		    !strncmp(strs, envp, str_size)) {
			ret = true;
			goto out;
		}

		strs += str_size + 1;
	} while (*strs != 0);

out:
	return ret;
}

static bool encode_current_envp(pb_ostream_t *stream, const pb_field_t *field,
				void * const *arg)
{
	struct string_arr_ctx *ctx = (struct string_arr_ctx *)*arg;
	int i;
	struct linux_binprm *bprm = ctx->bprm;
	unsigned long offset = bprm->p % PAGE_SIZE;
	unsigned long end = vma_pages(bprm->vma) * PAGE_SIZE;
	char *argv = ctx->stack;
	char *entry;
	size_t limit, used = 0;
	ssize_t ret;

	limit = get_config_limit(&csm_execute_config.envp_limit);
	if (!limit)
		return true;

	/* Skip arguments */
	for (i = 0; i < bprm->argc; i++) {
		if (!find_array_next_entry(argv, &offset, end))
			return false;
	}

	for (i = 0; i < bprm->envc; i++) {
		entry = find_array_next_entry(argv, &offset, end);
		if (!entry)
			return false;

		if (!check_envp_allowlist(entry))
			continue;

		ret = pb_encode_string_field_limit(stream, field,
						   (void * const *)&entry,
						   limit - used);
		if (ret < 0)
			return false;

		used += ret;

		if (used >= limit)
			break;
	}

	return true;
}

static bool is_overlayfs_mounted(struct file *file)
{
	struct vfsmount *mnt;
	struct super_block *mnt_sb;

	mnt = file->f_path.mnt;
	if (mnt == NULL)
		return false;

	mnt_sb = mnt->mnt_sb;
	if (mnt_sb == NULL || mnt_sb->s_magic != OVERLAYFS_SUPER_MAGIC)
		return false;

	return true;
}

/*
 * Before the process starts, identify a possible container by checking if the
 * task is on a pid namespace and the target file is using an overlayfs mounting
 * point. This check is valid for COS and GKE but not all existing containers.
 */
static bool is_possible_container(struct task_struct *task,
				  struct file *file)
{
	if (task_active_pid_ns(task) == &init_pid_ns)
		return false;

	return is_overlayfs_mounted(file);
}

/*
 * Generates a random identifier for this boot instance.
 * This identifier is generated only when needed to increase the entropy
 * available compared to doing it at early boot.
 */
static u32 get_machine_id(void)
{
	u32 machineid, old;

	machineid = atomic_read(&machine_rand);

	if (unlikely(machineid == 0)) {
		machineid = (int)get_random_u32();
		if (machineid == 0)
			machineid = 1;
		old = atomic_cmpxchg(&machine_rand, 0, machineid);

		/* If someone beat us, use their value. */
		if (old != 0)
			machineid = old;
	}

	return (u32)machineid;
}

/*
 * Generate a 128-bit unique identifier for the process by appending:
 *  - A machine identifier unique per boot.
 *  - The start time of the process in nanoseconds.
 *  - The tgid for the set of threads in a process.
 */
static int get_process_uuid(struct task_struct *task, char *buffer, size_t size)
{
	union process_uuid *id = (union process_uuid *)buffer;

	memset(buffer, 0, size);

	if (WARN_ON(size < PROCESS_UUID_SIZE))
		return -EINVAL;

	id->machineid = get_machine_id();
	id->start_time = ktime_mono_to_real(task->group_leader->start_time);
	id->tgid = task_tgid_nr(task);

	return 0;
}

int get_process_uuid_by_pid(pid_t pid_nr, char *buffer, size_t size)
{
	int err;
	struct task_struct *task = NULL;

	rcu_read_lock();
	task = find_task_by_pid_ns(pid_nr, &init_pid_ns);
	if (!task) {
		err = -ENOENT;
		goto out;
	}
	err = get_process_uuid(task, buffer, size);
out:
	rcu_read_unlock();
	return err;
}

static int get_process_uuid_from_xattr(struct file *file, char *buffer,
				       size_t size)
{
	struct dentry *dentry;
	int err;
	struct file_provenance prov;
	union process_uuid *id = (union process_uuid *)buffer;

	memset(buffer, 0, size);

	if (WARN_ON(size < PROCESS_UUID_SIZE))
		return -EINVAL;

	/* The file is part of overlayfs on the upper layer. */
	if (!is_overlayfs_mounted(file))
		return -ENODATA;

	dentry = ovl_dentry_upper(file->f_path.dentry);
	if (!dentry)
		return -ENODATA;

	err = __vfs_getxattr(dentry, dentry->d_inode,
			     XATTR_SECURITY_CSM, &prov, sizeof(prov));
	/* returns -ENODATA if the xattr does not exist. */
	if (err < 0)
		return err;
	if (err != sizeof(prov)) {
		pr_err("unexpected size for xattr: %zu -> %d\n",
		       size, err);
		return -ENODATA;
	}

	id->machineid = get_machine_id();
	id->start_time = prov.start_time;
	id->tgid = prov.tgid;
	return 0;
}

u64 csm_set_contid(struct task_struct *task)
{
	u64 cid;
	struct pid_namespace *ns;

	ns = task_active_pid_ns(task);
	if (WARN_ON(!task->audit) || WARN_ON(!ns))
		return AUDIT_CID_UNSET;

	cid = atomic_inc_return(&contid);
	task->audit->contid = cid;

	/*
	 * If the namespace container-id is not set, use the one assigned
	 * to the first process created.
	 */
	cmpxchg(&ns->cid, 0, cid);
	return cid;
}

u64 csm_get_ns_contid(struct pid_namespace *ns)
{
	if (!ns || !ns->cid)
		return AUDIT_CID_UNSET;

	return ns->cid;
}

union ip_data {
	struct in_addr ip4;
	struct in6_addr ip6;
};

struct file_data {
	void *allocated;
	union ip_data local;
	union ip_data remote;
	char modified_uuid[PROCESS_UUID_SIZE];
};

static void free_file_data(struct file_data *fdata)
{
	free_page((unsigned long)fdata->allocated);
	fdata->allocated = NULL;
}

static void fill_socket_description(struct sockaddr_storage *saddr,
				   union ip_data *idata,
				   schema_SocketIp *schema_socketip)
{
	struct sockaddr_in *sin4 = (struct sockaddr_in *)saddr;
	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)saddr;

	schema_socketip->family = saddr->ss_family;

	switch (saddr->ss_family) {
	case AF_INET:
		schema_socketip->port = ntohs(sin4->sin_port);
		idata->ip4 = sin4->sin_addr;
		schema_socketip->ip.funcs.encode = pb_encode_ip4;
		schema_socketip->ip.arg = &idata->ip4;
		break;
	case AF_INET6:
		schema_socketip->port = ntohs(sin6->sin6_port);
		idata->ip6 = sin6->sin6_addr;
		schema_socketip->ip.funcs.encode = pb_encode_ip6;
		schema_socketip->ip.arg = &idata->ip6;
		break;
	}
}

static int fill_file_overlayfs(struct file *file, schema_File *schema_file,
			       struct file_data *fdata)
{
	struct dentry *dentry;
	int err;
	schema_Overlay *overlayfs;

	/* If not an overlayfs superblock, done. */
	if (!is_overlayfs_mounted(file))
		return 0;

	dentry = file->f_path.dentry;
	schema_file->which_filesystem = schema_File_overlayfs_tag;
	overlayfs = &schema_file->filesystem.overlayfs;
	overlayfs->lower_layer = ovl_dentry_lower(dentry);
	overlayfs->upper_layer = ovl_dentry_upper(dentry);

	err = get_process_uuid_from_xattr(file, fdata->modified_uuid,
					  sizeof(fdata->modified_uuid));
	/* If there is no xattr, just skip the modified_uuid field. */
	if (err == -ENODATA)
		return 0;
	if (err < 0)
		return err;

	overlayfs->modified_uuid.funcs.encode = pb_encode_uuid_field;
	overlayfs->modified_uuid.arg = fdata->modified_uuid;
	return 0;
}

static int fill_file_description(struct file *file, schema_File *schema_file,
				 struct file_data *fdata)
{
	char *buf;
	int err;
	u32 mode;
	char *path;
	struct socket *socket;
	schema_Socket *socketfs;
	struct sockaddr_storage saddr;

	memset(fdata, 0, sizeof(*fdata));

	if (file == NULL)
		return 0;

	schema_file->ino = file_inode(file)->i_ino;
	mode = file_inode(file)->i_mode;

	/* For pipes, no need to resolve the path. */
	if (S_ISFIFO(mode))
		return 0;

	if (S_ISSOCK(mode)) {
		socket = (struct socket *)file->private_data;
		socketfs = &schema_file->filesystem.socket;

		/* Local socket */
		err = kernel_getsockname(socket, (struct sockaddr *)&saddr);
		if (err >= 0) {
			socketfs->has_local = true;
			fill_socket_description(&saddr, &fdata->local,
						&socketfs->local);
		}

		/* Remote socket, might not be connected. */
		err = kernel_getpeername(socket, (struct sockaddr *)&saddr);
		if (err >= 0) {
			socketfs->has_remote = true;
			fill_socket_description(&saddr, &fdata->remote,
						&socketfs->remote);
		}

		schema_file->which_filesystem = schema_File_socket_tag;
		return 0;
	}

	/*
	 * From this point, we care about all the other types of files as their
	 * path provides interesting insight.
	 */
	buf = (char *)__get_free_page(GFP_KERNEL);
	if (buf == NULL)
		return -ENOMEM;

	fdata->allocated = buf;

	path = d_path(&file->f_path, buf, PAGE_SIZE);
	if (IS_ERR(path)) {
		free_file_data(fdata);
		return PTR_ERR(path);
	}

	schema_file->fullpath.funcs.encode = pb_encode_string_field;
	schema_file->fullpath.arg = path; /* buf is freed in free_file_data. */

	err = fill_file_overlayfs(file, schema_file, fdata);
	if (err) {
		free_file_data(fdata);
		return err;
	}

	return 0;
}

static int fill_stream_description(schema_Descriptor *desc, int fd,
				   struct file_data *fdata)
{
	struct fd sfd;
	struct file *file;
	int err = 0;

	sfd = fdget(fd);
	file = sfd.file;

	if (file == NULL) {
		memset(fdata, 0, sizeof(*fdata));
		goto end;
	}

	desc->mode = file_inode(file)->i_mode;
	desc->has_file = true;
	err = fill_file_description(file, &desc->file, fdata);

end:
	fdput(sfd);
	return err;
}

static int populate_proc_uuid_common(schema_Process *proc, char *uuid,
				     size_t uuid_size, char *parent_uuid,
				     size_t parent_uuid_size,
				     struct task_struct *task)
{
	int err;
	struct task_struct *parent;
	/* Generate unique identifier for the process and its parent */
	err = get_process_uuid(task, uuid, uuid_size);
	if (err)
		return err;

	proc->uuid.funcs.encode = pb_encode_uuid_field;
	proc->uuid.arg = uuid;

	rcu_read_lock();

	if (!pid_alive(task))
		goto out;
	/*
	 * I don't think this needs to be task_rcu_dereference because
	 * real_parent is only supposed to be accessed using RCU.
	 */
	parent = rcu_dereference(task->real_parent);

	if (parent) {
		err = get_process_uuid(parent, parent_uuid, parent_uuid_size);
		if (!err) {
			proc->parent_uuid.funcs.encode = pb_encode_uuid_field;
			proc->parent_uuid.arg = parent_uuid;
		}
	}

out:
	rcu_read_unlock();

	return err;
}

/* Populate the fields that we always want to set in Process messages. */
static int populate_proc_common(schema_Process *proc, char *uuid,
				size_t uuid_size, char *parent_uuid,
				size_t parent_uuid_size,
				struct task_struct *task)
{
	u64 cid;
	struct pid_namespace *ns = task_active_pid_ns(task);

	/* Container identifier for the current namespace. */
	proc->container_id = csm_get_ns_contid(ns);

	/*
	 * If the process container-id is different, the process tree is part of
	 * a different session within the namespace (kubectl/docker exec,
	 * liveness probe or others).
	 */
	cid = audit_get_contid(task);
	if (proc->container_id != cid)
		proc->exec_session_id = cid;

	/* Add information about pid in different namespaces */
	proc->pid = task_tgid_nr(task);
	proc->parent_pid = task_ppid_nr(task);
	proc->container_pid = task_tgid_nr_ns(task, ns);
	proc->container_parent_pid = task_ppid_nr_ns(task, ns);

	return populate_proc_uuid_common(proc, uuid, uuid_size, parent_uuid,
					 parent_uuid_size, task);
}

int csm_bprm_check_security(struct linux_binprm *bprm)
{
	char uuid[PROCESS_UUID_SIZE];
	char parent_uuid[PROCESS_UUID_SIZE];
	int err;
	schema_Event event = {};
	schema_Process *proc;
	struct string_arr_ctx argv_ctx;
	void *stack = NULL, *ctx = NULL;
	u64 cid;
	struct file_data path_data = {};
	struct file_data stdin_data = {};
	struct file_data stdout_data = {};
	struct file_data stderr_data = {};

	/*
	 * Always create a container-id for containerized processes.
	 * If the LSM is enabled later, we can track existing containers.
	 */
	cid = audit_get_contid(current);

	if (cid == AUDIT_CID_UNSET) {
		if (!is_possible_container(current, bprm->file))
			return 0;

		cid = csm_set_contid(current);

		if (cid == AUDIT_CID_UNSET)
			return 0;
	}

	if (!csm_execute_enabled)
		return 0;

	/* The interpreter will call us again with more context. */
	if (bprm->buf[0] == '#' && bprm->buf[1] == '!')
		return 0;

	proc = &event.event.execute.proc;
	err = populate_proc_common(proc, uuid, sizeof(uuid), parent_uuid,
				   sizeof(parent_uuid), current);
	if (err)
		goto out_free_buf;

	proc->creation_timestamp = ktime_get_real_ns();

	/* Provide information about the launched binary. */
	proc->has_binary = true;
	err = fill_file_description(bprm->file, &proc->binary, &path_data);
	if (err)
		goto out_free_buf;

	/* Information about streams */
	proc->has_streams = true;

	proc->streams.has_stdin = true;
	err = fill_stream_description(&proc->streams.stdin, STDIN_FILENO,
				      &stdin_data);
	if (err)
		goto out_free_buf;

	proc->streams.has_stdout = true;
	err = fill_stream_description(&proc->streams.stdout, STDOUT_FILENO,
				      &stdout_data);
	if (err)
		goto out_free_buf;

	proc->streams.has_stderr = true;
	err = fill_stream_description(&proc->streams.stderr, STDERR_FILENO,
				      &stderr_data);
	if (err)
		goto out_free_buf;

	stack = kmap_argument_stack(bprm, &ctx);
	if (!stack) {
		err = -EFAULT;
		goto out_free_buf;
	}

	/* Capture process argument */
	argv_ctx.bprm = bprm;
	argv_ctx.stack = stack;
	proc->args.argv.funcs.encode = encode_current_argv;
	proc->args.argv.arg = &argv_ctx;

	/* Capture process environment variables */
	proc->args.envp.funcs.encode = encode_current_envp;
	proc->args.envp.arg = &argv_ctx;

	event.which_event = schema_Event_execute_tag;
	event.event.execute.has_proc = true;
	proc->has_args = true;

	/*
	 * Configurations options are checked when computing the serialized
	 * protobufs.
	 */
	down_read(&csm_rwsem_config);
	err = csm_sendeventproto(schema_Event_fields, &event);
	up_read(&csm_rwsem_config);

	if (err)
		pr_err("csm_sendeventproto returned %d on execve\n", err);
	err = 0;

out_free_buf:
	kunmap_argument_stack(bprm, stack, ctx);
	free_file_data(&path_data);
	free_file_data(&stdin_data);
	free_file_data(&stdout_data);
	free_file_data(&stderr_data);

	/*
	 * On failure, enforce it only if the execute config is enabled.
	 * If the collector was disabled, prefer to succeed to not impact the
	 * system.
	 */
	if (unlikely(err < 0 && !csm_execute_enabled))
		err = 0;

	return err;
}

/* Create a clone event when a new task leader is created. */
void csm_task_post_alloc(struct task_struct *task)
{
	int err;
	char uuid[PROCESS_UUID_SIZE];
	char parent_uuid[PROCESS_UUID_SIZE];
	schema_Event event = {};
	schema_Process *proc;

	if (!csm_execute_enabled ||
	    audit_get_contid(task) == AUDIT_CID_UNSET ||
	    !thread_group_leader(task))
		return;

	proc = &event.event.clone.proc;

	err = populate_proc_uuid_common(proc, uuid, sizeof(uuid), parent_uuid,
					sizeof(parent_uuid), task);

	event.which_event = schema_Event_clone_tag;
	event.event.clone.has_proc = true;
	err = csm_sendeventproto(schema_Event_fields, &event);
	if (err)
		pr_err("csm_sendeventproto returned %d on exit\n", err);
}

/*
 * This LSM hook callback doesn't exist upstream and is called only when the
 * last thread of a thread group exit.
 */
void csm_task_exit(struct task_struct *task)
{
	int err;
	schema_Event event = {};
	schema_ExitEvent *exit;
	char uuid[PROCESS_UUID_SIZE];

	if (!csm_execute_enabled ||
	    audit_get_contid(task) == AUDIT_CID_UNSET)
		return;

	exit = &event.event.exit;

	/* Fetch the unique identifier for this process */
	err = get_process_uuid(task, uuid, sizeof(uuid));
	if (err) {
		pr_err("failed to get process uuid on exit\n");
		return;
	}

	exit->process_uuid.funcs.encode = pb_encode_uuid_field;
	exit->process_uuid.arg = uuid;

	event.which_event = schema_Event_exit_tag;

	err = csm_sendeventproto(schema_Event_fields, &event);
	if (err)
		pr_err("csm_sendeventproto returned %d on exit\n", err);
}

int csm_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
		unsigned long prot)
{
	char uuid[PROCESS_UUID_SIZE];
	char parent_uuid[PROCESS_UUID_SIZE];
	int err;
	schema_Event event = {};
	schema_MemoryExecEvent *memexec;
	u64 cid;
	struct file_data path_data = {};

	cid = audit_get_contid(current);

	if (!csm_memexec_enabled ||
	    !(prot & PROT_EXEC) ||
	    vma->vm_file == NULL ||
	    cid == AUDIT_CID_UNSET)
		return 0;

	memexec = &event.event.memexec;

	err = fill_file_description(vma->vm_file, &memexec->mapped_file,
				    &path_data);
	if (err)
		return err;

	err = populate_proc_common(&memexec->proc, uuid, sizeof(uuid),
				   parent_uuid, sizeof(parent_uuid), current);
	if (err)
		goto out;

	memexec->prot_exec_timestamp = ktime_get_real_ns();
	memexec->new_flags = prot;
	memexec->req_flags = reqprot;
	memexec->old_vm_flags = vma->vm_flags;

	memexec->action = schema_MemoryExecEvent_Action_MPROTECT;
	memexec->start_addr = vma->vm_start;
	memexec->end_addr = vma->vm_end;

	event.which_event = schema_Event_memexec_tag;
	event.event.memexec.has_proc = true;
	event.event.memexec.has_mapped_file = true;

	err = csm_sendeventproto(schema_Event_fields, &event);
	if (err)
		pr_err("csm_sendeventproto returned %d on mprotect\n", err);
	err = 0;

	if (unlikely(err < 0 && !csm_memexec_enabled))
		err = 0;

out:
	free_file_data(&path_data);
	return err;
}

int csm_mmap_file(struct file *file, unsigned long reqprot,
		unsigned long prot, unsigned long flags)
{
	char uuid[PROCESS_UUID_SIZE];
	char parent_uuid[PROCESS_UUID_SIZE];
	int err;
	schema_Event event = {};
	schema_MemoryExecEvent *memexec;
	struct file *exe_file;
	u64 cid;
	struct file_data path_data = {};

	cid = audit_get_contid(current);

	if (!csm_memexec_enabled ||
	    !(prot & PROT_EXEC) ||
	    file == NULL ||
	    cid == AUDIT_CID_UNSET)
		return 0;

	memexec = &event.event.memexec;
	err = fill_file_description(file, &memexec->mapped_file,
				    &path_data);
	if (err)
		return err;

	err = populate_proc_common(&memexec->proc, uuid, sizeof(uuid),
				   parent_uuid, sizeof(parent_uuid), current);
	if (err)
		goto out;

	/* get_mm_exe_file does its own locking on mm_sem. */
	exe_file = get_mm_exe_file(current->mm);
	if (exe_file) {
		if (path_equal(&file->f_path, &exe_file->f_path))
			memexec->is_initial_mmap = 1;
		fput(exe_file);
	}

	memexec->prot_exec_timestamp = ktime_get_real_ns();
	memexec->new_flags = prot;
	memexec->req_flags = reqprot;
	memexec->mmap_flags = flags;
	memexec->action = schema_MemoryExecEvent_Action_MMAP_FILE;
	event.which_event = schema_Event_memexec_tag;
	event.event.memexec.has_proc = true;
	event.event.memexec.has_mapped_file = true;

	err = csm_sendeventproto(schema_Event_fields, &event);
	if (err)
		pr_err("csm_sendeventproto returned %d on mmap_file\n", err);
	err = 0;

	if (unlikely(err < 0 && !csm_memexec_enabled))
		err = 0;

out:
	free_file_data(&path_data);
	return err;
}

void csm_file_pre_free(struct file *file)
{
	struct dentry *dentry;
	int err;
	struct file_provenance prov;

	/* The file was opened to be modified and the LSM is enabled */
	if (!(file->f_mode & FMODE_WRITE) ||
	    !csm_enabled)
		return;

	/* The current process is containerized. */
	if (audit_get_contid(current) == AUDIT_CID_UNSET)
		return;

	/* The file is part of overlayfs on the upper layer. */
	if (!is_overlayfs_mounted(file))
		return;

	dentry = ovl_dentry_upper(file->f_path.dentry);
	if (!dentry)
		return;

	err = __vfs_getxattr(dentry, dentry->d_inode, XATTR_SECURITY_CSM,
			     NULL, 0);
	if (err != -ENODATA) {
		if (err < 0)
			pr_err("failed to get security attribute: %d\n", err);
		return;
	}

	prov.tgid = task_tgid_nr(current);
	prov.start_time = ktime_mono_to_real(current->group_leader->start_time);

	err = __vfs_setxattr(&nop_mnt_idmap, dentry, dentry->d_inode,
			     XATTR_SECURITY_CSM, &prov, sizeof(prov), 0);
	if (err < 0)
		pr_err("failed to set security attribute: %d\n", err);
}

/*
 * Based off of fs/proc/base.c:next_tgid
 *
 * next_thread_group_leader returns the task_struct of the next task with a pid
 * greater than or equal to tgid. The reference count is increased so that
 * rcu_read_unlock may be called, and preemption reenabled.
 */
static struct task_struct *next_thread_group_leader(pid_t *tgid)
{
	struct pid *pid;
	struct task_struct *task;

	cond_resched();
	rcu_read_lock();
retry:
	task = NULL;
	pid = find_ge_pid(*tgid, &init_pid_ns);
	if (pid) {
		*tgid = pid_nr_ns(pid, &init_pid_ns);
		task = pid_task(pid, PIDTYPE_PID);
		if (!task || !thread_group_leader(task) ||
		    audit_get_contid(task) == AUDIT_CID_UNSET) {
			(*tgid) += 1;
			goto retry;
		}

		/*
		 * Increment the reference count on the task before leaving
		 * the RCU grace period.
		 */
		get_task_struct(task);
		(*tgid) += 1;
	}

	rcu_read_unlock();
	return task;
}

void delayed_enumerate_processes(struct work_struct *work)
{
	pid_t tgid = 0;
	struct task_struct *task;
	struct csm_enumerate_processes_work_data *wd = container_of(
		work, struct csm_enumerate_processes_work_data, work);
	int wd_enumeration_count = wd->enumeration_count;

	kfree(wd);
	wd = NULL;
	work = NULL;

	/*
	 * Try for only a single enumeration routine at a time, as long as the
	 * execute collector is enabled.
	 */
	while ((wd_enumeration_count == atomic_read(&enumeration_count)) &&
	       READ_ONCE(csm_execute_enabled) &&
	       (task = next_thread_group_leader(&tgid))) {
		int err;
		char uuid[PROCESS_UUID_SIZE];
		char parent_uuid[PROCESS_UUID_SIZE];
		struct file *exe_file = NULL;
		struct file_data path_data = {};
		schema_Event event = {};
		schema_Process *proc = &event.event.enumproc.proc;

		exe_file = get_task_exe_file(task);
		if (!exe_file) {
			pr_err("failed to get enumerated process executable, pid: %u\n",
			       task_pid_nr(task));
			goto next;
		}

		proc->has_binary = true;
		err = fill_file_description(exe_file, &proc->binary,
					    &path_data);
		if (err) {
			pr_err("failed to fill enumerated process %u executable description: %d\n",
			       task_pid_nr(task), err);
			goto next;
		}

		err = populate_proc_common(proc, uuid, sizeof(uuid),
					   parent_uuid, sizeof(parent_uuid),
					   task);
		if (err) {
			pr_err("failed to set pid %u common fields: %d\n",
			       task_pid_nr(task), err);
			goto next;
		}

		if (task->flags & PF_EXITING)
			goto next;

		event.which_event = schema_Event_enumproc_tag;
		event.event.execute.has_proc = true;
		err = csm_sendeventproto(schema_Event_fields,
					 &event);
		if (err) {
			pr_err("failed to send pid %u enumerated process: %d\n",
			       task_pid_nr(task), err);
			goto next;
		}
next:
		free_file_data(&path_data);
		if (exe_file)
			fput(exe_file);

		put_task_struct(task);
	}
}

void csm_enumerate_processes(unsigned long const config_version)
{
	struct csm_enumerate_processes_work_data *wd;

	wd = kmalloc(sizeof(*wd), GFP_KERNEL);
	if (!wd)
		return;

	INIT_WORK(&wd->work, delayed_enumerate_processes);
	wd->enumeration_count = atomic_add_return(1, &enumeration_count);
	schedule_work(&wd->work);
}
