Merge branch 'floppy'
[sfrench/cifs-2.6.git] / drivers / block / floppy.c
index 51246bc9709a55590c8ea8889b2b15b0bc66a42b..0469aceaa230778896d02dbde35e3270aa494992 100644 (file)
@@ -3233,8 +3233,10 @@ 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) ||
@@ -3380,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)
 {
@@ -3506,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:
@@ -3703,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;
@@ -3905,7 +3930,7 @@ static void __init config_types(void)
        if (!UDP->cmos)
                UDP->cmos = FLOPPY0_TYPE;
        drive = 1;
-       if (!UDP->cmos && FLOPPY1_TYPE)
+       if (!UDP->cmos)
                UDP->cmos = FLOPPY1_TYPE;
 
        /* FIXME: additional physical CMOS drive detection should go here */
@@ -4429,7 +4454,7 @@ static int __init floppy_setup(char *str)
                pr_cont("\n");
        } else
                DPRINT("botched floppy option\n");
-       DPRINT("Read Documentation/blockdev/floppy.txt\n");
+       DPRINT("Read Documentation/admin-guide/blockdev/floppy.rst\n");
        return 0;
 }