[PATCH] pata_lagacy: Handle failed ATA timing computation in opti82c46x_set_piomode

Haonan Li posted 1 patch 2 years, 2 months ago
drivers/ata/pata_legacy.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
[PATCH] pata_lagacy: Handle failed ATA timing computation in opti82c46x_set_piomode
Posted by Haonan Li 2 years, 2 months ago
The function opti82c46x_set_piomode utilizes the ata_timing_compute()
to determine the appropriate ATA timings for a given device. However,
in certain conditions where the ata_timing_find_mode() function does
not find a valid mode, ata_timing_compute() returns an error (-EINVAL),
leaving the tp struct uninitialized.

This patch checks the return value of ata_timing_compute().
This avoids any potential use of uninitialized `tp` struct in the
opti82c46x_set_piomode function.

Signed-off-by: Haonan Li <lihaonan1105@gmail.com>
---
 drivers/ata/pata_legacy.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
index 448a511cb..d94c365cb 100644
--- a/drivers/ata/pata_legacy.c
+++ b/drivers/ata/pata_legacy.c
@@ -579,12 +579,16 @@ static void opti82c46x_set_piomode(struct ata_port *ap, struct ata_device *adev)
 	clock = 1000000000 / khz[sysclk];
 
 	/* Get the timing data in cycles */
-	ata_timing_compute(adev, adev->pio_mode, &t, clock, 1000);
+	if (ata_timing_compute(adev, adev->pio_mode, &t, clock, 1000)) {
+		return;
+	}
 
 	/* Setup timing is shared */
 	if (pair) {
 		struct ata_timing tp;
-		ata_timing_compute(pair, pair->pio_mode, &tp, clock, 1000);
+		if (ata_timing_compute(pair, pair->pio_mode, &tp, clock, 1000)) {
+			return;
+		}
 
 		ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP);
 	}
-- 
2.34.1
Re: [PATCH] pata_lagacy: Handle failed ATA timing computation in opti82c46x_set_piomode
Posted by kernel test robot 2 years, 2 months ago
Hi Haonan,

kernel test robot noticed the following build warnings:

[auto build test WARNING on linus/master]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Haonan-Li/pata_lagacy-Handle-failed-ATA-timing-computation-in-opti82c46x_set_piomode/20231018-073451
base:   linus/master
patch link:    https://lore.kernel.org/r/20231017233234.2170437-1-lihaonan1105%40gmail.com
patch subject: [PATCH] pata_lagacy: Handle failed ATA timing computation in opti82c46x_set_piomode
reproduce: (https://download.01.org/0day-ci/archive/20231018/202310180858.o7Wjw0A2-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202310180858.o7Wjw0A2-lkp@intel.com/

# many are suggestions rather than must-fix

WARNING:BRACES: braces {} are not necessary for single statement blocks
#31: FILE: drivers/ata/pata_legacy.c:582:
+	if (ata_timing_compute(adev, adev->pio_mode, &t, clock, 1000)) {
+		return;
+	}

WARNING:BRACES: braces {} are not necessary for single statement blocks
#39: FILE: drivers/ata/pata_legacy.c:589:
+		if (ata_timing_compute(pair, pair->pio_mode, &tp, clock, 1000)) {
+			return;
+		}

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH] pata_lagacy: Handle failed ATA timing computation in opti82c46x_set_piomode
Posted by Damien Le Moal 2 years, 2 months ago
On 10/18/23 08:32, Haonan Li wrote:
> The function opti82c46x_set_piomode utilizes the ata_timing_compute()
> to determine the appropriate ATA timings for a given device. However,
> in certain conditions where the ata_timing_find_mode() function does
> not find a valid mode, ata_timing_compute() returns an error (-EINVAL),
> leaving the tp struct uninitialized.
> 
> This patch checks the return value of ata_timing_compute().
> This avoids any potential use of uninitialized `tp` struct in the
> opti82c46x_set_piomode function.
> 
> Signed-off-by: Haonan Li <lihaonan1105@gmail.com>
> ---
>  drivers/ata/pata_legacy.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
> index 448a511cb..d94c365cb 100644
> --- a/drivers/ata/pata_legacy.c
> +++ b/drivers/ata/pata_legacy.c
> @@ -579,12 +579,16 @@ static void opti82c46x_set_piomode(struct ata_port *ap, struct ata_device *adev)
>  	clock = 1000000000 / khz[sysclk];
>  
>  	/* Get the timing data in cycles */
> -	ata_timing_compute(adev, adev->pio_mode, &t, clock, 1000);
> +	if (ata_timing_compute(adev, adev->pio_mode, &t, clock, 1000)) {
> +		return;
> +	}

You need a message here to tell the user something is wrong. See pata_amd.c for
an example.

>  
>  	/* Setup timing is shared */
>  	if (pair) {
>  		struct ata_timing tp;
> -		ata_timing_compute(pair, pair->pio_mode, &tp, clock, 1000);
> +		if (ata_timing_compute(pair, pair->pio_mode, &tp, clock, 1000)) {
> +			return;
> +		}

Same here. And while at it, please add a blank line after the declaration and
before your change.

>  
>  		ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP);
>  	}

-- 
Damien Le Moal
Western Digital Research
Re: [PATCH] pata_lagacy: Handle failed ATA timing computation in opti82c46x_set_piomode
Posted by Haonan Li 2 years, 2 months ago
The function opti82c46x_set_piomode utilizes the ata_timing_compute()
to determine the appropriate ATA timings for a given device. However,
in certain conditions where the ata_timing_find_mode() function does
not find a valid mode, ata_timing_compute() returns an error (-EINVAL),
leaving the tp struct uninitialized.

This patch checks the return value of ata_timing_compute() and print
err message. This avoids any potential use of uninitialized `tp`
struct in the opti82c46x_set_piomode function.

Signed-off-by: Haonan Li <lihaonan1105@gmail.com>
---
 drivers/ata/pata_legacy.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
index 448a511cbc17..3c7163f97aaf 100644
--- a/drivers/ata/pata_legacy.c
+++ b/drivers/ata/pata_legacy.c
@@ -579,12 +579,19 @@ static void opti82c46x_set_piomode(struct ata_port *ap, struct ata_device *adev)
 	clock = 1000000000 / khz[sysclk];
 
 	/* Get the timing data in cycles */
-	ata_timing_compute(adev, adev->pio_mode, &t, clock, 1000);
+	if (ata_timing_compute(adev, adev->pio_mode, &t, clock, 1000)) {
+		dev_err(ap->dev, "adev: unknown mode %d\n", adev->pio_mode);
+		return;
+	}
 
 	/* Setup timing is shared */
 	if (pair) {
 		struct ata_timing tp;
-		ata_timing_compute(pair, pair->pio_mode, &tp, clock, 1000);
+
+		if (ata_timing_compute(pair, pair->pio_mode, &tp, clock, 1000)) {
+			dev_err(ap->dev, "pair: unknown mode %d\n", pair->pio_mode);
+			return;
+		}
 
 		ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP);
 	}
-- 
2.34.1
Re: [PATCH] pata_lagacy: Handle failed ATA timing computation in opti82c46x_set_piomode
Posted by Sergey Shtylyov 2 years, 2 months ago
Hello!

On 10/18/23 3:52 AM, Haonan Li wrote:

> The function opti82c46x_set_piomode utilizes the ata_timing_compute()
> to determine the appropriate ATA timings for a given device. However,
> in certain conditions where the ata_timing_find_mode() function does
> not find a valid mode, ata_timing_compute() returns an error (-EINVAL),
> leaving the tp struct uninitialized.

   Looks like it's very common to ignore the result of ata_timing_compute()
in drivers/ata/...
   Mind sharing the "certain conditions"? :-) I don't think the set_piomode()
method can be called by libata itself with an unsupported xfer mode...

> This patch checks the return value of ata_timing_compute() and print
> err message. This avoids any potential use of uninitialized `tp`
> struct in the opti82c46x_set_piomode function.
> 
> Signed-off-by: Haonan Li <lihaonan1105@gmail.com>
[...]

Reviewed-by: Sergey Shtylyov <s.shtylyov@omp.ru>

MBR, Sergey
Re: [PATCH] pata_lagacy: Handle failed ATA timing computation in opti82c46x_set_piomode
Posted by Haonan Li 2 years, 2 months ago
Hello Sergey,

Thank you for pointing that out. My main concern was the potential
for ata_timing_find_mode() to return NULL, causing ata_timing_compute()
to return -EINVAL. While this might be rare, I thought it would be
safer to handle such cases.

However, if the common practice in drivers/ata/ is to ignore the result
of ata_timing_compute(), let's drop the patch as needed.

Thank you for your time and feedback.

Best,
Haonan

On Wed, Oct 18, 2023 at 10:15 AM Sergey Shtylyov <s.shtylyov@omp.ru> wrote:
>
> Hello!
>
> On 10/18/23 3:52 AM, Haonan Li wrote:
>
> > The function opti82c46x_set_piomode utilizes the ata_timing_compute()
> > to determine the appropriate ATA timings for a given device. However,
> > in certain conditions where the ata_timing_find_mode() function does
> > not find a valid mode, ata_timing_compute() returns an error (-EINVAL),
> > leaving the tp struct uninitialized.
>
>    Looks like it's very common to ignore the result of ata_timing_compute()
> in drivers/ata/...
>    Mind sharing the "certain conditions"? :-) I don't think the set_piomode()
> method can be called by libata itself with an unsupported xfer mode...
>
> > This patch checks the return value of ata_timing_compute() and print
> > err message. This avoids any potential use of uninitialized `tp`
> > struct in the opti82c46x_set_piomode function.
> >
> > Signed-off-by: Haonan Li <lihaonan1105@gmail.com>
> [...]
>
> Reviewed-by: Sergey Shtylyov <s.shtylyov@omp.ru>
>
> MBR, Sergey
Re: [PATCH] pata_lagacy: Handle failed ATA timing computation in opti82c46x_set_piomode
Posted by Damien Le Moal 2 years, 2 months ago
On 10/18/23 09:52, Haonan Li wrote:
> The function opti82c46x_set_piomode utilizes the ata_timing_compute()
> to determine the appropriate ATA timings for a given device. However,
> in certain conditions where the ata_timing_find_mode() function does
> not find a valid mode, ata_timing_compute() returns an error (-EINVAL),
> leaving the tp struct uninitialized.
> 
> This patch checks the return value of ata_timing_compute() and print
> err message. This avoids any potential use of uninitialized `tp`
> struct in the opti82c46x_set_piomode function.
> 
> Signed-off-by: Haonan Li <lihaonan1105@gmail.com>

Please do not send patches in reply to something else. Also, this is a v2 of a
previous patch so the patch title prefix should indicate that and a change log
should be present after the "---" below.

> ---
>  drivers/ata/pata_legacy.c | 11 +++++++++--
>  1 file changed, 9 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
> index 448a511cbc17..3c7163f97aaf 100644
> --- a/drivers/ata/pata_legacy.c
> +++ b/drivers/ata/pata_legacy.c
> @@ -579,12 +579,19 @@ static void opti82c46x_set_piomode(struct ata_port *ap, struct ata_device *adev)
>  	clock = 1000000000 / khz[sysclk];
>  
>  	/* Get the timing data in cycles */
> -	ata_timing_compute(adev, adev->pio_mode, &t, clock, 1000);
> +	if (ata_timing_compute(adev, adev->pio_mode, &t, clock, 1000)) {
> +		dev_err(ap->dev, "adev: unknown mode %d\n", adev->pio_mode);
> +		return;
> +	}
>  
>  	/* Setup timing is shared */
>  	if (pair) {
>  		struct ata_timing tp;
> -		ata_timing_compute(pair, pair->pio_mode, &tp, clock, 1000);
> +
> +		if (ata_timing_compute(pair, pair->pio_mode, &tp, clock, 1000)) {
> +			dev_err(ap->dev, "pair: unknown mode %d\n", pair->pio_mode);
> +			return;
> +		}
>  
>  		ata_timing_merge(&t, &tp, &t, ATA_TIMING_SETUP);
>  	}

-- 
Damien Le Moal
Western Digital Research