Skip to content

Commit 233087c

Browse files
wtarreautorvalds
authored andcommitted
floppy: disable FDRAWCMD by default
Minh Yuan reported a concurrency use-after-free issue in the floppy code between raw_cmd_ioctl and seek_interrupt. [ It turns out this has been around, and that others have reported the KASAN splats over the years, but Minh Yuan had a reproducer for it and so gets primary credit for reporting it for this fix - Linus ] The problem is, this driver tends to break very easily and nowadays, nobody is expected to use FDRAWCMD anyway since it was used to manipulate non-standard formats. The risk of breaking the driver is higher than the risk presented by this race, and accessing the device requires privileges anyway. Let's just add a config option to completely disable this ioctl and leave it disabled by default. Distros shouldn't use it, and only those running on antique hardware might need to enable it. Link: https://lore.kernel.org/all/[email protected]/ Link: https://lore.kernel.org/lkml/CAKcFiNC=MfYVW-Jt9A3=FPJpTwCD2PL_ULNCpsCVE5s8ZeBQgQ@mail.gmail.com Link: https://lore.kernel.org/all/CAEAjamu1FRhz6StCe_55XY5s389ZP_xmCF69k987En+1z53=eg@mail.gmail.com Reported-by: Minh Yuan <[email protected]> Reported-by: [email protected] Reported-by: cruise k <[email protected]> Reported-by: Kyungtae Kim <[email protected]> Suggested-by: Linus Torvalds <[email protected]> Tested-by: Denis Efremov <[email protected]> Signed-off-by: Willy Tarreau <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent 46cf2c6 commit 233087c

File tree

2 files changed

+48
-11
lines changed

2 files changed

+48
-11
lines changed

drivers/block/Kconfig

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,22 @@ config BLK_DEV_FD
3333
To compile this driver as a module, choose M here: the
3434
module will be called floppy.
3535

36+
config BLK_DEV_FD_RAWCMD
37+
bool "Support for raw floppy disk commands (DEPRECATED)"
38+
depends on BLK_DEV_FD
39+
help
40+
If you want to use actual physical floppies and expect to do
41+
special low-level hardware accesses to them (access and use
42+
non-standard formats, for example), then enable this.
43+
44+
Note that the code enabled by this option is rarely used and
45+
might be unstable or insecure, and distros should not enable it.
46+
47+
Note: FDRAWCMD is deprecated and will be removed from the kernel
48+
in the near future.
49+
50+
If unsure, say N.
51+
3652
config AMIGA_FLOPPY
3753
tristate "Amiga floppy support"
3854
depends on AMIGA

drivers/block/floppy.c

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2982,6 +2982,8 @@ static const char *drive_name(int type, int drive)
29822982
return "(null)";
29832983
}
29842984

2985+
#ifdef CONFIG_BLK_DEV_FD_RAWCMD
2986+
29852987
/* raw commands */
29862988
static void raw_cmd_done(int flag)
29872989
{
@@ -3181,6 +3183,35 @@ static int raw_cmd_ioctl(int cmd, void __user *param)
31813183
return ret;
31823184
}
31833185

3186+
static int floppy_raw_cmd_ioctl(int type, int drive, int cmd,
3187+
void __user *param)
3188+
{
3189+
int ret;
3190+
3191+
pr_warn_once("Note: FDRAWCMD is deprecated and will be removed from the kernel in the near future.\n");
3192+
3193+
if (type)
3194+
return -EINVAL;
3195+
if (lock_fdc(drive))
3196+
return -EINTR;
3197+
set_floppy(drive);
3198+
ret = raw_cmd_ioctl(cmd, param);
3199+
if (ret == -EINTR)
3200+
return -EINTR;
3201+
process_fd_request();
3202+
return ret;
3203+
}
3204+
3205+
#else /* CONFIG_BLK_DEV_FD_RAWCMD */
3206+
3207+
static int floppy_raw_cmd_ioctl(int type, int drive, int cmd,
3208+
void __user *param)
3209+
{
3210+
return -EOPNOTSUPP;
3211+
}
3212+
3213+
#endif
3214+
31843215
static int invalidate_drive(struct block_device *bdev)
31853216
{
31863217
/* invalidate the buffer track to force a reread */
@@ -3369,7 +3400,6 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int
33693400
{
33703401
int drive = (long)bdev->bd_disk->private_data;
33713402
int type = ITYPE(drive_state[drive].fd_device);
3372-
int i;
33733403
int ret;
33743404
int size;
33753405
union inparam {
@@ -3520,16 +3550,7 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int
35203550
outparam = &write_errors[drive];
35213551
break;
35223552
case FDRAWCMD:
3523-
if (type)
3524-
return -EINVAL;
3525-
if (lock_fdc(drive))
3526-
return -EINTR;
3527-
set_floppy(drive);
3528-
i = raw_cmd_ioctl(cmd, (void __user *)param);
3529-
if (i == -EINTR)
3530-
return -EINTR;
3531-
process_fd_request();
3532-
return i;
3553+
return floppy_raw_cmd_ioctl(type, drive, cmd, (void __user *)param);
35333554
case FDTWADDLE:
35343555
if (lock_fdc(drive))
35353556
return -EINTR;

0 commit comments

Comments
 (0)