// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2017 Red Hat, Inc.
 */

#include <linux/cred.h>
#include <linux/file.h>
#include <linux/mount.h>
#include <linux/xattr.h>
#include <linux/uio.h>
#include <linux/uaccess.h>
#include <linux/security.h>
#include <linux/fs.h>
#include <linux/backing-file.h>
#include "overlayfs.h"

static char ovl_whatisit(struct inode *inode, struct inode *realinode)
{
	if (realinode != ovl_inode_upper(inode))
		return 'l';
	if (ovl_has_upperdata(inode))
		return 'u';
	else
		return 'm';
}

static struct file *ovl_open_realfile(const struct file *file,
				      const struct path *realpath)
{
	struct inode *realinode = d_inode(realpath->dentry);
	struct inode *inode = file_inode(file);
	struct mnt_idmap *real_idmap;
	struct file *realfile;
	const struct cred *old_cred;
	int flags = file->f_flags | OVL_OPEN_FLAGS;
	int acc_mode = ACC_MODE(flags);
	int err;

	if (flags & O_APPEND)
		acc_mode |= MAY_APPEND;

	old_cred = ovl_override_creds(inode->i_sb);
	real_idmap = mnt_idmap(realpath->mnt);
	err = inode_permission(real_idmap, realinode, MAY_OPEN | acc_mode);
	if (err) {
		realfile = ERR_PTR(err);
	} else {
		if (!inode_owner_or_capable(real_idmap, realinode))
			flags &= ~O_NOATIME;

		realfile = backing_file_open(file_user_path((struct file *) file),
					     flags, realpath, current_cred());
	}
	ovl_revert_creds(old_cred);

	pr_debug("open(%p[%pD2/%c], 0%o) -> (%p, 0%o)\n",
		 file, file, ovl_whatisit(inode, realinode), file->f_flags,
		 realfile, IS_ERR(realfile) ? 0 : realfile->f_flags);

	return realfile;
}

#define OVL_SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT)

static int ovl_change_flags(struct file *file, unsigned int flags)
{
	struct inode *inode = file_inode(file);
	int err;

	flags &= OVL_SETFL_MASK;

	if (((flags ^ file->f_flags) & O_APPEND) && IS_APPEND(inode))
		return -EPERM;

	if ((flags & O_DIRECT) && !(file->f_mode & FMODE_CAN_ODIRECT))
		return -EINVAL;

	if (file->f_op->check_flags) {
		err = file->f_op->check_flags(flags);
		if (err)
			return err;
	}

	spin_lock(&file->f_lock);
	file->f_flags = (file->f_flags & ~OVL_SETFL_MASK) | flags;
	file->f_iocb_flags = iocb_flags(file);
	spin_unlock(&file->f_lock);

	return 0;
}

struct ovl_file {
	struct file *realfile;
	struct file *upperfile;
};

struct ovl_file *ovl_file_alloc(struct file *realfile)
{
	struct ovl_file *of = kzalloc(sizeof(struct ovl_file), GFP_KERNEL);

	if (unlikely(!of))
		return NULL;

	of->realfile = realfile;
	return of;
}

void ovl_file_free(struct ovl_file *of)
{
	fput(of->realfile);
	if (of->upperfile)
		fput(of->upperfile);
	kfree(of);
}

static bool ovl_is_real_file(const struct file *realfile,
			     const struct path *realpath)
{
	return file_inode(realfile) == d_inode(realpath->dentry);
}

static struct file *ovl_real_file_path(const struct file *file,
				       struct path *realpath)
{
	struct ovl_file *of = file->private_data;
	struct file *realfile = of->realfile;

	if (WARN_ON_ONCE(!realpath->dentry))
		return ERR_PTR(-EIO);

	/*
	 * If the realfile that we want is not where the data used to be at
	 * open time, either we'd been copied up, or it's an fsync of a
	 * metacopied file.  We need the upperfile either way, so see if it
	 * is already opened and if it is not then open and store it.
	 */
	if (unlikely(!ovl_is_real_file(realfile, realpath))) {
		struct file *upperfile = READ_ONCE(of->upperfile);
		struct file *old;

		if (!upperfile) { /* Nobody opened upperfile yet */
			upperfile = ovl_open_realfile(file, realpath);
			if (IS_ERR(upperfile))
				return upperfile;

			/* Store the upperfile for later */
			old = cmpxchg_release(&of->upperfile, NULL, upperfile);
			if (old) { /* Someone opened upperfile before us */
				fput(upperfile);
				upperfile = old;
			}
		}
		/*
		 * Stored file must be from the right inode, unless someone's
		 * been corrupting the upper layer.
		 */
		if (WARN_ON_ONCE(!ovl_is_real_file(upperfile, realpath)))
			return ERR_PTR(-EIO);

		realfile = upperfile;
	}

	/* Did the flags change since open? */
	if (unlikely((file->f_flags ^ realfile->f_flags) & ~OVL_OPEN_FLAGS)) {
		int err = ovl_change_flags(realfile, file->f_flags);

		if (err)
			return ERR_PTR(err);
	}

	return realfile;
}

static struct file *ovl_real_file(const struct file *file)
{
	struct dentry *dentry = file_dentry(file);
	struct path realpath;
	int err;

	if (d_is_dir(dentry)) {
		struct file *f = ovl_dir_real_file(file, false);

		if (WARN_ON_ONCE(!f))
			return ERR_PTR(-EIO);
		return f;
	}

	/* lazy lookup and verify of lowerdata */
	err = ovl_verify_lowerdata(dentry);
	if (err)
		return ERR_PTR(err);

	ovl_path_realdata(dentry, &realpath);

	return ovl_real_file_path(file, &realpath);
}

static int ovl_open(struct inode *inode, struct file *file)
{
	struct dentry *dentry = file_dentry(file);
	struct file *realfile;
	struct path realpath;
	struct ovl_file *of;
	int err;

	/* lazy lookup and verify lowerdata */
	err = ovl_verify_lowerdata(dentry);
	if (err)
		return err;

	err = ovl_maybe_copy_up(dentry, file->f_flags);
	if (err)
		return err;

	/* No longer need these flags, so don't pass them on to underlying fs */
	file->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC);

	ovl_path_realdata(dentry, &realpath);
	if (!realpath.dentry)
		return -EIO;

	realfile = ovl_open_realfile(file, &realpath);
	if (IS_ERR(realfile))
		return PTR_ERR(realfile);

	of = ovl_file_alloc(realfile);
	if (!of) {
		fput(realfile);
		return -ENOMEM;
	}

	file->private_data = of;

	return 0;
}

static int ovl_release(struct inode *inode, struct file *file)
{
	ovl_file_free(file->private_data);
	return 0;
}

static loff_t ovl_llseek(struct file *file, loff_t offset, int whence)
{
	struct inode *inode = file_inode(file);
	struct file *realfile;
	const struct cred *old_cred;
	loff_t ret;

	/*
	 * The two special cases below do not need to involve real fs,
	 * so we can optimizing concurrent callers.
	 */
	if (offset == 0) {
		if (whence == SEEK_CUR)
			return file->f_pos;

		if (whence == SEEK_SET)
			return vfs_setpos(file, 0, 0);
	}

	realfile = ovl_real_file(file);
	if (IS_ERR(realfile))
		return PTR_ERR(realfile);

	/*
	 * Overlay file f_pos is the master copy that is preserved
	 * through copy up and modified on read/write, but only real
	 * fs knows how to SEEK_HOLE/SEEK_DATA and real fs may impose
	 * limitations that are more strict than ->s_maxbytes for specific
	 * files, so we use the real file to perform seeks.
	 */
	ovl_inode_lock(inode);
	realfile->f_pos = file->f_pos;

	old_cred = ovl_override_creds(inode->i_sb);
	ret = vfs_llseek(realfile, offset, whence);
	ovl_revert_creds(old_cred);

	file->f_pos = realfile->f_pos;
	ovl_inode_unlock(inode);

	return ret;
}

static void ovl_file_modified(struct file *file)
{
	/* Update size/mtime */
	ovl_copyattr(file_inode(file));
}

static void ovl_file_end_write(struct kiocb *iocb, ssize_t ret)
{
	ovl_file_modified(iocb->ki_filp);
}

static void ovl_file_accessed(struct file *file)
{
	struct inode *inode, *upperinode;
	struct timespec64 ctime, uctime;
	struct timespec64 mtime, umtime;

	if (file->f_flags & O_NOATIME)
		return;

	inode = file_inode(file);
	upperinode = ovl_inode_upper(inode);

	if (!upperinode)
		return;

	ctime = inode_get_ctime(inode);
	uctime = inode_get_ctime(upperinode);
	mtime = inode_get_mtime(inode);
	umtime = inode_get_mtime(upperinode);
	if ((!timespec64_equal(&mtime, &umtime)) ||
	     !timespec64_equal(&ctime, &uctime)) {
		inode_set_mtime_to_ts(inode, inode_get_mtime(upperinode));
		inode_set_ctime_to_ts(inode, uctime);
	}

	touch_atime(&file->f_path);
}

static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter)
{
	struct file *file = iocb->ki_filp;
	struct file *realfile;
	struct backing_file_ctx ctx = {
		.cred = ovl_creds(file_inode(file)->i_sb),
		.accessed = ovl_file_accessed,
	};

	if (!iov_iter_count(iter))
		return 0;

	realfile = ovl_real_file(file);
	if (IS_ERR(realfile))
		return PTR_ERR(realfile);

	return backing_file_read_iter(realfile, iter, iocb, iocb->ki_flags,
				      &ctx);
}

static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
{
	struct file *file = iocb->ki_filp;
	struct inode *inode = file_inode(file);
	struct file *realfile;
	ssize_t ret;
	int ifl = iocb->ki_flags;
	struct backing_file_ctx ctx = {
		.cred = ovl_creds(inode->i_sb),
		.end_write = ovl_file_end_write,
	};

	if (!iov_iter_count(iter))
		return 0;

	inode_lock(inode);
	/* Update mode */
	ovl_copyattr(inode);

	realfile = ovl_real_file(file);
	ret = PTR_ERR(realfile);
	if (IS_ERR(realfile))
		goto out_unlock;

	if (!ovl_should_sync(OVL_FS(inode->i_sb)))
		ifl &= ~(IOCB_DSYNC | IOCB_SYNC);

	/*
	 * Overlayfs doesn't support deferred completions, don't copy
	 * this property in case it is set by the issuer.
	 */
	ifl &= ~IOCB_DIO_CALLER_COMP;
	ret = backing_file_write_iter(realfile, iter, iocb, ifl, &ctx);

out_unlock:
	inode_unlock(inode);

	return ret;
}

static ssize_t ovl_splice_read(struct file *in, loff_t *ppos,
			       struct pipe_inode_info *pipe, size_t len,
			       unsigned int flags)
{
	struct file *realfile;
	ssize_t ret;
	struct backing_file_ctx ctx = {
		.cred = ovl_creds(file_inode(in)->i_sb),
		.accessed = ovl_file_accessed,
	};
	struct kiocb iocb;

	realfile = ovl_real_file(in);
	if (IS_ERR(realfile))
		return PTR_ERR(realfile);

	init_sync_kiocb(&iocb, in);
	iocb.ki_pos = *ppos;
	ret = backing_file_splice_read(realfile, &iocb, pipe, len, flags, &ctx);
	*ppos = iocb.ki_pos;

	return ret;
}

/*
 * Calling iter_file_splice_write() directly from overlay's f_op may deadlock
 * due to lock order inversion between pipe->mutex in iter_file_splice_write()
 * and file_start_write(realfile) in ovl_write_iter().
 *
 * So do everything ovl_write_iter() does and call iter_file_splice_write() on
 * the real file.
 */
static ssize_t ovl_splice_write(struct pipe_inode_info *pipe, struct file *out,
				loff_t *ppos, size_t len, unsigned int flags)
{
	struct file *realfile;
	struct inode *inode = file_inode(out);
	ssize_t ret;
	struct backing_file_ctx ctx = {
		.cred = ovl_creds(inode->i_sb),
		.end_write = ovl_file_end_write,
	};
	struct kiocb iocb;

	inode_lock(inode);
	/* Update mode */
	ovl_copyattr(inode);

	realfile = ovl_real_file(out);
	ret = PTR_ERR(realfile);
	if (IS_ERR(realfile))
		goto out_unlock;

	init_sync_kiocb(&iocb, out);
	iocb.ki_pos = *ppos;
	ret = backing_file_splice_write(pipe, realfile, &iocb, len, flags, &ctx);
	*ppos = iocb.ki_pos;

out_unlock:
	inode_unlock(inode);

	return ret;
}

static int ovl_fsync(struct file *file, loff_t start, loff_t end, int datasync)
{
	struct dentry *dentry = file_dentry(file);
	enum ovl_path_type type;
	struct path upperpath;
	struct file *upperfile;
	const struct cred *old_cred;
	int ret;

	ret = ovl_sync_status(OVL_FS(file_inode(file)->i_sb));
	if (ret <= 0)
		return ret;

	/* Don't sync lower file for fear of receiving EROFS error */
	type = ovl_path_type(dentry);
	if (!OVL_TYPE_UPPER(type) || (datasync && OVL_TYPE_MERGE(type)))
		return 0;

	ovl_path_upper(dentry, &upperpath);
	upperfile = ovl_real_file_path(file, &upperpath);
	if (IS_ERR(upperfile))
		return PTR_ERR(upperfile);

	old_cred = ovl_override_creds(file_inode(file)->i_sb);
	ret = vfs_fsync_range(upperfile, start, end, datasync);
	ovl_revert_creds(old_cred);

	return ret;
}

static int ovl_mmap(struct file *file, struct vm_area_struct *vma)
{
	struct ovl_file *of = file->private_data;
	struct backing_file_ctx ctx = {
		.cred = ovl_creds(file_inode(file)->i_sb),
		.accessed = ovl_file_accessed,
	};

	return backing_file_mmap(of->realfile, vma, &ctx);
}

static long ovl_fallocate(struct file *file, int mode, loff_t offset, loff_t len)
{
	struct inode *inode = file_inode(file);
	struct file *realfile;
	const struct cred *old_cred;
	int ret;

	inode_lock(inode);
	/* Update mode */
	ovl_copyattr(inode);
	ret = file_remove_privs(file);
	if (ret)
		goto out_unlock;

	realfile = ovl_real_file(file);
	ret = PTR_ERR(realfile);
	if (IS_ERR(realfile))
		goto out_unlock;

	old_cred = ovl_override_creds(file_inode(file)->i_sb);
	ret = vfs_fallocate(realfile, mode, offset, len);
	ovl_revert_creds(old_cred);

	/* Update size */
	ovl_file_modified(file);

out_unlock:
	inode_unlock(inode);

	return ret;
}

static int ovl_fadvise(struct file *file, loff_t offset, loff_t len, int advice)
{
	struct file *realfile;
	const struct cred *old_cred;
	int ret;

	realfile = ovl_real_file(file);
	if (IS_ERR(realfile))
		return PTR_ERR(realfile);

	old_cred = ovl_override_creds(file_inode(file)->i_sb);
	ret = vfs_fadvise(realfile, offset, len, advice);
	ovl_revert_creds(old_cred);

	return ret;
}

enum ovl_copyop {
	OVL_COPY,
	OVL_CLONE,
	OVL_DEDUPE,
};

static loff_t ovl_copyfile(struct file *file_in, loff_t pos_in,
			    struct file *file_out, loff_t pos_out,
			    loff_t len, unsigned int flags, enum ovl_copyop op)
{
	struct inode *inode_out = file_inode(file_out);
	struct file *realfile_in, *realfile_out;
	const struct cred *old_cred;
	loff_t ret;

	inode_lock(inode_out);
	if (op != OVL_DEDUPE) {
		/* Update mode */
		ovl_copyattr(inode_out);
		ret = file_remove_privs(file_out);
		if (ret)
			goto out_unlock;
	}

	realfile_out = ovl_real_file(file_out);
	ret = PTR_ERR(realfile_out);
	if (IS_ERR(realfile_out))
		goto out_unlock;

	realfile_in = ovl_real_file(file_in);
	ret = PTR_ERR(realfile_in);
	if (IS_ERR(realfile_in))
		goto out_unlock;

	old_cred = ovl_override_creds(file_inode(file_out)->i_sb);
	switch (op) {
	case OVL_COPY:
		ret = vfs_copy_file_range(realfile_in, pos_in,
					  realfile_out, pos_out, len, flags);
		break;

	case OVL_CLONE:
		ret = vfs_clone_file_range(realfile_in, pos_in,
					   realfile_out, pos_out, len, flags);
		break;

	case OVL_DEDUPE:
		ret = vfs_dedupe_file_range_one(realfile_in, pos_in,
						realfile_out, pos_out, len,
						flags);
		break;
	}
	ovl_revert_creds(old_cred);

	/* Update size */
	ovl_file_modified(file_out);

out_unlock:
	inode_unlock(inode_out);

	return ret;
}

static ssize_t ovl_copy_file_range(struct file *file_in, loff_t pos_in,
				   struct file *file_out, loff_t pos_out,
				   size_t len, unsigned int flags)
{
	return ovl_copyfile(file_in, pos_in, file_out, pos_out, len, flags,
			    OVL_COPY);
}

static loff_t ovl_remap_file_range(struct file *file_in, loff_t pos_in,
				   struct file *file_out, loff_t pos_out,
				   loff_t len, unsigned int remap_flags)
{
	enum ovl_copyop op;

	if (remap_flags & ~(REMAP_FILE_DEDUP | REMAP_FILE_ADVISORY))
		return -EINVAL;

	if (remap_flags & REMAP_FILE_DEDUP)
		op = OVL_DEDUPE;
	else
		op = OVL_CLONE;

	/*
	 * Don't copy up because of a dedupe request, this wouldn't make sense
	 * most of the time (data would be duplicated instead of deduplicated).
	 */
	if (op == OVL_DEDUPE &&
	    (!ovl_inode_upper(file_inode(file_in)) ||
	     !ovl_inode_upper(file_inode(file_out))))
		return -EPERM;

	return ovl_copyfile(file_in, pos_in, file_out, pos_out, len,
			    remap_flags, op);
}

static int ovl_flush(struct file *file, fl_owner_t id)
{
	struct file *realfile;
	const struct cred *old_cred;
	int err = 0;

	realfile = ovl_real_file(file);
	if (IS_ERR(realfile))
		return PTR_ERR(realfile);

	if (realfile->f_op->flush) {
		old_cred = ovl_override_creds(file_inode(file)->i_sb);
		err = realfile->f_op->flush(realfile, id);
		ovl_revert_creds(old_cred);
	}

	return err;
}

const struct file_operations ovl_file_operations = {
	.open		= ovl_open,
	.release	= ovl_release,
	.llseek		= ovl_llseek,
	.read_iter	= ovl_read_iter,
	.write_iter	= ovl_write_iter,
	.fsync		= ovl_fsync,
	.mmap		= ovl_mmap,
	.fallocate	= ovl_fallocate,
	.fadvise	= ovl_fadvise,
	.flush		= ovl_flush,
	.splice_read    = ovl_splice_read,
	.splice_write   = ovl_splice_write,

	.copy_file_range	= ovl_copy_file_range,
	.remap_file_range	= ovl_remap_file_range,
};
