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.patch | 110 |
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 |
