All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jonathan Cameron <jic23@kernel.org>
To: Yizhuo <yzhai003@ucr.edu>
Cc: csong@cs.ucr.edu, zhiyunq@cs.ucr.edu,
	Hartmut Knaack <knaack.h@gmx.de>,
	Lars-Peter Clausen <lars@metafoo.de>,
	Peter Meerwald-Stadler <pmeerw@pmeerw.net>,
	Ray Jui <rjui@broadcom.com>,
	Scott Branden <sbranden@broadcom.com>,
	bcm-kernel-feedback-list@broadcom.com,
	Stephen Boyd <swboyd@chromium.org>,
	Allison Randal <allison@lohutok.net>,
	Thomas Gleixner <tglx@linutronix.de>,
	linux-iio@vger.kernel.org, linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] iio: adc: Variables could be uninitalized if regmap_read() fails
Date: Tue, 1 Oct 2019 10:18:21 +0100	[thread overview]
Message-ID: <20191001101821.438259c2@archlinux> (raw)
In-Reply-To: <20190930052540.19168-1-yzhai003@ucr.edu>

On Sun, 29 Sep 2019 22:25:39 -0700
Yizhuo <yzhai003@ucr.edu> wrote:

> Several functions in this file are trying to use regmap_read() to
> initialize the specific variable, however, if regmap_read() fails,
> the variable could be uninitialized but used directly, which is
> potentially unsafe. The return value of regmap_read() should be
> checked and handled.
> 
> Signed-off-by: Yizhuo <yzhai003@ucr.edu>
I haven't checked if this one has a clock, but there is a bigger issue.
See inline.

Jonathan

> ---
>  drivers/iio/adc/bcm_iproc_adc.c | 45 ++++++++++++++++++++++++++++-----
>  1 file changed, 39 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/iio/adc/bcm_iproc_adc.c b/drivers/iio/adc/bcm_iproc_adc.c
> index 646ebdc0a8b4..6df19ceb5ff2 100644
> --- a/drivers/iio/adc/bcm_iproc_adc.c
> +++ b/drivers/iio/adc/bcm_iproc_adc.c
> @@ -137,6 +137,7 @@ static irqreturn_t iproc_adc_interrupt_thread(int irq, void *data)
>  	u32 channel_intr_status;
>  	u32 intr_status;
>  	u32 intr_mask;
> +	int ret;
>  	struct iio_dev *indio_dev = data;
>  	struct iproc_adc_priv *adc_priv = iio_priv(indio_dev);
>  
> @@ -145,8 +146,19 @@ static irqreturn_t iproc_adc_interrupt_thread(int irq, void *data)
>  	 * Make sure this interrupt is intended for us.
>  	 * Handle only ADC channel specific interrupts.
>  	 */
> -	regmap_read(adc_priv->regmap, IPROC_INTERRUPT_STATUS, &intr_status);
> -	regmap_read(adc_priv->regmap, IPROC_INTERRUPT_MASK, &intr_mask);
> +	ret = regmap_read(adc_priv->regmap,
> +					IPROC_INTERRUPT_STATUS, &intr_status);
> +	if (ret) {
> +		dev_err(&indio_dev->dev, "Fail to read IPROC_INTERRUPT_STATUS.\n");
> +		return ret;
> +	}
> +
> +	ret = regmap_read(adc_priv->regmap, IPROC_INTERRUPT_MASK, &intr_mask);
> +	if (ret) {
> +		dev_err(&indio_dev->dev, "Fail to read IPROC_INTERRUPT_MASK.\n");
> +		return ret;
> +	}
You need to be extremely careful returning error codes from interrupt routines..

Basically you can't ;)

> +
>  	intr_status = intr_status & intr_mask;
>  	channel_intr_status = (intr_status & IPROC_ADC_INTR_MASK) >>
>  				IPROC_ADC_INTR;
> @@ -162,6 +174,7 @@ static irqreturn_t iproc_adc_interrupt_handler(int irq, void *data)
>  	struct iproc_adc_priv *adc_priv;
>  	struct iio_dev *indio_dev = data;
>  	unsigned int valid_entries;
> +	int ret;
>  	u32 intr_status;
>  	u32 intr_channels;
>  	u32 channel_status;
> @@ -169,23 +182,37 @@ static irqreturn_t iproc_adc_interrupt_handler(int irq, void *data)
>  
>  	adc_priv = iio_priv(indio_dev);
>  
> -	regmap_read(adc_priv->regmap, IPROC_INTERRUPT_STATUS, &intr_status);
> +	ret = regmap_read(adc_priv->regmap,
> +					IPROC_INTERRUPT_STATUS, &intr_status);
> +	if (ret) {
> +		dev_err(&indio_dev->dev, "Fail to read IPROC_INTERRUPT_STATUS.\n");
> +		return ret;
> +	}
> +
>  	dev_dbg(&indio_dev->dev, "iproc_adc_interrupt_handler(),INTRPT_STS:%x\n",
>  			intr_status);
>  
>  	intr_channels = (intr_status & IPROC_ADC_INTR_MASK) >> IPROC_ADC_INTR;
>  	if (intr_channels) {
> -		regmap_read(adc_priv->regmap,
> +		ret = regmap_read(adc_priv->regmap,
>  			    IPROC_ADC_CHANNEL_INTERRUPT_STATUS +
>  			    IPROC_ADC_CHANNEL_OFFSET * adc_priv->chan_id,
>  			    &ch_intr_status);
> +		if (ret) {
> +			dev_err(&indio_dev->dev, "Fail to read the register.\n");
> +			return ret;
> +		}
>  
>  		if (ch_intr_status & IPROC_ADC_CHANNEL_WTRMRK_INTR_MASK) {
> -			regmap_read(adc_priv->regmap,
> +			ret = regmap_read(adc_priv->regmap,
>  					IPROC_ADC_CHANNEL_STATUS +
>  					IPROC_ADC_CHANNEL_OFFSET *
>  					adc_priv->chan_id,
>  					&channel_status);
> +			if (ret) {
> +				dev_err(&indio_dev->dev, "Fail to read the register.\n");
> +				return ret;
> +			}
>  
>  			valid_entries = ((channel_status &
>  				IPROC_ADC_CHANNEL_VALID_ENTERIES_MASK) >>
> @@ -230,6 +257,7 @@ static int iproc_adc_do_read(struct iio_dev *indio_dev,
>  	u32 mask;
>  	u32 val_check;
>  	int failed_cnt = 0;
> +	int ret;
>  	struct iproc_adc_priv *adc_priv = iio_priv(indio_dev);
>  
>  	mutex_lock(&adc_priv->mutex);
> @@ -284,7 +312,12 @@ static int iproc_adc_do_read(struct iio_dev *indio_dev,
>  	 * Testing has shown that this may loop a few time, but we have never
>  	 * hit the full count.
>  	 */
> -	regmap_read(adc_priv->regmap, IPROC_INTERRUPT_MASK, &val_check);
> +	ret = regmap_read(adc_priv->regmap, IPROC_INTERRUPT_MASK, &val_check);
> +	if (ret) {
> +		dev_err(&indio_dev->dev, "Fail to read IPROC_INTERRUPT_MASK.\n");
> +		return ret;
> +	}
> +
>  	while (val_check != val) {
>  		failed_cnt++;
>  


WARNING: multiple messages have this Message-ID (diff)
From: Jonathan Cameron <jic23@kernel.org>
To: Yizhuo <yzhai003@ucr.edu>
Cc: csong@cs.ucr.edu, Lars-Peter Clausen <lars@metafoo.de>,
	Scott Branden <sbranden@broadcom.com>,
	linux-iio@vger.kernel.org, Ray Jui <rjui@broadcom.com>,
	zhiyunq@cs.ucr.edu, linux-kernel@vger.kernel.org,
	Stephen Boyd <swboyd@chromium.org>,
	bcm-kernel-feedback-list@broadcom.com,
	linux-arm-kernel@lists.infradead.org,
	Peter Meerwald-Stadler <pmeerw@pmeerw.net>,
	Hartmut Knaack <knaack.h@gmx.de>,
	Thomas Gleixner <tglx@linutronix.de>,
	Allison Randal <allison@lohutok.net>
Subject: Re: [PATCH] iio: adc: Variables could be uninitalized if regmap_read() fails
Date: Tue, 1 Oct 2019 10:18:21 +0100	[thread overview]
Message-ID: <20191001101821.438259c2@archlinux> (raw)
In-Reply-To: <20190930052540.19168-1-yzhai003@ucr.edu>

On Sun, 29 Sep 2019 22:25:39 -0700
Yizhuo <yzhai003@ucr.edu> wrote:

> Several functions in this file are trying to use regmap_read() to
> initialize the specific variable, however, if regmap_read() fails,
> the variable could be uninitialized but used directly, which is
> potentially unsafe. The return value of regmap_read() should be
> checked and handled.
> 
> Signed-off-by: Yizhuo <yzhai003@ucr.edu>
I haven't checked if this one has a clock, but there is a bigger issue.
See inline.

Jonathan

> ---
>  drivers/iio/adc/bcm_iproc_adc.c | 45 ++++++++++++++++++++++++++++-----
>  1 file changed, 39 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/iio/adc/bcm_iproc_adc.c b/drivers/iio/adc/bcm_iproc_adc.c
> index 646ebdc0a8b4..6df19ceb5ff2 100644
> --- a/drivers/iio/adc/bcm_iproc_adc.c
> +++ b/drivers/iio/adc/bcm_iproc_adc.c
> @@ -137,6 +137,7 @@ static irqreturn_t iproc_adc_interrupt_thread(int irq, void *data)
>  	u32 channel_intr_status;
>  	u32 intr_status;
>  	u32 intr_mask;
> +	int ret;
>  	struct iio_dev *indio_dev = data;
>  	struct iproc_adc_priv *adc_priv = iio_priv(indio_dev);
>  
> @@ -145,8 +146,19 @@ static irqreturn_t iproc_adc_interrupt_thread(int irq, void *data)
>  	 * Make sure this interrupt is intended for us.
>  	 * Handle only ADC channel specific interrupts.
>  	 */
> -	regmap_read(adc_priv->regmap, IPROC_INTERRUPT_STATUS, &intr_status);
> -	regmap_read(adc_priv->regmap, IPROC_INTERRUPT_MASK, &intr_mask);
> +	ret = regmap_read(adc_priv->regmap,
> +					IPROC_INTERRUPT_STATUS, &intr_status);
> +	if (ret) {
> +		dev_err(&indio_dev->dev, "Fail to read IPROC_INTERRUPT_STATUS.\n");
> +		return ret;
> +	}
> +
> +	ret = regmap_read(adc_priv->regmap, IPROC_INTERRUPT_MASK, &intr_mask);
> +	if (ret) {
> +		dev_err(&indio_dev->dev, "Fail to read IPROC_INTERRUPT_MASK.\n");
> +		return ret;
> +	}
You need to be extremely careful returning error codes from interrupt routines..

Basically you can't ;)

> +
>  	intr_status = intr_status & intr_mask;
>  	channel_intr_status = (intr_status & IPROC_ADC_INTR_MASK) >>
>  				IPROC_ADC_INTR;
> @@ -162,6 +174,7 @@ static irqreturn_t iproc_adc_interrupt_handler(int irq, void *data)
>  	struct iproc_adc_priv *adc_priv;
>  	struct iio_dev *indio_dev = data;
>  	unsigned int valid_entries;
> +	int ret;
>  	u32 intr_status;
>  	u32 intr_channels;
>  	u32 channel_status;
> @@ -169,23 +182,37 @@ static irqreturn_t iproc_adc_interrupt_handler(int irq, void *data)
>  
>  	adc_priv = iio_priv(indio_dev);
>  
> -	regmap_read(adc_priv->regmap, IPROC_INTERRUPT_STATUS, &intr_status);
> +	ret = regmap_read(adc_priv->regmap,
> +					IPROC_INTERRUPT_STATUS, &intr_status);
> +	if (ret) {
> +		dev_err(&indio_dev->dev, "Fail to read IPROC_INTERRUPT_STATUS.\n");
> +		return ret;
> +	}
> +
>  	dev_dbg(&indio_dev->dev, "iproc_adc_interrupt_handler(),INTRPT_STS:%x\n",
>  			intr_status);
>  
>  	intr_channels = (intr_status & IPROC_ADC_INTR_MASK) >> IPROC_ADC_INTR;
>  	if (intr_channels) {
> -		regmap_read(adc_priv->regmap,
> +		ret = regmap_read(adc_priv->regmap,
>  			    IPROC_ADC_CHANNEL_INTERRUPT_STATUS +
>  			    IPROC_ADC_CHANNEL_OFFSET * adc_priv->chan_id,
>  			    &ch_intr_status);
> +		if (ret) {
> +			dev_err(&indio_dev->dev, "Fail to read the register.\n");
> +			return ret;
> +		}
>  
>  		if (ch_intr_status & IPROC_ADC_CHANNEL_WTRMRK_INTR_MASK) {
> -			regmap_read(adc_priv->regmap,
> +			ret = regmap_read(adc_priv->regmap,
>  					IPROC_ADC_CHANNEL_STATUS +
>  					IPROC_ADC_CHANNEL_OFFSET *
>  					adc_priv->chan_id,
>  					&channel_status);
> +			if (ret) {
> +				dev_err(&indio_dev->dev, "Fail to read the register.\n");
> +				return ret;
> +			}
>  
>  			valid_entries = ((channel_status &
>  				IPROC_ADC_CHANNEL_VALID_ENTERIES_MASK) >>
> @@ -230,6 +257,7 @@ static int iproc_adc_do_read(struct iio_dev *indio_dev,
>  	u32 mask;
>  	u32 val_check;
>  	int failed_cnt = 0;
> +	int ret;
>  	struct iproc_adc_priv *adc_priv = iio_priv(indio_dev);
>  
>  	mutex_lock(&adc_priv->mutex);
> @@ -284,7 +312,12 @@ static int iproc_adc_do_read(struct iio_dev *indio_dev,
>  	 * Testing has shown that this may loop a few time, but we have never
>  	 * hit the full count.
>  	 */
> -	regmap_read(adc_priv->regmap, IPROC_INTERRUPT_MASK, &val_check);
> +	ret = regmap_read(adc_priv->regmap, IPROC_INTERRUPT_MASK, &val_check);
> +	if (ret) {
> +		dev_err(&indio_dev->dev, "Fail to read IPROC_INTERRUPT_MASK.\n");
> +		return ret;
> +	}
> +
>  	while (val_check != val) {
>  		failed_cnt++;
>  


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

  reply	other threads:[~2019-10-01  9:18 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-09-30  5:25 [PATCH] iio: adc: Variables could be uninitalized if regmap_read() fails Yizhuo
2019-09-30  5:25 ` Yizhuo
2019-10-01  9:18 ` Jonathan Cameron [this message]
2019-10-01  9:18   ` Jonathan Cameron

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20191001101821.438259c2@archlinux \
    --to=jic23@kernel.org \
    --cc=allison@lohutok.net \
    --cc=bcm-kernel-feedback-list@broadcom.com \
    --cc=csong@cs.ucr.edu \
    --cc=knaack.h@gmx.de \
    --cc=lars@metafoo.de \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-iio@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=pmeerw@pmeerw.net \
    --cc=rjui@broadcom.com \
    --cc=sbranden@broadcom.com \
    --cc=swboyd@chromium.org \
    --cc=tglx@linutronix.de \
    --cc=yzhai003@ucr.edu \
    --cc=zhiyunq@cs.ucr.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.