Skip to content

Commit 1bd34ad

Browse files
torvaldsBrian Maly
authored andcommitted
floppy: check FDC index for errors before assigning it
Jordy Zomer reported a KASAN out-of-bounds read in the floppy driver in wait_til_ready(). Which on the face of it can't happen, since as Willy Tarreau points out, the function does no particular memory access. Except through the FDCS macro, which just indexes a static allocation through teh current fdc, which is always checked against N_FDC. Except the checking happens after we've already assigned the value. The floppy driver is a disgrace (a lot of it going back to my original horrd "design"), and has no real maintainer. Nobody has the hardware, and nobody really cares. But it still gets used in virtual environment because it's one of those things that everybody supports. The whole thing should be re-written, or at least parts of it should be seriously cleaned up. The 'current fdc' index, which is used by the FDCS macro, and which is often shadowed by a local 'fdc' variable, is a prime example of how not to write code. But because nobody has the hardware or the motivation, let's just fix up the immediate problem with a nasty band-aid: test the fdc index before actually assigning it to the static 'fdc' variable. Reported-by: Jordy Zomer <[email protected]> Cc: Willy Tarreau <[email protected]> Cc: Dan Carpenter <[email protected]> Signed-off-by: Linus Torvalds <[email protected]> (cherry picked from commit 2e90ca6) Orabug: 31067516 CVE: CVE-2020-9383 Reviewed-by: John Donnelly <[email protected]> Signed-off-by: Allen Pais <[email protected]> Signed-off-by: Brian Maly <[email protected]>
1 parent 7ec59a8 commit 1bd34ad

File tree

1 file changed

+5
-2
lines changed

1 file changed

+5
-2
lines changed

drivers/block/floppy.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -847,14 +847,17 @@ static void reset_fdc_info(int mode)
847847
/* selects the fdc and drive, and enables the fdc's input/dma. */
848848
static void set_fdc(int drive)
849849
{
850+
unsigned int new_fdc = fdc;
851+
850852
if (drive >= 0 && drive < N_DRIVE) {
851-
fdc = FDC(drive);
853+
new_fdc = FDC(drive);
852854
current_drive = drive;
853855
}
854-
if (fdc != 1 && fdc != 0) {
856+
if (new_fdc >= N_FDC) {
855857
pr_info("bad fdc value\n");
856858
return;
857859
}
860+
fdc = new_fdc;
858861
set_dor(fdc, ~0, 8);
859862
#if N_FDC > 1
860863
set_dor(1 - fdc, ~8, 0);

0 commit comments

Comments
 (0)