Commit 99f6cf61 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull mtd fix from Richard Weinberger.

* 'mtd/fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux:
  mtd: properly check all write ioctls for permissions
parents f9bf3522 f7e6b19b
Loading
Loading
Loading
Loading
+47 −9
Original line number Diff line number Diff line
@@ -355,9 +355,6 @@ static int mtdchar_writeoob(struct file *file, struct mtd_info *mtd,
	uint32_t retlen;
	int ret = 0;

	if (!(file->f_mode & FMODE_WRITE))
		return -EPERM;

	if (length > 4096)
		return -EINVAL;

@@ -643,6 +640,48 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)

	pr_debug("MTD_ioctl\n");

	/*
	 * Check the file mode to require "dangerous" commands to have write
	 * permissions.
	 */
	switch (cmd) {
	/* "safe" commands */
	case MEMGETREGIONCOUNT:
	case MEMGETREGIONINFO:
	case MEMGETINFO:
	case MEMREADOOB:
	case MEMREADOOB64:
	case MEMLOCK:
	case MEMUNLOCK:
	case MEMISLOCKED:
	case MEMGETOOBSEL:
	case MEMGETBADBLOCK:
	case MEMSETBADBLOCK:
	case OTPSELECT:
	case OTPGETREGIONCOUNT:
	case OTPGETREGIONINFO:
	case OTPLOCK:
	case ECCGETLAYOUT:
	case ECCGETSTATS:
	case MTDFILEMODE:
	case BLKPG:
	case BLKRRPART:
		break;

	/* "dangerous" commands */
	case MEMERASE:
	case MEMERASE64:
	case MEMWRITEOOB:
	case MEMWRITEOOB64:
	case MEMWRITE:
		if (!(file->f_mode & FMODE_WRITE))
			return -EPERM;
		break;

	default:
		return -ENOTTY;
	}

	switch (cmd) {
	case MEMGETREGIONCOUNT:
		if (copy_to_user(argp, &(mtd->numeraseregions), sizeof(int)))
@@ -690,9 +729,6 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
	{
		struct erase_info *erase;

		if(!(file->f_mode & FMODE_WRITE))
			return -EPERM;

		erase=kzalloc(sizeof(struct erase_info),GFP_KERNEL);
		if (!erase)
			ret = -ENOMEM;
@@ -985,9 +1021,6 @@ static int mtdchar_ioctl(struct file *file, u_int cmd, u_long arg)
		ret = 0;
		break;
	}

	default:
		ret = -ENOTTY;
	}

	return ret;
@@ -1031,6 +1064,11 @@ static long mtdchar_compat_ioctl(struct file *file, unsigned int cmd,
		struct mtd_oob_buf32 buf;
		struct mtd_oob_buf32 __user *buf_user = argp;

		if (!(file->f_mode & FMODE_WRITE)) {
			ret = -EPERM;
			break;
		}

		if (copy_from_user(&buf, argp, sizeof(buf)))
			ret = -EFAULT;
		else