staging: comedi: drivers: properly validate cmd->scan_end_arg
authorH Hartley Sweeten <hsweeten@visionengravers.com>
Thu, 17 Apr 2014 17:07:47 +0000 (10:07 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 22 Apr 2014 17:21:29 +0000 (10:21 -0700)
When the async command 'scan_end_src' is TRIG_COUNT the 'scan_end_arg'
is the cmd->chanlist_len. Fix a couple open-coded drivers. Add the
check to the drivers that do not validate this command argument.

The core validates that the cmd->chanlist_len is <= s->len_chanlist.
During the post config after the attach the core also make sure that
the s->len_chanlist is initialized. For clarity, initialize the
s->len_chanlist in a couple drivers that are relying on the core to
initialize it to '1'.

Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Reviewed-by: Ian Abbott <abbotti@mev.co.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/staging/comedi/drivers/8255.c
drivers/staging/comedi/drivers/addi-data/hwdrv_apci3120.c
drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c
drivers/staging/comedi/drivers/addi_apci_1032.c
drivers/staging/comedi/drivers/amplc_pc236.c
drivers/staging/comedi/drivers/comedi_parport.c
drivers/staging/comedi/drivers/dt282x.c
drivers/staging/comedi/drivers/ni_6527.c
drivers/staging/comedi/drivers/ni_65xx.c
drivers/staging/comedi/drivers/pcl726.c
drivers/staging/comedi/drivers/rtd520.c

index 48817f087d9758a1e0e40aedce29b25b5ce6bab4..1d53e241e84d94bfd873d44c3de10a06ed83ec31 100644 (file)
@@ -231,7 +231,7 @@ static int subdev_8255_cmdtest(struct comedi_device *dev,
        err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
        err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
        err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
-       err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1);
+       err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
        err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
 
        if (err)
@@ -298,6 +298,7 @@ int subdev_8255_init_irq(struct comedi_device *dev, struct comedi_subdevice *s,
        if (ret)
                return ret;
 
+       s->len_chanlist = 1;
        s->do_cmdtest   = subdev_8255_cmdtest;
        s->do_cmd       = subdev_8255_cmd;
        s->cancel       = subdev_8255_cancel;
index 66c24e41d0ffa8367b1c908585740347c73bb90e..7ead23e34e8ebba36e480c527945c0293e8fbfe8 100644 (file)
@@ -778,6 +778,7 @@ static int apci3120_ai_cmdtest(struct comedi_device *dev,
        }
 
        err |= cfc_check_trigger_arg_min(&cmd->chanlist_len, 1);
+       err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
 
        if (cmd->stop_src == TRIG_COUNT)
                err |= cfc_check_trigger_arg_min(&cmd->stop_arg, 1);
index 0536d83738616547fea494e25d959ea59502913c..76a66820775e113c17094c69ca5c33505cf37e1f 100644 (file)
@@ -2270,6 +2270,11 @@ static int apci3200_ai_cmdtest(struct comedi_device *dev,
                apci3200_reset(dev);
                return 2;
        }
+
+       /* Step 3: check if arguments are trivially valid */
+
+       err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
        /* i_FirstChannel=cmd->chanlist[0]; */
        s_BoardInfos[dev->minor].i_FirstChannel = cmd->chanlist[0];
        /* i_LastChannel=cmd->chanlist[1]; */
index d6a5424654fca732d655f9c2f134470fc370777b..c242afc9134d6978660ad724c7fdb7b685576d01 100644 (file)
@@ -198,7 +198,7 @@ static int apci1032_cos_cmdtest(struct comedi_device *dev,
        err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
        err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
        err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
-       err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1);
+       err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
        err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
 
        if (err)
@@ -332,6 +332,7 @@ static int apci1032_auto_attach(struct comedi_device *dev,
                s->range_table  = &range_digital;
                s->insn_config  = apci1032_cos_insn_config;
                s->insn_bits    = apci1032_cos_insn_bits;
+               s->len_chanlist = 1;
                s->do_cmdtest   = apci1032_cos_cmdtest;
                s->do_cmd       = apci1032_cos_cmd;
                s->cancel       = apci1032_cos_cancel;
index b21d7b48f1daf93ecc8365a21413cbe70023b7b0..2834d0a9342afe866e079f02808c3394868ae0f4 100644 (file)
@@ -314,7 +314,7 @@ static int pc236_intr_cmdtest(struct comedi_device *dev,
        err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
        err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
        err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
-       err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1);
+       err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
        err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
 
        if (err)
@@ -402,6 +402,7 @@ static int pc236_common_attach(struct comedi_device *dev, unsigned long iobase,
                        s->maxdata = 1;
                        s->range_table = &range_digital;
                        s->insn_bits = pc236_intr_insn;
+                       s->len_chanlist = 1;
                        s->do_cmdtest = pc236_intr_cmdtest;
                        s->do_cmd = pc236_intr_cmd;
                        s->cancel = pc236_intr_cancel;
index 9de81c7712fb9103ae9054f54b37abf4dfa2c0b8..50723b9406305c2a12ffb2c69fd44af37cc03172 100644 (file)
@@ -181,7 +181,7 @@ static int parport_intr_cmdtest(struct comedi_device *dev,
        err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
        err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
        err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
-       err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1);
+       err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
        err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
 
        if (err)
@@ -295,6 +295,7 @@ static int parport_attach(struct comedi_device *dev,
                s->maxdata      = 1;
                s->range_table  = &range_digital;
                s->insn_bits    = parport_intr_insn_bits;
+               s->len_chanlist = 1;
                s->do_cmdtest   = parport_intr_cmdtest;
                s->do_cmd       = parport_intr_cmd;
                s->cancel       = parport_intr_cancel;
index 16cc100531e5dbdb879220c206001c2b8d18cbf7..b1154f0641d2054437b8735d8b44050375f236ce 100644 (file)
@@ -852,7 +852,7 @@ static int dt282x_ao_cmdtest(struct comedi_device *dev,
        err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
        err |= cfc_check_trigger_arg_min(&cmd->scan_begin_arg, 5000);
        err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
-       err |= cfc_check_trigger_arg_max(&cmd->scan_end_arg, 2);
+       err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
 
        if (cmd->stop_src == TRIG_COUNT) {
                /* any count is allowed */
index 860fc81fb11c62bbaabcd714f1dfb2992d729734..2b2dafe29c05f1b04e4e93f1d2de5219c75af701 100644 (file)
@@ -253,7 +253,7 @@ static int ni6527_intr_cmdtest(struct comedi_device *dev,
        err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
        err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
        err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
-       err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1);
+       err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
        err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
 
        if (err)
@@ -421,6 +421,7 @@ static int ni6527_auto_attach(struct comedi_device *dev,
                s->range_table  = &range_digital;
                s->insn_config  = ni6527_intr_insn_config;
                s->insn_bits    = ni6527_intr_insn_bits;
+               s->len_chanlist = 1;
                s->do_cmdtest   = ni6527_intr_cmdtest;
                s->do_cmd       = ni6527_intr_cmd;
                s->cancel       = ni6527_intr_cancel;
index 6e42001f686e3906ff288a73618b12fff59a6e7a..2051a7c5de109d4222e3646a22a4d28db717c474 100644 (file)
@@ -473,7 +473,7 @@ static int ni_65xx_intr_cmdtest(struct comedi_device *dev,
        err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
        err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
        err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
-       err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1);
+       err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
        err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
 
        if (err)
@@ -671,6 +671,7 @@ static int ni_65xx_auto_attach(struct comedi_device *dev,
        s->n_chan = 1;
        s->range_table = &range_unknown;
        s->maxdata = 1;
+       s->len_chanlist = 1;
        s->do_cmdtest = ni_65xx_intr_cmdtest;
        s->do_cmd = ni_65xx_intr_cmd;
        s->cancel = ni_65xx_intr_cancel;
index cf9568ee46e46f2bcb064c5339baebb3c007aa8e..07ff1e22e61ca67e8bbb7768924c2dcbc19b81ae 100644 (file)
@@ -197,7 +197,7 @@ static int pcl726_intr_cmdtest(struct comedi_device *dev,
        err |= cfc_check_trigger_arg_is(&cmd->start_arg, 0);
        err |= cfc_check_trigger_arg_is(&cmd->scan_begin_arg, 0);
        err |= cfc_check_trigger_arg_is(&cmd->convert_arg, 0);
-       err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, 1);
+       err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
        err |= cfc_check_trigger_arg_is(&cmd->stop_arg, 0);
 
        if (err)
@@ -430,6 +430,7 @@ static int pcl726_attach(struct comedi_device *dev,
                s->maxdata      = 1;
                s->range_table  = &range_digital;
                s->insn_bits    = pcl726_intr_insn_bits;
+               s->len_chanlist = 1;
                s->do_cmdtest   = pcl726_intr_cmdtest;
                s->do_cmd       = pcl726_intr_cmd;
                s->cancel       = pcl726_intr_cancel;
index 1b1c166c8e9b1681301cd2d3e8f3a516fa896587..e7c2e34624d905a2111f40a7f84965a446c09377 100644 (file)
@@ -878,6 +878,8 @@ static int rtd_ai_cmdtest(struct comedi_device *dev,
                err |= cfc_check_trigger_arg_max(&cmd->convert_arg, 9);
        }
 
+       err |= cfc_check_trigger_arg_is(&cmd->scan_end_arg, cmd->chanlist_len);
+
        if (cmd->stop_src == TRIG_COUNT) {
                /* TODO check for rounding error due to counter wrap */
        } else {