Tested-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
- drivers/block/floppy.c | 5 +++++
+ drivers/block/floppy.c | 5 +++++
1 file changed, 5 insertions(+)
-diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
-index 2daa5b84abbc..42ae1d2d8243 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
-@@ -2113,6 +2113,9 @@ static void setup_format_params(int track)
+@@ -2113,6 +2113,9 @@ static void setup_format_params(int trac
raw_cmd->kernel_data = floppy_track_buffer;
raw_cmd->length = 4 * F_SECT_PER_TRACK;
/* allow for about 30ms for data transport per track */
head_shift = (F_SECT_PER_TRACK + 5) / 6;
-@@ -3235,6 +3238,8 @@ static int set_geometry(unsigned int cmd, struct floppy_struct *g,
+@@ -3235,6 +3238,8 @@ static int set_geometry(unsigned int cmd
/* sanity checking for parameters. */
if (g->sect <= 0 ||
g->head <= 0 ||
g->track <= 0 || g->track > UDP->tracks >> STRETCH(g) ||
/* check if reserved bits are set */
(g->stretch & ~(FD_STRETCH | FD_SWAPSIDES | FD_SECTBASEMASK)) != 0)
---
-2.20.1
-
--- /dev/null
+From 9b04609b784027968348796a18f601aed9db3789 Mon Sep 17 00:00:00 2001
+From: Denis Efremov <efremov@ispras.ru>
+Date: Fri, 12 Jul 2019 21:55:22 +0300
+Subject: floppy: fix invalid pointer dereference in drive_name
+
+From: Denis Efremov <efremov@ispras.ru>
+
+commit 9b04609b784027968348796a18f601aed9db3789 upstream.
+
+This fixes the invalid pointer dereference in the drive_name function of
+the floppy driver.
+
+The native_format field of the struct floppy_drive_params is used as
+floppy_type array index in the drive_name function. Thus, the field
+should be checked the same way as the autodetect field.
+
+To trigger the bug, one could use a value out of range and set the drive
+parameters with the FDSETDRVPRM ioctl. Next, FDGETDRVTYP ioctl should
+be used to call the drive_name. A floppy disk is not required to be
+inserted.
+
+CAP_SYS_ADMIN is required to call FDSETDRVPRM.
+
+The patch adds the check for a value of the native_format field to be in
+the '0 <= x < ARRAY_SIZE(floppy_type)' range of the floppy_type array
+indices.
+
+The bug was found by syzkaller.
+
+Signed-off-by: Denis Efremov <efremov@ispras.ru>
+Tested-by: Willy Tarreau <w@1wt.eu>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/floppy.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+--- a/drivers/block/floppy.c
++++ b/drivers/block/floppy.c
+@@ -3383,7 +3383,8 @@ static int fd_getgeo(struct block_device
+ return 0;
+ }
+
+-static bool valid_floppy_drive_params(const short autodetect[8])
++static bool valid_floppy_drive_params(const short autodetect[8],
++ int native_format)
+ {
+ size_t floppy_type_size = ARRAY_SIZE(floppy_type);
+ size_t i = 0;
+@@ -3394,6 +3395,9 @@ static bool valid_floppy_drive_params(co
+ return false;
+ }
+
++ if (native_format < 0 || native_format >= floppy_type_size)
++ return false;
++
+ return true;
+ }
+
+@@ -3523,7 +3527,8 @@ static int fd_locked_ioctl(struct block_
+ SUPBOUND(size, strlen((const char *)outparam) + 1);
+ break;
+ case FDSETDRVPRM:
+- if (!valid_floppy_drive_params(inparam.dp.autodetect))
++ if (!valid_floppy_drive_params(inparam.dp.autodetect,
++ inparam.dp.native_format))
+ return -EINVAL;
+ *UDP = inparam.dp;
+ break;
Tested-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
- drivers/block/floppy.c | 6 ++++--
+ drivers/block/floppy.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
-diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
-index 42ae1d2d8243..7516fed84ae9 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
-@@ -3236,8 +3236,10 @@ static int set_geometry(unsigned int cmd, struct floppy_struct *g,
+@@ -3236,8 +3236,10 @@ static int set_geometry(unsigned int cmd
int cnt;
/* sanity checking for parameters. */
/* check for zero in F_SECT_PER_TRACK */
(unsigned char)((g->sect << 2) >> FD_SIZECODE(g)) == 0 ||
g->track <= 0 || g->track > UDP->tracks >> STRETCH(g) ||
---
-2.20.1
-
--- /dev/null
+From 5635f897ed83fd539df78e98ba69ee91592f9bb8 Mon Sep 17 00:00:00 2001
+From: Denis Efremov <efremov@ispras.ru>
+Date: Fri, 12 Jul 2019 21:55:21 +0300
+Subject: floppy: fix out-of-bounds read in next_valid_format
+
+From: Denis Efremov <efremov@ispras.ru>
+
+commit 5635f897ed83fd539df78e98ba69ee91592f9bb8 upstream.
+
+This fixes a global out-of-bounds read access in the next_valid_format
+function of the floppy driver.
+
+The values from autodetect field of the struct floppy_drive_params are
+used as indices for the floppy_type array in the next_valid_format
+function 'floppy_type[DP->autodetect[probed_format]].sect'.
+
+To trigger the bug, one could use a value out of range and set the drive
+parameters with the FDSETDRVPRM ioctl. A floppy disk is not required to
+be inserted.
+
+CAP_SYS_ADMIN is required to call FDSETDRVPRM.
+
+The patch adds the check for values of the autodetect field to be in the
+'0 <= x < ARRAY_SIZE(floppy_type)' range of the floppy_type array indices.
+
+The bug was found by syzkaller.
+
+Signed-off-by: Denis Efremov <efremov@ispras.ru>
+Tested-by: Willy Tarreau <w@1wt.eu>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/block/floppy.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+--- a/drivers/block/floppy.c
++++ b/drivers/block/floppy.c
+@@ -3383,6 +3383,20 @@ static int fd_getgeo(struct block_device
+ return 0;
+ }
+
++static bool valid_floppy_drive_params(const short autodetect[8])
++{
++ size_t floppy_type_size = ARRAY_SIZE(floppy_type);
++ size_t i = 0;
++
++ for (i = 0; i < 8; ++i) {
++ if (autodetect[i] < 0 ||
++ autodetect[i] >= floppy_type_size)
++ return false;
++ }
++
++ return true;
++}
++
+ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd,
+ unsigned long param)
+ {
+@@ -3509,6 +3523,8 @@ static int fd_locked_ioctl(struct block_
+ SUPBOUND(size, strlen((const char *)outparam) + 1);
+ break;
+ case FDSETDRVPRM:
++ if (!valid_floppy_drive_params(inparam.dp.autodetect))
++ return -EINVAL;
+ *UDP = inparam.dp;
+ break;
+ case FDGETDRVPRM:
bluetooth-check-state-in-l2cap_disconnect_rsp.patch
bluetooth-validate-ble-connection-interval-updates.patch
floppy-fix-div-by-zero-in-setup_format_params.patch
+floppy-fix-out-of-bounds-read-in-next_valid_format.patch
+floppy-fix-invalid-pointer-dereference-in-drive_name.patch
floppy-fix-out-of-bounds-read-in-copy_buffer.patch