Don't write to wpa_supplicant.conf directly

There is a chance that wpa_supplicant may get killed during
the time it is writing config file. If this happens, user
information like SSIDs and passwords can be lost forever.

This change works around that by writing config to a
temporary file and then renaming the file to the correct name.

Signed-off-by: Vinit Deshpande <vinitd@google.com>
This commit is contained in:
Vinit Deshpande 2015-02-05 12:48:02 -08:00 committed by Jouni Malinen
parent 4cfc46934d
commit 663ae2f417

View file

@ -11,6 +11,9 @@
*/ */
#include "includes.h" #include "includes.h"
#ifdef ANDROID
#include <sys/stat.h>
#endif /* ANDROID */
#include "common.h" #include "common.h"
#include "config.h" #include "config.h"
@ -1245,12 +1248,21 @@ int wpa_config_write(const char *name, struct wpa_config *config)
struct wpa_config_blob *blob; struct wpa_config_blob *blob;
#endif /* CONFIG_NO_CONFIG_BLOBS */ #endif /* CONFIG_NO_CONFIG_BLOBS */
int ret = 0; int ret = 0;
const char *orig_name = name;
int tmp_len = os_strlen(name) + 5; /* allow space for .tmp suffix */
char *tmp_name = os_malloc(tmp_len);
if (tmp_name) {
os_snprintf(tmp_name, tmp_len, "%s.tmp", name);
name = tmp_name;
}
wpa_printf(MSG_DEBUG, "Writing configuration file '%s'", name); wpa_printf(MSG_DEBUG, "Writing configuration file '%s'", name);
f = fopen(name, "w"); f = fopen(name, "w");
if (f == NULL) { if (f == NULL) {
wpa_printf(MSG_DEBUG, "Failed to open '%s' for writing", name); wpa_printf(MSG_DEBUG, "Failed to open '%s' for writing", name);
os_free(tmp_name);
return -1; return -1;
} }
@ -1285,8 +1297,21 @@ int wpa_config_write(const char *name, struct wpa_config *config)
fclose(f); fclose(f);
if (tmp_name) {
int chmod_ret = 0;
#ifdef ANDROID
chmod_ret = chmod(tmp_name,
S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
#endif /* ANDROID */
if (chmod_ret != 0 || rename(tmp_name, orig_name) != 0)
ret = -1;
os_free(tmp_name);
}
wpa_printf(MSG_DEBUG, "Configuration file '%s' written %ssuccessfully", wpa_printf(MSG_DEBUG, "Configuration file '%s' written %ssuccessfully",
name, ret ? "un" : ""); orig_name, ret ? "un" : "");
return ret; return ret;
#else /* CONFIG_NO_CONFIG_WRITE */ #else /* CONFIG_NO_CONFIG_WRITE */
return -1; return -1;