Commit 47d6a760 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'floppy'

Merge floppy ioctl verification fixes from Denis Efremov.

This also marks the floppy driver as orphaned - it turns out that Jiri
no longer has working hardware.

Actual working physical floppy hardware is getting hard to find, and
while Willy was able to test this, I think the driver can be considered
pretty much dead from an actual hardware standpoint.  The hardware that
is still sold seems to be mainly USB-based, which doesn't use this
legacy driver at all.

The old floppy disk controller is still emulated in various VM
environments, so the driver isn't going away, but let's see if anybody
is interested to step up to maintain it.

The lack of hardware also likely means that the ioctl range verification
fixes are probably mostly relevant to anybody using floppies in a
virtual environment.  Which is probably also going away in favor of USB
storage emulation, but who knows.

Will Decon reviewed the patches but I'm not rebasing them just for that,
so I'll add a
Reviewed-by: default avatarWill Deacon <will@kernel.org>

here instead.

* floppy:
  MAINTAINERS: mark floppy.c orphaned
  floppy: fix out-of-bounds read in copy_buffer
  floppy: fix invalid pointer dereference in drive_name
  floppy: fix out-of-bounds read in next_valid_format
  floppy: fix div-by-zero in setup_format_params
parents 22051d9c be2ece49
......@@ -6321,9 +6321,8 @@ F: Documentation/devicetree/bindings/counter/ftm-quaddec.txt
F: drivers/counter/ftm-quaddec.c
FLOPPY DRIVER
M: Jiri Kosina <jikos@kernel.org>
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jikos/floppy.git
S: Odd fixes
S: Orphan
L: linux-block@vger.kernel.org
F: drivers/block/floppy.c
FMC SUBSYSTEM
......
......@@ -2120,6 +2120,9 @@ static void setup_format_params(int track)
raw_cmd->kernel_data = floppy_track_buffer;
raw_cmd->length = 4 * F_SECT_PER_TRACK;
if (!F_SECT_PER_TRACK)
return;
/* allow for about 30ms for data transport per track */
head_shift = (F_SECT_PER_TRACK + 5) / 6;
......@@ -3230,8 +3233,12 @@ static int set_geometry(unsigned int cmd, struct floppy_struct *g,
int cnt;
/* sanity checking for parameters. */
if (g->sect <= 0 ||
g->head <= 0 ||
if ((int)g->sect <= 0 ||
(int)g->head <= 0 ||
/* check for overflow in max_sector */
(int)(g->sect * g->head) <= 0 ||
/* 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) ||
/* check if reserved bits are set */
(g->stretch & ~(FD_STRETCH | FD_SWAPSIDES | FD_SECTBASEMASK)) != 0)
......@@ -3375,6 +3382,24 @@ static int fd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
return 0;
}
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;
for (i = 0; i < 8; ++i) {
if (autodetect[i] < 0 ||
autodetect[i] >= floppy_type_size)
return false;
}
if (native_format < 0 || native_format >= 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)
{
......@@ -3501,6 +3526,9 @@ static int fd_locked_ioctl(struct block_device *bdev, fmode_t mode, unsigned int
SUPBOUND(size, strlen((const char *)outparam) + 1);
break;
case FDSETDRVPRM:
if (!valid_floppy_drive_params(inparam.dp.autodetect,
inparam.dp.native_format))
return -EINVAL;
*UDP = inparam.dp;
break;
case FDGETDRVPRM:
......@@ -3698,6 +3726,8 @@ static int compat_setdrvprm(int drive,
return -EPERM;
if (copy_from_user(&v, arg, sizeof(struct compat_floppy_drive_params)))
return -EFAULT;
if (!valid_floppy_drive_params(v.autodetect, v.native_format))
return -EINVAL;
mutex_lock(&floppy_mutex);
UDP->cmos = v.cmos;
UDP->max_dtr = v.max_dtr;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment