lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <b6c75eee-761d-44c8-8413-2a5b34ee2f98@linux.intel.com>
Date: Tue, 3 Sep 2024 15:34:39 +0800
From: "Liao, Bard" <yung-chuan.liao@...ux.intel.com>
To: Vinod Koul <vkoul@...nel.org>,
 Pierre-Louis Bossart <pierre-louis.bossart@...ux.intel.com>
Cc: Krzysztof Kozlowski <krzysztof.kozlowski@...aro.org>,
 Sanyog Kale <sanyog.r.kale@...el.com>, Shreyas NC <shreyas.nc@...el.com>,
 alsa-devel@...a-project.org, linux-kernel@...r.kernel.org,
 stable@...r.kernel.org, bard.liao@...el.com
Subject: Re: [PATCH] soundwire: stream: fix programming slave ports for
 non-continous port maps


On 7/31/2024 2:56 PM, Vinod Koul wrote:
> On 29-07-24, 16:25, Pierre-Louis Bossart wrote:
>>
>> On 7/29/24 16:01, Krzysztof Kozlowski wrote:
>>> Two bitmasks in 'struct sdw_slave_prop' - 'source_ports' and
>>> 'sink_ports' - define which ports to program in
>>> sdw_program_slave_port_params().  The masks are used to get the
>>> appropriate data port properties ('struct sdw_get_slave_dpn_prop') from
>>> an array.
>>>
>>> Bitmasks can be non-continuous or can start from index different than 0,
>>> thus when looking for matching port property for given port, we must
>>> iterate over mask bits, not from 0 up to number of ports.
>>>
>>> This fixes allocation and programming slave ports, when a source or sink
>>> masks start from further index.
>>>
>>> Fixes: f8101c74aa54 ("soundwire: Add Master and Slave port programming")
>>> Cc: <stable@...r.kernel.org>
>>> Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@...aro.org>
>> This is a valid change to optimize how the port are accessed.
>>
>> But the commit message is not completely clear, the allocation in
>> mipi_disco.c is not modified and I don't think there's anything that
>> would crash. If there are non-contiguous ports, we will still allocate
>> space that will not be initialized/used.
>>
>> 	/* Allocate memory for set bits in port lists */
>> 	nval = hweight32(prop->source_ports);
>> 	prop->src_dpn_prop = devm_kcalloc(&slave->dev, nval,
>> 					  sizeof(*prop->src_dpn_prop),
>> 					  GFP_KERNEL);
>> 	if (!prop->src_dpn_prop)
>> 		return -ENOMEM;
>>
>> 	/* Read dpn properties for source port(s) */
>> 	sdw_slave_read_dpn(slave, prop->src_dpn_prop, nval,
>> 			   prop->source_ports, "source");
>>
>> IOW, this is a valid change, but it's an optimization, not a fix in the
>> usual sense of 'kernel oops otherwise'.
>>
>> Am I missing something?
>>
>> BTW, the notion of DPn is that n > 0. DP0 is a special case with
>> different properties, BIT(0) cannot be set for either of the sink/source
>> port bitmask.
> The fix seems right to me, we cannot have assumption that ports are
> contagious, so we need to iterate over all valid ports and not to N
> ports which code does now!


Sorry to jump in after the commit was applied. But, it breaks my test.

The point is that dpn_prop[i].num where the i is the array index, and

num is the port number. So, `for (i = 0; i < num_ports; i++)` will iterate

over all valid ports.

We can see in below drivers/soundwire/mipi_disco.c

         nval = hweight32(prop->sink_ports);

         prop->sink_dpn_prop = devm_kcalloc(&slave->dev, nval,

sizeof(*prop->sink_dpn_prop),

                                            GFP_KERNEL);

And sdw_slave_read_dpn() set data port properties one by one.

`for_each_set_bit(i, &mask, 32)` will break the system when port numbers

are not continuous. For example, a codec has source port number = 1 and 3,

then dpn_prop[0].num = 1 and dpn_prop[1].num = 3. And we need to go

throuth dpn_prop[0] and dpn_prop[1] instead of dpn_prop[1] and dpn_prop[3].


>
>>
>>> ---
>>>   drivers/soundwire/stream.c | 8 ++++----
>>>   1 file changed, 4 insertions(+), 4 deletions(-)
>>>
>>> diff --git a/drivers/soundwire/stream.c b/drivers/soundwire/stream.c
>>> index 7aa4900dcf31..f275143d7b18 100644
>>> --- a/drivers/soundwire/stream.c
>>> +++ b/drivers/soundwire/stream.c
>>> @@ -1291,18 +1291,18 @@ struct sdw_dpn_prop *sdw_get_slave_dpn_prop(struct sdw_slave *slave,
>>>   					    unsigned int port_num)
>>>   {
>>>   	struct sdw_dpn_prop *dpn_prop;
>>> -	u8 num_ports;
>>> +	unsigned long mask;
>>>   	int i;
>>>   
>>>   	if (direction == SDW_DATA_DIR_TX) {
>>> -		num_ports = hweight32(slave->prop.source_ports);
>>> +		mask = slave->prop.source_ports;
>>>   		dpn_prop = slave->prop.src_dpn_prop;
>>>   	} else {
>>> -		num_ports = hweight32(slave->prop.sink_ports);
>>> +		mask = slave->prop.sink_ports;
>>>   		dpn_prop = slave->prop.sink_dpn_prop;
>>>   	}
>>>   
>>> -	for (i = 0; i < num_ports; i++) {
>>> +	for_each_set_bit(i, &mask, 32) {
>>>   		if (dpn_prop[i].num == port_num)
>>>   			return &dpn_prop[i];
>>>   	}

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ