FAILED: patch "[PATCH] iio: frequency: admv1013: fix NULL pointer dereference on str" failed to apply to 6.12-stable tree
[email protected]
maintainerThe patch below does not apply to the 6.12-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.12.y
git checkout FETCH_HEAD
git cherry-pick -x aac0a51b16700b403a55b67ba495de021db78763
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026050124-kiwi-tapeless-d419@gregkh' --subject-prefix 'PATCH 6.12.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From aac0a51b16700b403a55b67ba495de021db78763 Mon Sep 17 00:00:00 2001
From: Antoniu Miclaus <[email protected]>
Date: Thu, 5 Mar 2026 11:14:48 +0200
Subject: [PATCH] iio: frequency: admv1013: fix NULL pointer dereference on str
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
When device_property_read_string() fails, str is left uninitialized but the code falls through to strcmp(str, ...), dereferencing a garbage pointer. Replace manual read/strcmp with device_property_match_property_string() and consolidate the SE mode enums into a single sequential enum, mapping to hardware register values via a switch consistent with other bitfields in the driver.
Several cleanup patches have been applied to this driver recently so this will need a manual backport.
drivers/iio/frequency/admv1013.c +37 -28
@@ -85,9 +85,9 @@ enum { };enum { -ADMV1013_SE_MODE_POS =6 , -ADMV1013_SE_MODE_NEG =9 , -ADMV1013_SE_MODE_DIFF =12 +ADMV1013_SE_MODE_POS , +ADMV1013_SE_MODE_NEG , +ADMV1013_SE_MODE_DIFF , };struct admv1013_state {
@@ -468,10 +468,23 @@ static int admv1013_init(struct admv1013_state *st, int vcm_uv)if (ret)return ret; - data =FIELD_PREP (ADMV1013_QUAD_SE_MODE_MSK , st->quad_se_mode); +switch (st->quad_se_mode) { +case ADMV1013_SE_MODE_POS : + data =6 ; +break ; +case ADMV1013_SE_MODE_NEG : + data =9 ; +break ; +case ADMV1013_SE_MODE_DIFF : + data =12 ; +break ; +default : +return -EINVAL ; + } ret =__admv1013_spi_update_bits (st,ADMV1013_REG_QUAD , -ADMV1013_QUAD_SE_MODE_MSK , data); +ADMV1013_QUAD_SE_MODE_MSK , +FIELD_PREP (ADMV1013_QUAD_SE_MODE_MSK , data));if (ret)return ret;
@@ -512,37 +525,33 @@ static void admv1013_powerdown(void *data)admv1013_spi_update_bits (data,ADMV1013_REG_ENABLE , enable_reg_msk, enable_reg); } +static const char *const admv1013_input_modes[] = { + [ADMV1013_IQ_MODE ] ="iq" , + [ADMV1013_IF_MODE ] ="if" , +}; + +static const char *const admv1013_quad_se_modes[] = { + [ADMV1013_SE_MODE_POS ] ="se-pos" , + [ADMV1013_SE_MODE_NEG ] ="se-neg" , + [ADMV1013_SE_MODE_DIFF ] ="diff" , +}; +static int admv1013_properties_parse (struct admv1013_state *st) {int ret; -const char *str;struct device *dev = &st->spi->dev; st->det_en =device_property_read_bool (dev,"adi,detector-enable" ); - ret =device_property_read_string (dev,"adi,input-mode" , &str); -if (ret) - st->input_mode =ADMV1013_IQ_MODE ; + ret =device_property_match_property_string (dev,"adi,input-mode" , + admv1013_input_modes, +ARRAY_SIZE (admv1013_input_modes)); + st->input_mode = ret >=0 ? ret :ADMV1013_IQ_MODE ; -if (!strcmp (str,"iq" )) - st->input_mode =ADMV1013_IQ_MODE ; -else if (!strcmp (str,"if" )) - st->input_mode =ADMV1013_IF_MODE ; -else -return -EINVAL ; - - ret =device_property_read_string (dev,"adi,quad-se-mode" , &str); -if (ret) - st->quad_se_mode =ADMV1013_SE_MODE_DIFF ; - -if (!strcmp (str,"diff" )) - st->quad_se_mode =ADMV1013_SE_MODE_DIFF ; -else if (!strcmp (str,"se-pos" )) - st->quad_se_mode =ADMV1013_SE_MODE_POS ; -else if (!strcmp (str,"se-neg" )) - st->quad_se_mode =ADMV1013_SE_MODE_NEG ; -else -return -EINVAL ; + ret =device_property_match_property_string (dev,"adi,quad-se-mode" , + admv1013_quad_se_modes, +ARRAY_SIZE (admv1013_quad_se_modes)); + st->quad_se_mode = ret >=0 ? ret :ADMV1013_SE_MODE_DIFF ; ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(admv1013_vcc_regs),
Sasha Levin
maintainerPATCH 1/2 iio: frequency: admv1013: add dev variable
From: Antoniu Miclaus <[email protected]>
[ Upstream commit e61b5bb0e91390adee41eaddc0a1a7d55d5652b2 ]
Introduce a local struct device pointer in functions that reference &spi->dev for device-managed resource calls and device property reads, improving code readability.
Stable-dep-of: aac0a51b1670 ("iio: frequency: admv1013: fix NULL pointer dereference on str")
--- drivers/iio/frequency/admv1013.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-)
drivers/iio/frequency/admv1013.c +15 -14
@@ -518,11 +518,11 @@ static int admv1013_properties_parse(struct admv1013_state *st) {int ret;const char *str; -struct spi_device *spi = st->spi; +struct device *dev = &st->spi->dev; - st->det_en =device_property_read_bool (&spi->dev,"adi,detector-enable" ); + st->det_en =device_property_read_bool (dev,"adi,detector-enable" ); - ret =device_property_read_string (&spi->dev,"adi,input-mode" , &str); + ret =device_property_read_string (dev,"adi,input-mode" , &str);if (ret) st->input_mode =ADMV1013_IQ_MODE ;
@@ -533,7 +533,7 @@ static int admv1013_properties_parse(struct admv1013_state *st)else return -EINVAL ; - ret =device_property_read_string (&spi->dev,"adi,quad-se-mode" , &str); + ret =device_property_read_string (dev,"adi,quad-se-mode" , &str);if (ret) st->quad_se_mode =ADMV1013_SE_MODE_DIFF ;
@@ -546,11 +546,11 @@ static int admv1013_properties_parse(struct admv1013_state *st)else return -EINVAL ; - ret =devm_regulator_bulk_get_enable (&st->spi->dev, + ret =devm_regulator_bulk_get_enable (dev,ARRAY_SIZE (admv1013_vcc_regs), admv1013_vcc_regs);if (ret) { -dev_err_probe (&spi->dev, ret, +dev_err_probe (dev, ret,"Failed to request VCC regulators\n" );return ret; }
@@ -562,9 +562,10 @@ static int admv1013_probe(struct spi_device *spi) {struct iio_dev *indio_dev;struct admv1013_state *st; +struct device *dev = &spi->dev;int ret, vcm_uv; - indio_dev =devm_iio_device_alloc (&spi->dev,sizeof (*st)); + indio_dev =devm_iio_device_alloc (dev,sizeof (*st));if (!indio_dev)return -ENOMEM ;
@@ -581,20 +582,20 @@ static int admv1013_probe(struct spi_device *spi)if (ret)return ret; - ret =devm_regulator_get_enable_read_voltage (&spi->dev,"vcm" ); + ret =devm_regulator_get_enable_read_voltage (dev,"vcm" );if (ret <0 ) -return dev_err_probe (&spi->dev, ret, +return dev_err_probe (dev, ret,"failed to get the common-mode voltage\n" ); vcm_uv = ret; - st->clkin =devm_clk_get_enabled (&spi->dev,"lo_in" ); + st->clkin =devm_clk_get_enabled (dev,"lo_in" );if (IS_ERR (st->clkin)) -return dev_err_probe (&spi->dev,PTR_ERR (st->clkin), +return dev_err_probe (dev,PTR_ERR (st->clkin),"failed to get the LO input clock\n" ); st->nb.notifier_call = admv1013_freq_change; - ret =devm_clk_notifier_register (&spi->dev, st->clkin, &st->nb); + ret =devm_clk_notifier_register (dev, st->clkin, &st->nb);if (ret)return ret;
@@ -606,11 +607,11 @@ static int admv1013_probe(struct spi_device *spi)return ret; } - ret =devm_add_action_or_reset (&spi->dev, admv1013_powerdown, st); + ret =devm_add_action_or_reset (dev, admv1013_powerdown, st);if (ret)return ret; -return devm_iio_device_register (&spi->dev, indio_dev); +return devm_iio_device_register (dev, indio_dev); }static const struct spi_device_id admv1013_id[] = {
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/2 iio: frequency: admv1013: fix NULL pointer dereference on str
From: Antoniu Miclaus <[email protected]>
[ Upstream commit aac0a51b16700b403a55b67ba495de021db78763 ]
When device_property_read_string() fails, str is left uninitialized but the code falls through to strcmp(str, ...), dereferencing a garbage pointer. Replace manual read/strcmp with device_property_match_property_string() and consolidate the SE mode enums into a single sequential enum, mapping to hardware register values via a switch consistent with other bitfields in the driver.
Several cleanup patches have been applied to this driver recently so this will need a manual backport.
--- drivers/iio/frequency/admv1013.c | 65 ++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 28 deletions(-)
drivers/iio/frequency/admv1013.c +37 -28
@@ -85,9 +85,9 @@ enum { };enum { -ADMV1013_SE_MODE_POS =6 , -ADMV1013_SE_MODE_NEG =9 , -ADMV1013_SE_MODE_DIFF =12 +ADMV1013_SE_MODE_POS , +ADMV1013_SE_MODE_NEG , +ADMV1013_SE_MODE_DIFF , };struct admv1013_state {
@@ -470,10 +470,23 @@ static int admv1013_init(struct admv1013_state *st, int vcm_uv)if (ret)return ret; - data =FIELD_PREP (ADMV1013_QUAD_SE_MODE_MSK , st->quad_se_mode); +switch (st->quad_se_mode) { +case ADMV1013_SE_MODE_POS : + data =6 ; +break ; +case ADMV1013_SE_MODE_NEG : + data =9 ; +break ; +case ADMV1013_SE_MODE_DIFF : + data =12 ; +break ; +default : +return -EINVAL ; + } ret =__admv1013_spi_update_bits (st,ADMV1013_REG_QUAD , -ADMV1013_QUAD_SE_MODE_MSK , data); +ADMV1013_QUAD_SE_MODE_MSK , +FIELD_PREP (ADMV1013_QUAD_SE_MODE_MSK , data));if (ret)return ret;
@@ -514,37 +527,33 @@ static void admv1013_powerdown(void *data)admv1013_spi_update_bits (data,ADMV1013_REG_ENABLE , enable_reg_msk, enable_reg); } +static const char *const admv1013_input_modes[] = { + [ADMV1013_IQ_MODE ] ="iq" , + [ADMV1013_IF_MODE ] ="if" , +}; + +static const char *const admv1013_quad_se_modes[] = { + [ADMV1013_SE_MODE_POS ] ="se-pos" , + [ADMV1013_SE_MODE_NEG ] ="se-neg" , + [ADMV1013_SE_MODE_DIFF ] ="diff" , +}; +static int admv1013_properties_parse (struct admv1013_state *st) {int ret; -const char *str;struct device *dev = &st->spi->dev; st->det_en =device_property_read_bool (dev,"adi,detector-enable" ); - ret =device_property_read_string (dev,"adi,input-mode" , &str); -if (ret) - st->input_mode =ADMV1013_IQ_MODE ; - -if (!strcmp (str,"iq" )) - st->input_mode =ADMV1013_IQ_MODE ; -else if (!strcmp (str,"if" )) - st->input_mode =ADMV1013_IF_MODE ; -else -return -EINVAL ; + ret =device_property_match_property_string (dev,"adi,input-mode" , + admv1013_input_modes, +ARRAY_SIZE (admv1013_input_modes)); + st->input_mode = ret >=0 ? ret :ADMV1013_IQ_MODE ; - ret =device_property_read_string (dev,"adi,quad-se-mode" , &str); -if (ret) - st->quad_se_mode =ADMV1013_SE_MODE_DIFF ; - -if (!strcmp (str,"diff" )) - st->quad_se_mode =ADMV1013_SE_MODE_DIFF ; -else if (!strcmp (str,"se-pos" )) - st->quad_se_mode =ADMV1013_SE_MODE_POS ; -else if (!strcmp (str,"se-neg" )) - st->quad_se_mode =ADMV1013_SE_MODE_NEG ; -else -return -EINVAL ; + ret =device_property_match_property_string (dev,"adi,quad-se-mode" , + admv1013_quad_se_modes, +ARRAY_SIZE (admv1013_quad_se_modes)); + st->quad_se_mode = ret >=0 ? ret :ADMV1013_SE_MODE_DIFF ; ret = devm_regulator_bulk_get_enable(dev, ARRAY_SIZE(admv1013_vcc_regs),
Signature · 1 line
2.53.0