This patchset fixes WLED's handling of enabled-strings: besides some
cleanup it is now actually possible to specify a non-contiguous array of
enabled strings (not necessarily starting at zero) and the values from
DT are now validated to prevent possible unexpected out-of-bounds
register and array element accesses.
Off-by-one mistakes in the maximum number of strings, also causing
out-of-bounds access, have been addressed as well.
Marijn Suijten (10):
backlight: qcom-wled: Pass number of elements to read to
read_u32_array
backlight: qcom-wled: Use cpu_to_le16 macro to perform conversion
backlight: qcom-wled: Override num-strings when enabled-strings is set
backlight: qcom-wled: Validate enabled string indices in DT
backlight: qcom-wled: Fix off-by-one maximum with default num_strings
backlight: qcom-wled: Remove unnecessary 4th default string in wled3
backlight: qcom-wled: Provide enabled_strings default for wled 4 and 5
backlight: qcom-wled: Remove unnecessary double whitespace
backlight: qcom-wled: Consistently use enabled-strings in
set_brightness
backlight: qcom-wled: Consider enabled_strings in autodetection
drivers/video/backlight/qcom-wled.c | 88 ++++++++++++++++++-----------
1 file changed, 55 insertions(+), 33 deletions(-)
--
2.33.0
of_property_read_u32_array takes the number of elements to read as last
argument. This does not always need to be 4 (sizeof(u32)) but should
instead be the size of the array in DT as read just above with
of_property_count_elems_of_size.
To not make such an error go unnoticed again the driver now bails
accordingly when of_property_read_u32_array returns an error.
Fixes: 775d2ffb4af6 ("backlight: qcom-wled: Restructure the driver for WLED3")
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: AngeloGioacchino Del Regno <redacted>
---
drivers/video/backlight/qcom-wled.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
@@ -1528,11 +1528,18 @@ static int wled_configure(struct wled *wled)string_len=of_property_count_elems_of_size(dev->of_node,"qcom,enabled-strings",sizeof(u32));-if(string_len>0)-of_property_read_u32_array(dev->of_node,+if(string_len>0){+rc=of_property_read_u32_array(dev->of_node,"qcom,enabled-strings",wled->cfg.enabled_strings,-sizeof(u32));+string_len);+if(rc){+dev_err(dev,"Failed to read %d elements from "+"qcom,enabled-strings: %d\n",+string_len,rc);+return-EINVAL;+}+}return0;}
The kernel already provides appropriate primitives to perform endianness
conversion which should be used in favour of manual bit-wrangling.
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: AngeloGioacchino Del Regno <redacted>
---
drivers/video/backlight/qcom-wled.c | 25 +++++++++++--------------
1 file changed, 11 insertions(+), 14 deletions(-)
The strings passed in DT may possibly cause out-of-bounds register
accesses and should be validated before use.
Fixes: 775d2ffb4af6 ("backlight: qcom-wled: Restructure the driver for WLED3")
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: AngeloGioacchino Del Regno <redacted>
---
drivers/video/backlight/qcom-wled.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
@@ -1526,6 +1526,12 @@ static int wled_configure(struct wled *wled)"qcom,enabled-strings",sizeof(u32));if(string_len>0){+if(string_len>wled->max_string_count){+dev_err(dev,"Cannot have more than %d strings\n",+wled->max_string_count);+return-EINVAL;+}+rc=of_property_read_u32_array(dev->of_node,"qcom,enabled-strings",wled->cfg.enabled_strings,
@@ -1537,6 +1543,14 @@ static int wled_configure(struct wled *wled)return-EINVAL;}+for(i=0;i<string_len;++i){+if(wled->cfg.enabled_strings[i]>=wled->max_string_count){+dev_err(dev,"qcom,enabled-strings index %d at %d is out of bounds\n",+wled->cfg.enabled_strings[i],i);+return-EINVAL;+}+}+cfg->num_strings=string_len;}
When not specifying num-strings in the DT the default is used, but +1 is
added to it which turns wled3 into 4 and wled4/5 into 5 strings instead
of 3 and 4 respectively, causing out of bounds reads and register
read/writes. This +1 exists for a deficiency in the DT parsing code,
and is simply omitted entirely - solving this oob issue - by allowing
one extra iteration of the wled_var_cfg function parsing this particular
property.
Fixes: 93c64f1ea1e8 ("leds: add Qualcomm PM8941 WLED driver")
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: AngeloGioacchino Del Regno <redacted>
---
drivers/video/backlight/qcom-wled.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
DT-bindings do not specify num-strings as mandatory property, yet it is
required to be specified even if enabled-strings is used. The length of
that property-array should already be enough to determine exactly which
and how many strings to enable.
Fixes: 775d2ffb4af6 ("backlight: qcom-wled: Restructure the driver for WLED3")
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: AngeloGioacchino Del Regno <redacted>
---
drivers/video/backlight/qcom-wled.c | 2 ++
1 file changed, 2 insertions(+)
Only wled 3 sets a sensible default that allows operating this driver
with just qcom,num-strings in the DT; wled 4 and 5 require
qcom,enabled-strings to be provided otherwise enabled_strings remains
zero-initialized, resuling in every string-specific register write
(currently only the setup and config functions, brightness follows in a
future patch) to only configure the zero'th string multiple times.
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: AngeloGioacchino Del Regno <redacted>
---
drivers/video/backlight/qcom-wled.c | 2 ++
1 file changed, 2 insertions(+)
The previous commit improves num_strings parsing to not go over the
maximum of 3 strings for wled3 anymore. Likewise this default index for
a hypothetical 4th string is invalid and could access registers that are
not mapped to the desired purpose.
Removing this value gets rid of undesired confusion and avoids the
possibility of accessing registers at this offset even if the 4th array
element is used by accident.
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: AngeloGioacchino Del Regno <redacted>
---
drivers/video/backlight/qcom-wled.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Remove redundant spaces inside for loop conditions. No other double
spaces were found that are not part of indentation with `[^\s] `.
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: AngeloGioacchino Del Regno <redacted>
---
drivers/video/backlight/qcom-wled.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
Following the previous commit using enabled_strings in set_brightness,
enabled_strings is now also used in the autodetection path for
consistent behaviour: when a list of strings is specified in DT only
those strings will be probed for autodetection, analogous to how the
number of strings that need to be probed is already bound by
qcom,num-strings.
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: AngeloGioacchino Del Regno <redacted>
---
drivers/video/backlight/qcom-wled.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
@@ -616,14 +616,15 @@ static void wled_auto_string_detection(struct wled *wled)/* Iterate through the strings one by one */for(i=0;i<wled->cfg.num_strings;i++){-sink_test=BIT((WLED4_SINK_REG_CURR_SINK_SHFT+i));+j=wled->cfg.enabled_strings[i];+sink_test=BIT((WLED4_SINK_REG_CURR_SINK_SHFT+j));/* Enable feedback control */rc=regmap_write(wled->regmap,wled->ctrl_addr+-WLED3_CTRL_REG_FEEDBACK_CONTROL,i+1);+WLED3_CTRL_REG_FEEDBACK_CONTROL,j+1);if(rc<0){dev_err(wled->dev,"Failed to enable feedback for SINK %d rc = %d\n",-i+1,rc);+j+1,rc);gotofailed_detect;}
The hardware is capable of controlling any non-contiguous sequence of
LEDs specified in the DT using qcom,enabled-strings as u32
array, and this also follows from the DT-bindings documentation. The
numbers specified in this array represent indices of the LED strings
that are to be enabled and disabled.
Its value is appropriately used to setup and enable string modules, but
completely disregarded in the set_brightness paths which only iterate
over the number of strings linearly.
Take an example where only string 2 is enabled with
qcom,enabled_strings=<2>: this string is appropriately enabled but
subsequent brightness changes would have only touched the zero'th
brightness register because num_strings is 1 here. This is simply
addressed by looking up the string for this index in the enabled_strings
array just like the other codepaths that iterate over num_strings.
Fixes: 775d2ffb4af6 ("backlight: qcom-wled: Restructure the driver for WLED3")
Fixes: 03b2b5e86986 ("backlight: qcom-wled: Add support for WLED4 peripheral")
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: AngeloGioacchino Del Regno <redacted>
---
drivers/video/backlight/qcom-wled.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
From: Daniel Thompson <hidden> Date: 2021-10-05 09:06:01
On Mon, Oct 04, 2021 at 09:27:32PM +0200, Marijn Suijten wrote:
of_property_read_u32_array takes the number of elements to read as last
argument. This does not always need to be 4 (sizeof(u32)) but should
instead be the size of the array in DT as read just above with
of_property_count_elems_of_size.
To not make such an error go unnoticed again the driver now bails
accordingly when of_property_read_u32_array returns an error.
Fixes: 775d2ffb4af6 ("backlight: qcom-wled: Restructure the driver for WLED3")
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: AngeloGioacchino Del Regno <redacted>
@@ -1528,11 +1528,18 @@ static int wled_configure(struct wled *wled)string_len=of_property_count_elems_of_size(dev->of_node,"qcom,enabled-strings",sizeof(u32));-if(string_len>0)-of_property_read_u32_array(dev->of_node,+if(string_len>0){+rc=of_property_read_u32_array(dev->of_node,"qcom,enabled-strings",wled->cfg.enabled_strings,-sizeof(u32));+string_len);+if(rc){+dev_err(dev,"Failed to read %d elements from "+"qcom,enabled-strings: %d\n",+string_len,rc);+return-EINVAL;+}+}return0;}
From: Daniel Thompson <hidden> Date: 2021-10-05 09:07:07
On Mon, Oct 04, 2021 at 09:27:33PM +0200, Marijn Suijten wrote:
The kernel already provides appropriate primitives to perform endianness
conversion which should be used in favour of manual bit-wrangling.
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: AngeloGioacchino Del Regno <redacted>
From: Daniel Thompson <hidden> Date: 2021-10-05 09:15:02
On Mon, Oct 04, 2021 at 09:27:35PM +0200, Marijn Suijten wrote:
The strings passed in DT may possibly cause out-of-bounds register
accesses and should be validated before use.
Fixes: 775d2ffb4af6 ("backlight: qcom-wled: Restructure the driver for WLED3")
The first half of this patch actually fixes patch 1 from this patch set.
It would be better to move that code there.
Daniel.
quoted hunk
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: AngeloGioacchino Del Regno <redacted>
---
drivers/video/backlight/qcom-wled.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
@@ -1526,6 +1526,12 @@ static int wled_configure(struct wled *wled)"qcom,enabled-strings",sizeof(u32));if(string_len>0){+if(string_len>wled->max_string_count){+dev_err(dev,"Cannot have more than %d strings\n",+wled->max_string_count);+return-EINVAL;+}+rc=of_property_read_u32_array(dev->of_node,"qcom,enabled-strings",wled->cfg.enabled_strings,
@@ -1537,6 +1543,14 @@ static int wled_configure(struct wled *wled)return-EINVAL;}+for(i=0;i<string_len;++i){+if(wled->cfg.enabled_strings[i]>=wled->max_string_count){+dev_err(dev,"qcom,enabled-strings index %d at %d is out of bounds\n",+wled->cfg.enabled_strings[i],i);+return-EINVAL;+}+}+cfg->num_strings=string_len;}
From: Daniel Thompson <hidden> Date: 2021-10-05 09:19:55
On Mon, Oct 04, 2021 at 09:27:36PM +0200, Marijn Suijten wrote:
quoted hunk
When not specifying num-strings in the DT the default is used, but +1 is
added to it which turns wled3 into 4 and wled4/5 into 5 strings instead
of 3 and 4 respectively, causing out of bounds reads and register
read/writes. This +1 exists for a deficiency in the DT parsing code,
and is simply omitted entirely - solving this oob issue - by allowing
one extra iteration of the wled_var_cfg function parsing this particular
property.
Fixes: 93c64f1ea1e8 ("leds: add Qualcomm PM8941 WLED driver")
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: AngeloGioacchino Del Regno <redacted>
---
drivers/video/backlight/qcom-wled.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
From: Daniel Thompson <hidden> Date: 2021-10-05 09:20:47
On Mon, Oct 04, 2021 at 09:27:37PM +0200, Marijn Suijten wrote:
The previous commit improves num_strings parsing to not go over the
maximum of 3 strings for wled3 anymore. Likewise this default index for
a hypothetical 4th string is invalid and could access registers that are
not mapped to the desired purpose.
Removing this value gets rid of undesired confusion and avoids the
possibility of accessing registers at this offset even if the 4th array
element is used by accident.
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: AngeloGioacchino Del Regno <redacted>
From: Daniel Thompson <hidden> Date: 2021-10-05 09:21:27
On Mon, Oct 04, 2021 at 09:27:38PM +0200, Marijn Suijten wrote:
Only wled 3 sets a sensible default that allows operating this driver
with just qcom,num-strings in the DT; wled 4 and 5 require
qcom,enabled-strings to be provided otherwise enabled_strings remains
zero-initialized, resuling in every string-specific register write
(currently only the setup and config functions, brightness follows in a
future patch) to only configure the zero'th string multiple times.
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: AngeloGioacchino Del Regno <redacted>
From: Daniel Thompson <hidden> Date: 2021-10-05 09:21:52
On Mon, Oct 04, 2021 at 09:27:39PM +0200, Marijn Suijten wrote:
Remove redundant spaces inside for loop conditions. No other double
spaces were found that are not part of indentation with `[^\s] `.
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: AngeloGioacchino Del Regno <redacted>
From: Daniel Thompson <hidden> Date: 2021-10-05 09:33:38
On Mon, Oct 04, 2021 at 09:27:40PM +0200, Marijn Suijten wrote:
The hardware is capable of controlling any non-contiguous sequence of
LEDs specified in the DT using qcom,enabled-strings as u32
array, and this also follows from the DT-bindings documentation. The
numbers specified in this array represent indices of the LED strings
that are to be enabled and disabled.
Its value is appropriately used to setup and enable string modules, but
completely disregarded in the set_brightness paths which only iterate
over the number of strings linearly.
Take an example where only string 2 is enabled with
qcom,enabled_strings=<2>: this string is appropriately enabled but
subsequent brightness changes would have only touched the zero'th
brightness register because num_strings is 1 here. This is simply
addressed by looking up the string for this index in the enabled_strings
array just like the other codepaths that iterate over num_strings.
This isn't true until patch 10 is applied!
Given both patches fix the same issue in different functions I'd prefer
these to be squashed together (and doubly so because the autodetect code
uses set_brightness() as a helper function).
Daniel.
From: Daniel Thompson <hidden> Date: 2021-10-05 09:38:28
On Mon, Oct 04, 2021 at 09:27:34PM +0200, Marijn Suijten wrote:
DT-bindings do not specify num-strings as mandatory property, yet it is
required to be specified even if enabled-strings is used. The length of
that property-array should already be enough to determine exactly which
and how many strings to enable.
Fixes: 775d2ffb4af6 ("backlight: qcom-wled: Restructure the driver for WLED3")
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: AngeloGioacchino Del Regno <redacted>
On Mon, Oct 04, 2021 at 09:27:35PM +0200, Marijn Suijten wrote:
quoted
The strings passed in DT may possibly cause out-of-bounds register
accesses and should be validated before use.
Fixes: 775d2ffb4af6 ("backlight: qcom-wled: Restructure the driver for WLED3")
The first half of this patch actually fixes patch 1 from this patch set.
It would be better to move that code there.
It only helps guarding against a maximum of 3 leds for WLED3, while
using string_len instead of an unintentional sizeof(u32) (resulting in
a fixed size of 4) is a different issue requiring a separate patch to
fix.
Would it help to reorder this patch before 1/10, and mention in patch
1/10 (then 2/10) that, besides properly using string_len instead of
hardcoded 4 (which causes wrong reads from DT on top of this), it relies
on the previous patch to prevent against an array longer than 3 for
WLED3?
- Marijn
Daniel.
quoted
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: AngeloGioacchino Del Regno <redacted>
---
drivers/video/backlight/qcom-wled.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
@@ -1526,6 +1526,12 @@ static int wled_configure(struct wled *wled)"qcom,enabled-strings",sizeof(u32));if(string_len>0){+if(string_len>wled->max_string_count){+dev_err(dev,"Cannot have more than %d strings\n",+wled->max_string_count);+return-EINVAL;+}+rc=of_property_read_u32_array(dev->of_node,"qcom,enabled-strings",wled->cfg.enabled_strings,
@@ -1537,6 +1543,14 @@ static int wled_configure(struct wled *wled)return-EINVAL;}+for(i=0;i<string_len;++i){+if(wled->cfg.enabled_strings[i]>=wled->max_string_count){+dev_err(dev,"qcom,enabled-strings index %d at %d is out of bounds\n",+wled->cfg.enabled_strings[i],i);+return-EINVAL;+}+}+cfg->num_strings=string_len;}
On Mon, Oct 04, 2021 at 09:27:36PM +0200, Marijn Suijten wrote:
quoted
When not specifying num-strings in the DT the default is used, but +1 is
added to it which turns wled3 into 4 and wled4/5 into 5 strings instead
of 3 and 4 respectively, causing out of bounds reads and register
read/writes. This +1 exists for a deficiency in the DT parsing code,
and is simply omitted entirely - solving this oob issue - by allowing
one extra iteration of the wled_var_cfg function parsing this particular
property.
Fixes: 93c64f1ea1e8 ("leds: add Qualcomm PM8941 WLED driver")
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: AngeloGioacchino Del Regno <redacted>
---
drivers/video/backlight/qcom-wled.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
These comments represent the possible loop iterations the DT "cfg
parser" runs through, starting at j=0 and running up until and including
j=3. Should I make that more clear or omit these comments entirely?
- Marijn
On Mon, Oct 04, 2021 at 09:27:40PM +0200, Marijn Suijten wrote:
quoted
The hardware is capable of controlling any non-contiguous sequence of
LEDs specified in the DT using qcom,enabled-strings as u32
array, and this also follows from the DT-bindings documentation. The
numbers specified in this array represent indices of the LED strings
that are to be enabled and disabled.
Its value is appropriately used to setup and enable string modules, but
completely disregarded in the set_brightness paths which only iterate
over the number of strings linearly.
Take an example where only string 2 is enabled with
qcom,enabled_strings=<2>: this string is appropriately enabled but
subsequent brightness changes would have only touched the zero'th
brightness register because num_strings is 1 here. This is simply
addressed by looking up the string for this index in the enabled_strings
array just like the other codepaths that iterate over num_strings.
This isn't true until patch 10 is applied!
Patch 9 and 10 were split up at a last resort to prevent a clash in the
title, apologies for that.
Given both patches fix the same issue in different functions I'd prefer
these to be squashed together (and doubly so because the autodetect code
uses set_brightness() as a helper function).
That's a fair reason, and solution I agree on. I'll figure out how to
generify the title and re-spin this patchset except if there are other
reviewers/maintainers I should wait for.
- Marijn
From: Daniel Thompson <hidden> Date: 2021-10-05 10:38:49
On Tue, Oct 05, 2021 at 12:06:06PM +0200, Marijn Suijten wrote:
On 2021-10-05 10:19:47, Daniel Thompson wrote:
quoted
On Mon, Oct 04, 2021 at 09:27:36PM +0200, Marijn Suijten wrote:
quoted
When not specifying num-strings in the DT the default is used, but +1 is
added to it which turns wled3 into 4 and wled4/5 into 5 strings instead
of 3 and 4 respectively, causing out of bounds reads and register
read/writes. This +1 exists for a deficiency in the DT parsing code,
and is simply omitted entirely - solving this oob issue - by allowing
one extra iteration of the wled_var_cfg function parsing this particular
property.
Fixes: 93c64f1ea1e8 ("leds: add Qualcomm PM8941 WLED driver")
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: AngeloGioacchino Del Regno <redacted>
---
drivers/video/backlight/qcom-wled.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
These comments represent the possible loop iterations the DT "cfg
parser" runs through, starting at j=0 and running up until and including
j=3. Should I make that more clear or omit these comments entirely?
The role of wled3_num_strings_values_fn() is to enumerate the list of
legal values for the property [ 1, 2, 3 ]. Your changes cause the
enumeration to include a non-legal value so that you can have an
identity mapping between the symbol and the enumerate value.
An alternative approach would be to leave the enumeration logic
alone but set the num_string default to UINT_MAX in all cases:
- cfg->num_strings = cfg->num_strings + 1;
+ if (cfg->num_strings == UINT_MAX)
+ cfg->num_strings =
+ else
+ /* Convert from enumerated to numeric form */
+ cfg->num_strings = wled3_num_strings_values_fn(
+ cfg->num_strings);
Daniel.
From: Daniel Thompson <hidden> Date: 2021-10-05 10:42:26
On Tue, Oct 05, 2021 at 12:03:50PM +0200, Marijn Suijten wrote:
On 2021-10-05 10:14:52, Daniel Thompson wrote:
quoted
On Mon, Oct 04, 2021 at 09:27:35PM +0200, Marijn Suijten wrote:
quoted
The strings passed in DT may possibly cause out-of-bounds register
accesses and should be validated before use.
Fixes: 775d2ffb4af6 ("backlight: qcom-wled: Restructure the driver for WLED3")
The first half of this patch actually fixes patch 1 from this patch set.
It would be better to move that code there.
It only helps guarding against a maximum of 3 leds for WLED3, while
using string_len instead of an unintentional sizeof(u32) (resulting in
a fixed size of 4) is a different issue requiring a separate patch to
fix.
Would it help to reorder this patch before 1/10, and mention in patch
1/10 (then 2/10) that, besides properly using string_len instead of
hardcoded 4 (which causes wrong reads from DT on top of this), it relies
on the previous patch to prevent against an array longer than 3 for
WLED3?
Reordering is OK for me.
Daniel.
quoted
quoted
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: AngeloGioacchino Del Regno <redacted>
---
drivers/video/backlight/qcom-wled.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
@@ -1526,6 +1526,12 @@ static int wled_configure(struct wled *wled)"qcom,enabled-strings",sizeof(u32));if(string_len>0){+if(string_len>wled->max_string_count){+dev_err(dev,"Cannot have more than %d strings\n",+wled->max_string_count);+return-EINVAL;+}+rc=of_property_read_u32_array(dev->of_node,"qcom,enabled-strings",wled->cfg.enabled_strings,
@@ -1537,6 +1543,14 @@ static int wled_configure(struct wled *wled)return-EINVAL;}+for(i=0;i<string_len;++i){+if(wled->cfg.enabled_strings[i]>=wled->max_string_count){+dev_err(dev,"qcom,enabled-strings index %d at %d is out of bounds\n",+wled->cfg.enabled_strings[i],i);+return-EINVAL;+}+}+cfg->num_strings=string_len;}
From: Daniel Thompson <hidden> Date: 2021-10-05 10:53:20
On Tue, Oct 05, 2021 at 11:38:43AM +0100, Daniel Thompson wrote:
On Tue, Oct 05, 2021 at 12:06:06PM +0200, Marijn Suijten wrote:
quoted
On 2021-10-05 10:19:47, Daniel Thompson wrote:
quoted
On Mon, Oct 04, 2021 at 09:27:36PM +0200, Marijn Suijten wrote:
quoted
When not specifying num-strings in the DT the default is used, but +1 is
added to it which turns wled3 into 4 and wled4/5 into 5 strings instead
of 3 and 4 respectively, causing out of bounds reads and register
read/writes. This +1 exists for a deficiency in the DT parsing code,
and is simply omitted entirely - solving this oob issue - by allowing
one extra iteration of the wled_var_cfg function parsing this particular
property.
Fixes: 93c64f1ea1e8 ("leds: add Qualcomm PM8941 WLED driver")
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: AngeloGioacchino Del Regno <redacted>
---
drivers/video/backlight/qcom-wled.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
These comments represent the possible loop iterations the DT "cfg
parser" runs through, starting at j=0 and running up until and including
j=3. Should I make that more clear or omit these comments entirely?
The role of wled3_num_strings_values_fn() is to enumerate the list of
legal values for the property [ 1, 2, 3 ]. Your changes cause the
enumeration to include a non-legal value so that you can have an
identity mapping between the symbol and the enumerate value.
An alternative approach would be to leave the enumeration logic
alone but set the num_string default to UINT_MAX in all cases:
- cfg->num_strings = cfg->num_strings + 1;
+ if (cfg->num_strings == UINT_MAX)
+ cfg->num_strings =
Oops... looks like I missed the cfg->max_string_count here.
quoted hunk
+ else+ /* Convert from enumerated to numeric form */+ cfg->num_strings = wled3_num_strings_values_fn(+ cfg->num_strings);
PS the alternative option is not to treat num-strings as an enumerated
value at all and just read it directly without using wled_values()...
On Tue, Oct 05, 2021 at 11:38:43AM +0100, Daniel Thompson wrote:
quoted
On Tue, Oct 05, 2021 at 12:06:06PM +0200, Marijn Suijten wrote:
quoted
On 2021-10-05 10:19:47, Daniel Thompson wrote:
quoted
On Mon, Oct 04, 2021 at 09:27:36PM +0200, Marijn Suijten wrote:
quoted
When not specifying num-strings in the DT the default is used, but +1 is
added to it which turns wled3 into 4 and wled4/5 into 5 strings instead
of 3 and 4 respectively, causing out of bounds reads and register
read/writes. This +1 exists for a deficiency in the DT parsing code,
and is simply omitted entirely - solving this oob issue - by allowing
one extra iteration of the wled_var_cfg function parsing this particular
property.
Fixes: 93c64f1ea1e8 ("leds: add Qualcomm PM8941 WLED driver")
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: AngeloGioacchino Del Regno <redacted>
---
drivers/video/backlight/qcom-wled.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
These comments represent the possible loop iterations the DT "cfg
parser" runs through, starting at j=0 and running up until and including
j=3. Should I make that more clear or omit these comments entirely?
The role of wled3_num_strings_values_fn() is to enumerate the list of
legal values for the property [ 1, 2, 3 ]. Your changes cause the
enumeration to include a non-legal value so that you can have an
identity mapping between the symbol and the enumerate value.
An alternative approach would be to leave the enumeration logic
alone but set the num_string default to UINT_MAX in all cases:
- cfg->num_strings = cfg->num_strings + 1;
+ if (cfg->num_strings == UINT_MAX)
+ cfg->num_strings =
Oops... looks like I missed the cfg->max_string_count here.
quoted
+ else+ /* Convert from enumerated to numeric form */+ cfg->num_strings = wled3_num_strings_values_fn(+ cfg->num_strings);
PS the alternative option is not to treat num-strings as an enumerated
value at all and just read it directly without using wled_values()...
I much prefer doing that instead of trying to wrangle enumeration
parsing around integer values that are supposed to be used as-is. After
all this variable is already named to set the `+ 1` override currently,
and `qcom,enabled_strings` has "custom" handling as well. I'll extend
the validation to ensure num_strings>=1 too.
In addition, and this needs some investigation on the dt-bindings side
too, it might be beneficial to make both properties mutually exclusive.
When specifying qcom,enabled_strings it makes little sense to also
provide qcom,num_strings and we want the former to take precedence. At
that point one might ask why qcom,num_strings remains at all when DT can
use qcom,enabled_strings instead.
We will supposedly have to keep backwards compatibility with DTs in mind
so none of this can be removed or made mutually exclusive from a driver
standpoint, that all has to be done in dt-bindings yaml to be enforced
on checked-in DTs.
- Marijn
From: Daniel Thompson <hidden> Date: 2021-10-05 14:07:33
On Tue, Oct 05, 2021 at 01:44:35PM +0200, Marijn Suijten wrote:
On 2021-10-05 11:53:12, Daniel Thompson wrote:
quoted
On Tue, Oct 05, 2021 at 11:38:43AM +0100, Daniel Thompson wrote:
quoted
On Tue, Oct 05, 2021 at 12:06:06PM +0200, Marijn Suijten wrote:
quoted
On 2021-10-05 10:19:47, Daniel Thompson wrote:
quoted
On Mon, Oct 04, 2021 at 09:27:36PM +0200, Marijn Suijten wrote:
quoted
When not specifying num-strings in the DT the default is used, but +1 is
added to it which turns wled3 into 4 and wled4/5 into 5 strings instead
of 3 and 4 respectively, causing out of bounds reads and register
read/writes. This +1 exists for a deficiency in the DT parsing code,
and is simply omitted entirely - solving this oob issue - by allowing
one extra iteration of the wled_var_cfg function parsing this particular
property.
Fixes: 93c64f1ea1e8 ("leds: add Qualcomm PM8941 WLED driver")
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
Reviewed-by: AngeloGioacchino Del Regno <redacted>
---
drivers/video/backlight/qcom-wled.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
These comments represent the possible loop iterations the DT "cfg
parser" runs through, starting at j=0 and running up until and including
j=3. Should I make that more clear or omit these comments entirely?
The role of wled3_num_strings_values_fn() is to enumerate the list of
legal values for the property [ 1, 2, 3 ]. Your changes cause the
enumeration to include a non-legal value so that you can have an
identity mapping between the symbol and the enumerate value.
An alternative approach would be to leave the enumeration logic
alone but set the num_string default to UINT_MAX in all cases:
- cfg->num_strings = cfg->num_strings + 1;
+ if (cfg->num_strings == UINT_MAX)
+ cfg->num_strings =
Oops... looks like I missed the cfg->max_string_count here.
quoted
+ else+ /* Convert from enumerated to numeric form */+ cfg->num_strings = wled3_num_strings_values_fn(+ cfg->num_strings);
PS the alternative option is not to treat num-strings as an enumerated
value at all and just read it directly without using wled_values()...
I much prefer doing that instead of trying to wrangle enumeration
parsing around integer values that are supposed to be used as-is. After
all this variable is already named to set the `+ 1` override currently,
and `qcom,enabled_strings` has "custom" handling as well. I'll extend
the validation to ensure num_strings>=1 too.
Great.
In addition, and this needs some investigation on the dt-bindings side
too, it might be beneficial to make both properties mutually exclusive.
When specifying qcom,enabled_strings it makes little sense to also
provide qcom,num_strings and we want the former to take precedence.
If we are designing a "fix" for that then my view is that if both are
passed then num-strings should take precedence because it is an
explicit statement about the number of strings where enabled_strings
is implicit. In other words, if num-strings <= len(enabled_strings) then
we should do what we are told, otherwise report error.
At that point one might ask why qcom,num_strings remains at all when
DT can use qcom,enabled_strings instead. We will supposedly have to
keep backwards compatibility with DTs in mind so none of this can be
removed or made mutually exclusive from a driver standpoint, that all
has to be done in dt-bindings yaml to be enforced on checked-in DTs.
So... perhaps I made a make offering a Reviewed-by: to a patch
that allows len(enabled-strings) to have precedence. If anything
currently uses enabled-strings then it *will* be 4 cells long and
is relying on num-strings to ensure the right things happens ;-) .
We'd like that case to keep working so we must allow num-strings to have
precedence. In other words, when you add the new code, please put it at
the end of the function!
Daniel.
On 2021-10-05 15:03:49, Daniel Thompson wrote:
[..]
quoted
I much prefer doing that instead of trying to wrangle enumeration
parsing around integer values that are supposed to be used as-is. After
all this variable is already named to set the `+ 1` override currently,
and `qcom,enabled_strings` has "custom" handling as well. I'll extend
the validation to ensure num_strings>=1 too.
Great.
quoted
In addition, and this needs some investigation on the dt-bindings side
too, it might be beneficial to make both properties mutually exclusive.
When specifying qcom,enabled_strings it makes little sense to also
provide qcom,num_strings and we want the former to take precedence.
If we are designing a "fix" for that then my view is that if both are
passed then num-strings should take precedence because it is an
explicit statement about the number of strings where enabled_strings
is implicit. In other words, if num-strings <= len(enabled_strings) then
we should do what we are told, otherwise report error.
IMO both should be identical (num-strings == len(enabled-strings)) to
avoid ambiguity, but do read on.
quoted
At that point one might ask why qcom,num_strings remains at all when
DT can use qcom,enabled_strings instead. We will supposedly have to
keep backwards compatibility with DTs in mind so none of this can be
removed or made mutually exclusive from a driver standpoint, that all
has to be done in dt-bindings yaml to be enforced on checked-in DTs.
So... perhaps I made a make offering a Reviewed-by: to a patch
that allows len(enabled-strings) to have precedence. If anything
currently uses enabled-strings then it *will* be 4 cells long and
is relying on num-strings to ensure the right things happens ;-) .
Unfortunately Konrad (one of my team members) landed such a patch at the
beginning of this year because I failed to submit this patchset in time
while it has been sitting in my queue since 2019 after being used in a
downstream project. This is in pmi8994 which doesn't have anything
widely used / production ready yet, so I'd prefer to fix the DT instead
and remove / fix his comment:
/* Yes, all four strings *have to* be defined or things won't work. */
But this is mostly because, prior to this patchset, no default was set
for WLED4 so the 0'th string would get enabled num-strings (3 in
pmi8994's case) times.
Aside that there's only one more PMIC (also being worked on by
SoMainline) that sets qcom,enabled-strings: this is pm660l, pulled from
our local tree, and it actually has enabled-strings of length 2 which is
broken in its current form, exactly because of relying on this patchset.
Finally, we already discussed this inside SoMainline and the
number/enabled leds should most likely be moved out of the PMIC dtsi's
as they're probably panel, hence board or even device dependent.
We'd like that case to keep working so we must allow num-strings to have
precedence. In other words, when you add the new code, please put it at
the end of the function!
Since there don't seem to be any substantial platforms/PMICs using this
functionality in a working manner, can I talk you into agreeing with
fixing the DT instead?
PS. In -next pmi8994_wled is only enabled for sony-xperia-tone, and
pm660l_wled has yet to be enabled by anything.
- Marijn
From: Daniel Thompson <hidden> Date: 2021-10-05 16:25:00
On Tue, Oct 05, 2021 at 05:23:26PM +0200, Marijn Suijten wrote:
On 2021-10-05 15:03:49, Daniel Thompson wrote:
[..]
quoted
quoted
At that point one might ask why qcom,num_strings remains at all when
DT can use qcom,enabled_strings instead. We will supposedly have to
keep backwards compatibility with DTs in mind so none of this can be
removed or made mutually exclusive from a driver standpoint, that all
has to be done in dt-bindings yaml to be enforced on checked-in DTs.
So... perhaps I made a make offering a Reviewed-by: to a patch
that allows len(enabled-strings) to have precedence. If anything
currently uses enabled-strings then it *will* be 4 cells long and
is relying on num-strings to ensure the right things happens ;-) .
Unfortunately Konrad (one of my team members) landed such a patch at the
beginning of this year because I failed to submit this patchset in time
while it has been sitting in my queue since 2019 after being used in a
downstream project. This is in pmi8994 which doesn't have anything
widely used / production ready yet, so I'd prefer to fix the DT instead
and remove / fix his comment:
/* Yes, all four strings *have to* be defined or things won't work. */
But this is mostly because, prior to this patchset, no default was set
for WLED4 so the 0'th string would get enabled num-strings (3 in
pmi8994's case) times.
Aside that there's only one more PMIC (also being worked on by
SoMainline) that sets qcom,enabled-strings: this is pm660l, pulled from
our local tree, and it actually has enabled-strings of length 2 which is
broken in its current form, exactly because of relying on this patchset.
Finally, we already discussed this inside SoMainline and the
number/enabled leds should most likely be moved out of the PMIC dtsi's
as they're probably panel, hence board or even device dependent.
quoted
We'd like that case to keep working so we must allow num-strings to have
precedence. In other words, when you add the new code, please put it at
the end of the function!
Since there don't seem to be any substantial platforms/PMICs using this
functionality in a working manner, can I talk you into agreeing with
fixing the DT instead?
I've no objections to seeing the DT updated. However I don't really see
what benefit we get from breaking existing DTs in order to do so.
"Cleaning up annoying legacy" is seldom a good reason to break existing
DTs since, if we could break DTs whenever we choose, there would never
be any annoying legacy to worry about. When conflicting properties
result in uninterpretable DTs then a break may be justified but that is
not the case here.
Daniel.
From: Konrad Dybcio <hidden> Date: 2021-10-05 16:50:58
[snipping to not have the entire thread here]
I've no objections to seeing the DT updated. However I don't really see
what benefit we get from breaking existing DTs in order to do so.
"Cleaning up annoying legacy" is seldom a good reason to break existing
DTs since, if we could break DTs whenever we choose, there would never
be any annoying legacy to worry about. When conflicting properties
result in uninterpretable DTs then a break may be justified but that is
not the case here.
Daniel.
The only true user of wled as of right now is Xperia Tone platform, which does not yet
have display support upstream, so unless one classifies lighting up an otherwise black display
a dealbreaker, I think it'd be fine to bend the rules this time.
Konrad
On Tue, Oct 05, 2021 at 05:23:26PM +0200, Marijn Suijten wrote:
quoted
On 2021-10-05 15:03:49, Daniel Thompson wrote:
[..]
quoted
quoted
At that point one might ask why qcom,num_strings remains at all when
DT can use qcom,enabled_strings instead. We will supposedly have to
keep backwards compatibility with DTs in mind so none of this can be
removed or made mutually exclusive from a driver standpoint, that all
has to be done in dt-bindings yaml to be enforced on checked-in DTs.
So... perhaps I made a make offering a Reviewed-by: to a patch
that allows len(enabled-strings) to have precedence. If anything
currently uses enabled-strings then it *will* be 4 cells long and
is relying on num-strings to ensure the right things happens ;-) .
Unfortunately Konrad (one of my team members) landed such a patch at the
beginning of this year because I failed to submit this patchset in time
while it has been sitting in my queue since 2019 after being used in a
downstream project. This is in pmi8994 which doesn't have anything
widely used / production ready yet, so I'd prefer to fix the DT instead
and remove / fix his comment:
/* Yes, all four strings *have to* be defined or things won't work. */
But this is mostly because, prior to this patchset, no default was set
for WLED4 so the 0'th string would get enabled num-strings (3 in
pmi8994's case) times.
Aside that there's only one more PMIC (also being worked on by
SoMainline) that sets qcom,enabled-strings: this is pm660l, pulled from
our local tree, and it actually has enabled-strings of length 2 which is
broken in its current form, exactly because of relying on this patchset.
Finally, we already discussed this inside SoMainline and the
number/enabled leds should most likely be moved out of the PMIC dtsi's
as they're probably panel, hence board or even device dependent.
quoted
We'd like that case to keep working so we must allow num-strings to have
precedence. In other words, when you add the new code, please put it at
the end of the function!
Since there don't seem to be any substantial platforms/PMICs using this
functionality in a working manner, can I talk you into agreeing with
fixing the DT instead?
I've no objections to seeing the DT updated. However I don't really see
what benefit we get from breaking existing DTs in order to do so.
"Cleaning up annoying legacy" is seldom a good reason to break existing
DTs since, if we could break DTs whenever we choose, there would never
be any annoying legacy to worry about. When conflicting properties
result in uninterpretable DTs then a break may be justified but that is
not the case here.
As mentioned in my message and repeated by Konrad, the only "existing
DT" that could possibly be broken is a platform that's brought up by us
(SoMainline) and we're more than happy to improve the driver and leave
legacy DT behind us, unless there's more DT in circulation that hasn't
landed in Linux mainline but should be taken into account?
Anyway the plan is to leave qcom,num-strings in place so that the
default enabled_strings list in this driver actually serves a purpose.
Then, if num-strings and enabled-strings is provided the former has
precedence (assuming it doesn't exceed the size of the latter) but we'll
print a warning about this (now unnecessary) ambiguity, and if possible
at all - haven't found an example yet - make the properties mutually
exclusive in dt-bindings.
Disallowing both cases would only simplify the code in the end but we
can spend a few lines to support the desired legacy.
- Marijn
From: Daniel Thompson <hidden> Date: 2021-10-06 14:44:53
On Tue, Oct 05, 2021 at 07:34:00PM +0200, Marijn Suijten wrote:
On 2021-10-05 17:24:53, Daniel Thompson wrote:
quoted
On Tue, Oct 05, 2021 at 05:23:26PM +0200, Marijn Suijten wrote:
quoted
Since there don't seem to be any substantial platforms/PMICs using this
functionality in a working manner, can I talk you into agreeing with
fixing the DT instead?
I've no objections to seeing the DT updated. However I don't really see
what benefit we get from breaking existing DTs in order to do so.
"Cleaning up annoying legacy" is seldom a good reason to break existing
DTs since, if we could break DTs whenever we choose, there would never
be any annoying legacy to worry about. When conflicting properties
result in uninterpretable DTs then a break may be justified but that is
not the case here.
As mentioned in my message and repeated by Konrad, the only "existing
DT" that could possibly be broken is a platform that's brought up by us
(SoMainline) and we're more than happy to improve the driver and leave
legacy DT behind us, unless there's more DT in circulation that hasn't
landed in Linux mainline but should be taken into account?
Devicetrees are supposed to be the domain of firmware (e.g. not part of
the kernel).
I'm therefore reluctant to adopt an "it only exists if it is upstream"
approach for documented DT bindings. Doubly so when it is our bugs that
causes DTs to be written in a manner which we then retrospectively
declare to be wrong.
Anyway the plan is to leave qcom,num-strings in place so that the
default enabled_strings list in this driver actually serves a purpose.
Then, if num-strings and enabled-strings is provided the former has
precedence (assuming it doesn't exceed the size of the latter) but
we'll print a warning about this (now unnecessary) ambiguity, and if
possible at all - haven't found an example yet - make the properties
mutually exclusive in dt-bindings.
Disallowing both cases would only simplify the code in the end but we
can spend a few lines to support the desired legacy.
On Tue, Oct 05, 2021 at 07:34:00PM +0200, Marijn Suijten wrote:
quoted
On 2021-10-05 17:24:53, Daniel Thompson wrote:
quoted
On Tue, Oct 05, 2021 at 05:23:26PM +0200, Marijn Suijten wrote:
quoted
Since there don't seem to be any substantial platforms/PMICs using this
functionality in a working manner, can I talk you into agreeing with
fixing the DT instead?
I've no objections to seeing the DT updated. However I don't really see
what benefit we get from breaking existing DTs in order to do so.
"Cleaning up annoying legacy" is seldom a good reason to break existing
DTs since, if we could break DTs whenever we choose, there would never
be any annoying legacy to worry about. When conflicting properties
result in uninterpretable DTs then a break may be justified but that is
not the case here.
As mentioned in my message and repeated by Konrad, the only "existing
DT" that could possibly be broken is a platform that's brought up by us
(SoMainline) and we're more than happy to improve the driver and leave
legacy DT behind us, unless there's more DT in circulation that hasn't
landed in Linux mainline but should be taken into account?
Devicetrees are supposed to be the domain of firmware (e.g. not part of
the kernel).
I'm therefore reluctant to adopt an "it only exists if it is upstream"
approach for documented DT bindings. Doubly so when it is our bugs that
causes DTs to be written in a manner which we then retrospectively
declare to be wrong.
I'm aware that DT is considered firmware and is ""intended"" to be
shipped separately (and probably only once out of the factory) but it
seems so far there's an advantage in updating DT in parallel with the
kernel. However this is the first time hearing that having dt-bindings
documentation available contributes to considering the DT contract
(more) stable. Either way I'd expect these bindings to have been fixed
much sooner if it was really actively used.
quoted
Anyway the plan is to leave qcom,num-strings in place so that the
default enabled_strings list in this driver actually serves a purpose.
Then, if num-strings and enabled-strings is provided the former has
precedence (assuming it doesn't exceed the size of the latter) but
we'll print a warning about this (now unnecessary) ambiguity, and if
possible at all - haven't found an example yet - make the properties
mutually exclusive in dt-bindings.
Disallowing both cases would only simplify the code in the end but we
can spend a few lines to support the desired legacy.