Message ID | 20200904161705.43950-1-colin.king@canonical.com |
---|---|
State | Accepted |
Headers | show |
Series | s3: fix segmentation fault when PM_S2IDLE_SLP_S0 is not available (LP: #1894229) | expand |
On 2020-09-04 10:17 a.m., Colin King wrote: > From: Colin Ian King <colin.king@canonical.com> > > Currently if PM_S2IDLE_SLP_S0 is not available then atoi() is called > on a NULL pointer causing a segmentation fault. If it is available > there string returned is leaked. Fix these two bugs by adding a helper > function to read the PM_S2IDLE_SLP_S0 file and return 0 if it is not > possible or the residency value if it is available. > > Fixes: 69c18bab0cc0 ("s3: check slp_s0_residency_usec for s2idle") > Signed-off-by: Colin Ian King <colin.king@canonical.com> > --- > src/acpi/s3/s3.c | 23 +++++++++++++++++++++-- > 1 file changed, 21 insertions(+), 2 deletions(-) > > diff --git a/src/acpi/s3/s3.c b/src/acpi/s3/s3.c > index fc6186a4..997ac83f 100644 > --- a/src/acpi/s3/s3.c > +++ b/src/acpi/s3/s3.c > @@ -206,6 +206,25 @@ static int wrap_pmutils_do_suspend(fwts_pm_method_vars *fwts_settings, > return status; > } > > +/* > + * get_s2_idle_residency() > + * read PM_S2IDLE_SLP_S0, return 0 if it is not available > + */ > +static uint32_t get_s2_idle_residency(void) > +{ > + char *str; > + uint32_t val; > + > + str = fwts_get(PM_S2IDLE_SLP_S0); > + if (!str) > + return 0; > + > + val = atoi(str); > + free(str); > + > + return val; > +} > + > static int s3_do_suspend_resume(fwts_framework *fw, > int *hw_errors, > int *pm_errors, > @@ -336,7 +355,7 @@ static int s3_do_suspend_resume(fwts_framework *fw, > } > > if (!strncmp(sleep_type, "s2idle", strlen("s2idle"))) { > - uint32_t residency = atoi(fwts_get(PM_S2IDLE_SLP_S0)); > + uint32_t residency = get_s2_idle_residency(); > bool intel; > if (fwts_cpu_is_Intel(&intel) == FWTS_OK && intel && residency <= *s2idle_residency) { > (*s2idle_errors)++; > @@ -545,7 +564,7 @@ static int s3_test_multiple(fwts_framework *fw) > int resume_too_long = 0; > int awake_delay = s3_min_delay * 1000; > int delta = (int)(s3_delay_delta * 1000.0); > - uint32_t s2idle_residency = atoi(fwts_get(PM_S2IDLE_SLP_S0)); > + uint32_t s2idle_residency = get_s2_idle_residency(); > int pm_debug; > > #if FWTS_ENABLE_LOGIND > Thanks for fixing this. Acked-by: Alex Hung <alex.hung@canonical.com>
On 9/5/20 12:17 AM, Colin King wrote: > From: Colin Ian King <colin.king@canonical.com> > > Currently if PM_S2IDLE_SLP_S0 is not available then atoi() is called > on a NULL pointer causing a segmentation fault. If it is available > there string returned is leaked. Fix these two bugs by adding a helper > function to read the PM_S2IDLE_SLP_S0 file and return 0 if it is not > possible or the residency value if it is available. > > Fixes: 69c18bab0cc0 ("s3: check slp_s0_residency_usec for s2idle") > Signed-off-by: Colin Ian King <colin.king@canonical.com> > --- > src/acpi/s3/s3.c | 23 +++++++++++++++++++++-- > 1 file changed, 21 insertions(+), 2 deletions(-) > > diff --git a/src/acpi/s3/s3.c b/src/acpi/s3/s3.c > index fc6186a4..997ac83f 100644 > --- a/src/acpi/s3/s3.c > +++ b/src/acpi/s3/s3.c > @@ -206,6 +206,25 @@ static int wrap_pmutils_do_suspend(fwts_pm_method_vars *fwts_settings, > return status; > } > > +/* > + * get_s2_idle_residency() > + * read PM_S2IDLE_SLP_S0, return 0 if it is not available > + */ > +static uint32_t get_s2_idle_residency(void) > +{ > + char *str; > + uint32_t val; > + > + str = fwts_get(PM_S2IDLE_SLP_S0); > + if (!str) > + return 0; > + > + val = atoi(str); > + free(str); > + > + return val; > +} > + > static int s3_do_suspend_resume(fwts_framework *fw, > int *hw_errors, > int *pm_errors, > @@ -336,7 +355,7 @@ static int s3_do_suspend_resume(fwts_framework *fw, > } > > if (!strncmp(sleep_type, "s2idle", strlen("s2idle"))) { > - uint32_t residency = atoi(fwts_get(PM_S2IDLE_SLP_S0)); > + uint32_t residency = get_s2_idle_residency(); > bool intel; > if (fwts_cpu_is_Intel(&intel) == FWTS_OK && intel && residency <= *s2idle_residency) { > (*s2idle_errors)++; > @@ -545,7 +564,7 @@ static int s3_test_multiple(fwts_framework *fw) > int resume_too_long = 0; > int awake_delay = s3_min_delay * 1000; > int delta = (int)(s3_delay_delta * 1000.0); > - uint32_t s2idle_residency = atoi(fwts_get(PM_S2IDLE_SLP_S0)); > + uint32_t s2idle_residency = get_s2_idle_residency(); > int pm_debug; > > #if FWTS_ENABLE_LOGIND > Acked-by: Ivan Hu <ivan.hu@canonical.com>
diff --git a/src/acpi/s3/s3.c b/src/acpi/s3/s3.c index fc6186a4..997ac83f 100644 --- a/src/acpi/s3/s3.c +++ b/src/acpi/s3/s3.c @@ -206,6 +206,25 @@ static int wrap_pmutils_do_suspend(fwts_pm_method_vars *fwts_settings, return status; } +/* + * get_s2_idle_residency() + * read PM_S2IDLE_SLP_S0, return 0 if it is not available + */ +static uint32_t get_s2_idle_residency(void) +{ + char *str; + uint32_t val; + + str = fwts_get(PM_S2IDLE_SLP_S0); + if (!str) + return 0; + + val = atoi(str); + free(str); + + return val; +} + static int s3_do_suspend_resume(fwts_framework *fw, int *hw_errors, int *pm_errors, @@ -336,7 +355,7 @@ static int s3_do_suspend_resume(fwts_framework *fw, } if (!strncmp(sleep_type, "s2idle", strlen("s2idle"))) { - uint32_t residency = atoi(fwts_get(PM_S2IDLE_SLP_S0)); + uint32_t residency = get_s2_idle_residency(); bool intel; if (fwts_cpu_is_Intel(&intel) == FWTS_OK && intel && residency <= *s2idle_residency) { (*s2idle_errors)++; @@ -545,7 +564,7 @@ static int s3_test_multiple(fwts_framework *fw) int resume_too_long = 0; int awake_delay = s3_min_delay * 1000; int delta = (int)(s3_delay_delta * 1000.0); - uint32_t s2idle_residency = atoi(fwts_get(PM_S2IDLE_SLP_S0)); + uint32_t s2idle_residency = get_s2_idle_residency(); int pm_debug; #if FWTS_ENABLE_LOGIND