Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a761a1c0 authored by Dave Hansen's avatar Dave Hansen Committed by Al Viro
Browse files

[PATCH] r/o bind mounts: elevate write count for ncp_ioctl()

parent 18f335af
Loading
Loading
Loading
Loading
+53 −1
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <linux/ioctl.h>
#include <linux/time.h>
#include <linux/mm.h>
#include <linux/mount.h>
#include <linux/highuid.h>
#include <linux/smp_lock.h>
#include <linux/vmalloc.h>
@@ -261,7 +262,7 @@ ncp_get_charsets(struct ncp_server* server, struct ncp_nls_ioctl __user *arg)
}
#endif /* CONFIG_NCPFS_NLS */

int ncp_ioctl(struct inode *inode, struct file *filp,
static int __ncp_ioctl(struct inode *inode, struct file *filp,
	      unsigned int cmd, unsigned long arg)
{
	struct ncp_server *server = NCP_SERVER(inode);
@@ -822,6 +823,57 @@ int ncp_ioctl(struct inode *inode, struct file *filp,
	return -EINVAL;
}

static int ncp_ioctl_need_write(unsigned int cmd)
{
	switch (cmd) {
	case NCP_IOC_GET_FS_INFO:
	case NCP_IOC_GET_FS_INFO_V2:
	case NCP_IOC_NCPREQUEST:
	case NCP_IOC_SETDENTRYTTL:
	case NCP_IOC_SIGN_INIT:
	case NCP_IOC_LOCKUNLOCK:
	case NCP_IOC_SET_SIGN_WANTED:
		return 1;
	case NCP_IOC_GETOBJECTNAME:
	case NCP_IOC_SETOBJECTNAME:
	case NCP_IOC_GETPRIVATEDATA:
	case NCP_IOC_SETPRIVATEDATA:
	case NCP_IOC_SETCHARSETS:
	case NCP_IOC_GETCHARSETS:
	case NCP_IOC_CONN_LOGGED_IN:
	case NCP_IOC_GETDENTRYTTL:
	case NCP_IOC_GETMOUNTUID2:
	case NCP_IOC_SIGN_WANTED:
	case NCP_IOC_GETROOT:
	case NCP_IOC_SETROOT:
		return 0;
	default:
		/* unkown IOCTL command, assume write */
		return 1;
	}
}

int ncp_ioctl(struct inode *inode, struct file *filp,
	      unsigned int cmd, unsigned long arg)
{
	int ret;

	if (ncp_ioctl_need_write(cmd)) {
		/*
		 * inside the ioctl(), any failures which
		 * are because of file_permission() are
		 * -EACCESS, so it seems consistent to keep
		 *  that here.
		 */
		if (mnt_want_write(filp->f_path.mnt))
			return -EACCES;
	}
	ret = __ncp_ioctl(inode, filp, cmd, arg);
	if (ncp_ioctl_need_write(cmd))
		mnt_drop_write(filp->f_path.mnt);
	return ret;
}

#ifdef CONFIG_COMPAT
long ncp_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{