diff mbox series

s3: fix segmentation fault when PM_S2IDLE_SLP_S0 is not available (LP: #1894229)

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

Commit Message

Colin Ian King Sept. 4, 2020, 4:17 p.m. UTC
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(-)

Comments

Alex Hung Sept. 5, 2020, 1:17 a.m. UTC | #1
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>
Ivan Hu Sept. 7, 2020, 2:38 a.m. UTC | #2
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 mbox series

Patch

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