VYPR
Unrated severityNVD Advisory· Published Jun 8, 2026

CVE-2026-46282

CVE-2026-46282

Description

In the Linux kernel, the following vulnerability has been resolved:

iio: frequency: admv1013: fix NULL pointer dereference on str

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.

Affected products

2

Patches

8
2dc8d26690bf

iio: frequency: admv1013: fix NULL pointer dereference on str

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitAntoniu MiclausFixed in 7.0.4via kernel-cna
1 file changed · +37 29
  • drivers/iio/frequency/admv1013.c+37 29 modified
    diff --git a/drivers/iio/frequency/admv1013.c b/drivers/iio/frequency/admv1013.c
    index d29e288da011a..5cea2c9887905 100644
    --- a/drivers/iio/frequency/admv1013.c
    +++ b/drivers/iio/frequency/admv1013.c
    @@ -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),
    -- 
    cgit 1.3-korg
    
    
    
aac0a51b1670

iio: frequency: admv1013: fix NULL pointer dereference on str

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitAntoniu MiclausFixed in 7.1-rc1via kernel-cna
1 file changed · +37 29
  • drivers/iio/frequency/admv1013.c+37 29 modified
    diff --git a/drivers/iio/frequency/admv1013.c b/drivers/iio/frequency/admv1013.c
    index 9202443ef4452..b852378b3f68d 100644
    --- a/drivers/iio/frequency/admv1013.c
    +++ b/drivers/iio/frequency/admv1013.c
    @@ -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;
    -
    -	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),
    -- 
    cgit 1.3-korg
    
    
    
3a9d8ec2051c

iio: frequency: admv1013: fix NULL pointer dereference on str

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitAntoniu MiclausFixed in 6.12.86via kernel-cna
1 file changed · +37 29
  • drivers/iio/frequency/admv1013.c+37 29 modified
    diff --git a/drivers/iio/frequency/admv1013.c b/drivers/iio/frequency/admv1013.c
    index 72d1ea7997243..635bcd7556f07 100644
    --- a/drivers/iio/frequency/admv1013.c
    +++ b/drivers/iio/frequency/admv1013.c
    @@ -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),
    -- 
    cgit 1.3-korg
    
    
    
5e9f1bad26df

iio: frequency: admv1013: fix NULL pointer dereference on str

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitAntoniu MiclausFixed in 6.18.27via kernel-cna
1 file changed · +37 29
  • drivers/iio/frequency/admv1013.c+37 29 modified
    diff --git a/drivers/iio/frequency/admv1013.c b/drivers/iio/frequency/admv1013.c
    index d29e288da011a..5cea2c9887905 100644
    --- a/drivers/iio/frequency/admv1013.c
    +++ b/drivers/iio/frequency/admv1013.c
    @@ -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),
    -- 
    cgit 1.3-korg
    
    
    
3a9d8ec2051c

iio: frequency: admv1013: fix NULL pointer dereference on str

1 file changed · +37 29
  • drivers/iio/frequency/admv1013.c+37 29 modified
    diff --git a/drivers/iio/frequency/admv1013.c b/drivers/iio/frequency/admv1013.c
    index 72d1ea7997243..635bcd7556f07 100644
    --- a/drivers/iio/frequency/admv1013.c
    +++ b/drivers/iio/frequency/admv1013.c
    @@ -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),
    -- 
    cgit 1.3-korg
    
    
    
2dc8d26690bf

iio: frequency: admv1013: fix NULL pointer dereference on str

1 file changed · +37 29
  • drivers/iio/frequency/admv1013.c+37 29 modified
    diff --git a/drivers/iio/frequency/admv1013.c b/drivers/iio/frequency/admv1013.c
    index d29e288da011a..5cea2c9887905 100644
    --- a/drivers/iio/frequency/admv1013.c
    +++ b/drivers/iio/frequency/admv1013.c
    @@ -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),
    -- 
    cgit 1.3-korg
    
    
    
aac0a51b1670

iio: frequency: admv1013: fix NULL pointer dereference on str

1 file changed · +37 29
  • drivers/iio/frequency/admv1013.c+37 29 modified
    diff --git a/drivers/iio/frequency/admv1013.c b/drivers/iio/frequency/admv1013.c
    index 9202443ef4452..b852378b3f68d 100644
    --- a/drivers/iio/frequency/admv1013.c
    +++ b/drivers/iio/frequency/admv1013.c
    @@ -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;
    -
    -	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),
    -- 
    cgit 1.3-korg
    
    
    
5e9f1bad26df

iio: frequency: admv1013: fix NULL pointer dereference on str

1 file changed · +37 29
  • drivers/iio/frequency/admv1013.c+37 29 modified
    diff --git a/drivers/iio/frequency/admv1013.c b/drivers/iio/frequency/admv1013.c
    index d29e288da011a..5cea2c9887905 100644
    --- a/drivers/iio/frequency/admv1013.c
    +++ b/drivers/iio/frequency/admv1013.c
    @@ -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),
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"The code dereferences an uninitialized pointer when reading device properties."

Attack vector

An attacker can trigger this vulnerability by providing malformed device properties to the admv1013 driver. Specifically, if the `device_property_read_string()` function fails to read a string property, the `str` variable remains uninitialized. The subsequent call to `strcmp(str, ...)` then dereferences this uninitialized pointer, leading to a NULL pointer dereference.

Affected code

The vulnerability exists in the `admv1013_properties_parse` function within the `drivers/iio/frequency/admv1013.c` file. The issue arises from the way string properties like `adi,input-mode` and `adi,quad-se-mode` are read and processed using `device_property_read_string()` and `strcmp()`.

What the fix does

The patch replaces the manual reading and comparison of string properties with `device_property_match_property_string()`. This function safely handles cases where the property might not be found or is malformed, preventing the dereference of an uninitialized pointer. Additionally, the SE mode enums were consolidated and mapped to hardware register values more consistently.

Generated on Jun 8, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

1