|
|
9fc0f6 |
From 9835435400e945b294872a525aacf99a5ad5bcf5 Mon Sep 17 00:00:00 2001
|
|
|
9fc0f6 |
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
|
|
9fc0f6 |
Date: Tue, 31 Dec 2013 11:23:58 -0500
|
|
|
9fc0f6 |
Subject: [PATCH] sleep-config: fix double free
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
Before 34a3baa4d 'sleep-config: Dereference pointer before check for NULL'
|
|
|
9fc0f6 |
oom conditions would not be detected properly. After that commit, a double
|
|
|
9fc0f6 |
free was performed.
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
Rework the whole function to be easier to understand, and also replace
|
|
|
9fc0f6 |
strv_split_nulstr with strv_new, since we know the strings anyway.
|
|
|
9fc0f6 |
---
|
|
|
9fc0f6 |
src/shared/sleep-config.c | 38 ++++++++++++++++++++------------------
|
|
|
9fc0f6 |
1 file changed, 20 insertions(+), 18 deletions(-)
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
diff --git a/src/shared/sleep-config.c b/src/shared/sleep-config.c
|
|
|
9fc0f6 |
index b2a0787..70a0896 100644
|
|
|
9fc0f6 |
--- a/src/shared/sleep-config.c
|
|
|
9fc0f6 |
+++ b/src/shared/sleep-config.c
|
|
|
9fc0f6 |
@@ -28,11 +28,14 @@
|
|
|
9fc0f6 |
#include "strv.h"
|
|
|
9fc0f6 |
#include "util.h"
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
-int parse_sleep_config(const char *verb, char ***modes, char ***states) {
|
|
|
9fc0f6 |
+#define USE(x, y) do{ (x) = (y); (y) = NULL; } while(0)
|
|
|
9fc0f6 |
+
|
|
|
9fc0f6 |
+int parse_sleep_config(const char *verb, char ***_modes, char ***_states) {
|
|
|
9fc0f6 |
_cleanup_strv_free_ char
|
|
|
9fc0f6 |
**suspend_mode = NULL, **suspend_state = NULL,
|
|
|
9fc0f6 |
**hibernate_mode = NULL, **hibernate_state = NULL,
|
|
|
9fc0f6 |
**hybrid_mode = NULL, **hybrid_state = NULL;
|
|
|
9fc0f6 |
+ char **modes, **states;
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
const ConfigTableItem items[] = {
|
|
|
9fc0f6 |
{ "Sleep", "SuspendMode", config_parse_strv, 0, &suspend_mode },
|
|
|
9fc0f6 |
@@ -59,47 +62,46 @@ int parse_sleep_config(const char *verb, char ***modes, char ***states) {
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
if (streq(verb, "suspend")) {
|
|
|
9fc0f6 |
/* empty by default */
|
|
|
9fc0f6 |
- *modes = suspend_mode;
|
|
|
9fc0f6 |
+ USE(modes, suspend_mode);
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
if (suspend_state)
|
|
|
9fc0f6 |
- *states = suspend_state;
|
|
|
9fc0f6 |
+ USE(states, suspend_state);
|
|
|
9fc0f6 |
else
|
|
|
9fc0f6 |
- *states = strv_split_nulstr("mem\0standby\0freeze\0");
|
|
|
9fc0f6 |
+ states = strv_new("mem", "standby", "freeze", NULL);
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
- suspend_mode = suspend_state = NULL;
|
|
|
9fc0f6 |
} else if (streq(verb, "hibernate")) {
|
|
|
9fc0f6 |
if (hibernate_mode)
|
|
|
9fc0f6 |
- *modes = hibernate_mode;
|
|
|
9fc0f6 |
+ USE(modes, hibernate_mode);
|
|
|
9fc0f6 |
else
|
|
|
9fc0f6 |
- *modes = strv_split_nulstr("platform\0shutdown\0");
|
|
|
9fc0f6 |
+ modes = strv_new("platform", "shutdown", NULL);
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
if (hibernate_state)
|
|
|
9fc0f6 |
- *states = hibernate_state;
|
|
|
9fc0f6 |
+ USE(states, hibernate_state);
|
|
|
9fc0f6 |
else
|
|
|
9fc0f6 |
- *states = strv_split_nulstr("disk\0");
|
|
|
9fc0f6 |
+ states = strv_new("disk", NULL);
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
- hibernate_mode = hibernate_state = NULL;
|
|
|
9fc0f6 |
} else if (streq(verb, "hybrid-sleep")) {
|
|
|
9fc0f6 |
if (hybrid_mode)
|
|
|
9fc0f6 |
- *modes = hybrid_mode;
|
|
|
9fc0f6 |
+ USE(modes, hybrid_mode);
|
|
|
9fc0f6 |
else
|
|
|
9fc0f6 |
- *modes = strv_split_nulstr("suspend\0platform\0shutdown\0");
|
|
|
9fc0f6 |
+ modes = strv_new("suspend", "platform", "shutdown", NULL);
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
if (hybrid_state)
|
|
|
9fc0f6 |
- *states = hybrid_state;
|
|
|
9fc0f6 |
+ USE(states, hybrid_state);
|
|
|
9fc0f6 |
else
|
|
|
9fc0f6 |
- *states = strv_split_nulstr("disk\0");
|
|
|
9fc0f6 |
+ states = strv_new("disk", NULL);
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
- hybrid_mode = hybrid_state = NULL;
|
|
|
9fc0f6 |
} else
|
|
|
9fc0f6 |
assert_not_reached("what verb");
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
- if (!*modes || !*states) {
|
|
|
9fc0f6 |
- strv_free(*modes);
|
|
|
9fc0f6 |
- strv_free(*states);
|
|
|
9fc0f6 |
+ if ((!modes && !streq(verb, "suspend")) || !states) {
|
|
|
9fc0f6 |
+ strv_free(modes);
|
|
|
9fc0f6 |
+ strv_free(states);
|
|
|
9fc0f6 |
return log_oom();
|
|
|
9fc0f6 |
}
|
|
|
9fc0f6 |
|
|
|
9fc0f6 |
+ *_modes = modes;
|
|
|
9fc0f6 |
+ *_states = states;
|
|
|
9fc0f6 |
return 0;
|
|
|
9fc0f6 |
}
|
|
|
9fc0f6 |
|