aboutsummaryrefslogtreecommitdiffstats
path: root/0001-mtd-properly-check-all-write-ioctls-for-permissions.patch
diff options
Diffstat (limited to '0001-mtd-properly-check-all-write-ioctls-for-permissions.patch')
-rw-r--r--0001-mtd-properly-check-all-write-ioctls-for-permissions.patch110
1 files changed, 110 insertions, 0 deletions
diff --git a/0001-mtd-properly-check-all-write-ioctls-for-permissions.patch b/0001-mtd-properly-check-all-write-ioctls-for-permissions.patch
new file mode 100644
index 00000000000000..66b766d88c3527
--- /dev/null
+++ b/0001-mtd-properly-check-all-write-ioctls-for-permissions.patch
@@ -0,0 +1,110 @@
+From 02c6bc84e034fc1930dd3e57c933ea22351e9f85 Mon Sep 17 00:00:00 2001
+From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Date: Sat, 11 Jul 2020 08:51:20 +0200
+Subject: [PATCH 1/2] mtd: properly check all write ioctls for permissions
+
+When doing a "write" ioctl call, properly check that we have permissions
+to do so before copying anything from userspace or anything else so we
+can "fail fast". This includes also covering the MEMWRITE ioctl which
+previously missed checking for this.
+
+Cc: Miquel Raynal <miquel.raynal@bootlin.com>
+Cc: Richard Weinberger <richard@nod.at>
+Cc: Vignesh Raghavendra <vigneshr@ti.com>
+Cc: stable <stable@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mtd/mtdchar.c | 54 +++++++++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 45 insertions(+), 9 deletions(-)
+
+--- a/drivers/mtd/mtdchar.c
++++ b/drivers/mtd/mtdchar.c
+@@ -355,9 +355,6 @@ static int mtdchar_writeoob(struct file
+ 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 *fi
+
+ 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 *fi
+ {
+ 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 *fi
+ ret = 0;
+ break;
+ }
+-
+- default:
+- ret = -ENOTTY;
+ }
+
+ return ret;
+@@ -1031,6 +1064,9 @@ static long mtdchar_compat_ioctl(struct
+ struct mtd_oob_buf32 buf;
+ struct mtd_oob_buf32 __user *buf_user = argp;
+
++ if (!(file->f_mode & FMODE_WRITE))
++ return -EPERM;
++
+ if (copy_from_user(&buf, argp, sizeof(buf)))
+ ret = -EFAULT;
+ else