patch "staging: comedi: addi_apci_1500: check INSN_CONFIG_DIGITAL_TRIG shift" added to staging-linus
Subsystems (2)
This is a note to let you know that I've just added the patch titled
staging: comedi: addi_apci_1500: check INSN_CONFIG_DIGITAL_TRIG shift
to my staging git tree which can be found at
git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git
in the staging-linus branch.
The patch will show up in the next release of the linux-next tree (usually sometime within the next 24 hours during the week.)
The patch will hopefully also be merged in Linus's tree for the next -rc kernel release.
If you have any questions about this process, please let me know.
From fc846e9db67c7e808d77bf9e2ef3d49e3820ce5d Mon Sep 17 00:00:00 2001
From: Ian Abbott <[email protected]>
Date: Fri, 17 Jul 2020 15:52:57 +0100
Subject: staging: comedi: addi_apci_1500: check INSN_CONFIG_DIGITAL_TRIG shift
The INSN_CONFIG comedi instruction with sub-instruction code INSN_CONFIG_DIGITAL_TRIG includes a base channel in data[3]. This is used as a right shift amount for other bitmask values without being checked. Shift amounts greater than or equal to 32 will result in undefined behavior. Add code to deal with this, adjusting the checks for invalid channels so that enabled channel bits that would have been lost by shifting are also checked for validity. Only channels 0 to 15 are valid.
--- .../staging/comedi/drivers/addi_apci_1500.c | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-)
drivers/staging/comedi/drivers/addi_apci_1500.c +19 -5
@@ -452,13 +452,14 @@ static int apci1500_di_cfg_trig(struct comedi_device *dev,struct apci1500_private *devpriv = dev->private;unsigned int trig = data[1 ];unsigned int shift = data[3 ]; -unsigned int hi_mask = data[4 ] << shift; -unsigned int lo_mask = data[5 ] << shift; -unsigned int chan_mask = hi_mask | lo_mask; -unsigned int old_mask = (1 << shift) -1 ; +unsigned int hi_mask; +unsigned int lo_mask; +unsigned int chan_mask; +unsigned int old_mask;unsigned int pm;unsigned int pt;unsigned int pp; +unsigned int invalid_chan;if (trig >1 ) { dev_dbg(dev->class_dev,
@@ -466,7 +467,20 @@ static int apci1500_di_cfg_trig(struct comedi_device *dev,return -EINVAL ; } -if (chan_mask >0xffff ) { +if (shift <=16 ) { + hi_mask = data[4 ] << shift; + lo_mask = data[5 ] << shift; + old_mask = (1U << shift) -1 ; + invalid_chan = (data[4 ] | data[5 ]) >> (16 - shift); + }else { + hi_mask =0 ; + lo_mask =0 ; + old_mask =0xffff ; + invalid_chan = data[4 ] | data[5 ]; + } + chan_mask = hi_mask | lo_mask; + +if (invalid_chan) {dev_dbg (dev->class_dev,"invalid digital trigger channel\n" );return -EINVAL ; }
Signature · 1 line
2.27.0