2023-10-17 23:33:20

by Haonan Li

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

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 <[email protected]>
---
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


2023-10-17 23:37:02

by Damien Le Moal

[permalink] [raw]
Subject: Re: [PATCH] pata_lagacy: Handle failed ATA timing computation in opti82c46x_set_piomode

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 <[email protected]>
> ---
> 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

2023-10-18 00:51:15

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH] pata_lagacy: Handle failed ATA timing computation in opti82c46x_set_piomode

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/[email protected]/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 <[email protected]>
| Closes: https://lore.kernel.org/oe-kbuild-all/[email protected]/

# 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

2023-10-18 00:56:10

by Haonan Li

[permalink] [raw]
Subject: Re: [PATCH] pata_lagacy: Handle failed ATA timing computation in opti82c46x_set_piomode

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 <[email protected]>
---
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

2023-10-18 06:21:44

by Damien Le Moal

[permalink] [raw]
Subject: Re: [PATCH] pata_lagacy: Handle failed ATA timing computation in opti82c46x_set_piomode

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 <[email protected]>

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

2023-10-18 17:16:03

by Sergey Shtylyov

[permalink] [raw]
Subject: Re: [PATCH] pata_lagacy: Handle failed ATA timing computation in opti82c46x_set_piomode

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 <[email protected]>
[...]

Reviewed-by: Sergey Shtylyov <[email protected]>

MBR, Sergey

2023-10-18 18:01:48

by Haonan Li

[permalink] [raw]
Subject: Re: [PATCH] pata_lagacy: Handle failed ATA timing computation in opti82c46x_set_piomode

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 <[email protected]> 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 <[email protected]>
> [...]
>
> Reviewed-by: Sergey Shtylyov <[email protected]>
>
> MBR, Sergey