floppy: fix invalid pointer dereference in drive_name [Linux 3.16.72]

This Linux kernel change "floppy: fix invalid pointer dereference in drive_name" is included in the Linux 3.16.72 release. This change is authored by Denis Efremov <efremov [at] ispras.ru> on Fri Jul 12 21:55:22 2019 +0300. The commit for this change in Linux stable tree is fbf6a95 (patch) which is from upstream commit 9b04609. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream 9b04609.

floppy: fix invalid pointer dereference in drive_name

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

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

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>
[bwh: Backported to 3.16: Drop changes in compat_setdrvprm(), as compat
 ioctls go via fd_ioctl_locked() after translation in compat_ioctl.c.]
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>

There are 9 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/block/floppy.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
index 7345154..2d6087b 100644
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -3383,7 +3383,8 @@ static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
    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(const short autodetect[8])
            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_device *bdev, fmode_t mode, unsigned int
        SUPBOUND(size, strlen((const char *)outparam) + 1);
-       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;

Leave a Reply

Your email address will not be published. Required fields are marked *