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