sleep-config: fix double free

Before 34a3baa4d 'sleep-config: Dereference pointer before check for NULL'
oom conditions would not be detected properly. After that commit, a double
free was performed.

Rework the whole function to be easier to understand, and also replace
strv_split_nulstr with strv_new, since we know the strings anyway.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2013-12-31 13:00:57 -05:00
parent b8265d4f8e
commit dabeaa460d
+20 -18
View File
@@ -28,11 +28,14 @@
#include "strv.h"
#include "util.h"
int parse_sleep_config(const char *verb, char ***modes, char ***states) {
#define USE(x, y) do{ (x) = (y); (y) = NULL; } while(0)
int parse_sleep_config(const char *verb, char ***_modes, char ***_states) {
_cleanup_strv_free_ char
**suspend_mode = NULL, **suspend_state = NULL,
**hibernate_mode = NULL, **hibernate_state = NULL,
**hybrid_mode = NULL, **hybrid_state = NULL;
char **modes, **states;
const ConfigTableItem items[] = {
{ "Sleep", "SuspendMode", config_parse_strv, 0, &suspend_mode },
@@ -59,47 +62,46 @@ int parse_sleep_config(const char *verb, char ***modes, char ***states) {
if (streq(verb, "suspend")) {
/* empty by default */
*modes = suspend_mode;
USE(modes, suspend_mode);
if (suspend_state)
*states = suspend_state;
USE(states, suspend_state);
else
*states = strv_split_nulstr("mem\0standby\0freeze\0");
states = strv_new("mem", "standby", "freeze", NULL);
suspend_mode = suspend_state = NULL;
} else if (streq(verb, "hibernate")) {
if (hibernate_mode)
*modes = hibernate_mode;
USE(modes, hibernate_mode);
else
*modes = strv_split_nulstr("platform\0shutdown\0");
modes = strv_new("platform", "shutdown", NULL);
if (hibernate_state)
*states = hibernate_state;
USE(states, hibernate_state);
else
*states = strv_split_nulstr("disk\0");
states = strv_new("disk", NULL);
hibernate_mode = hibernate_state = NULL;
} else if (streq(verb, "hybrid-sleep")) {
if (hybrid_mode)
*modes = hybrid_mode;
USE(modes, hybrid_mode);
else
*modes = strv_split_nulstr("suspend\0platform\0shutdown\0");
modes = strv_new("suspend", "platform", "shutdown", NULL);
if (hybrid_state)
*states = hybrid_state;
USE(states, hybrid_state);
else
*states = strv_split_nulstr("disk\0");
states = strv_new("disk", NULL);
hybrid_mode = hybrid_state = NULL;
} else
assert_not_reached("what verb");
if (!*modes || !*states) {
strv_free(*modes);
strv_free(*states);
if ((!modes && !streq(verb, "suspend")) || !states) {
strv_free(modes);
strv_free(states);
return log_oom();
}
*_modes = modes;
*_states = states;
return 0;
}