[augeas-devel] [PATCH 2/4] Fix BZ 613967 - memory corruption on reloading externally modified file
lutter at redhat.com
lutter at redhat.com
Thu Aug 5 20:58:26 UTC 2010
From: David Lutterkort <lutter at redhat.com>
The problem was that when we replaced the old tree for a file with the new
one we just read from the file, the replace operation did not update
nodesets in variables, since we did not pass the global symtab into
tree_replace.
* src/internal.h (tree_replace): pass in struct augeas, so that we have
access to the global symtab
* src/augeas.c (tree_replace): make sure we create the pathx with the
global symtab
* src/transform.c (load_file): adapt to new prototype for tree_replace
* tests/test-load.c (testReloadExternalMod): test that we do not segfault
when a file was modified externally
---
src/augeas.c | 6 +++---
src/internal.h | 2 +-
src/transform.c | 2 +-
tests/test-load.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++--
4 files changed, 55 insertions(+), 7 deletions(-)
diff --git a/src/augeas.c b/src/augeas.c
index 9ae217e..68ef86c 100644
--- a/src/augeas.c
+++ b/src/augeas.c
@@ -916,13 +916,13 @@ int aug_rm(struct augeas *aug, const char *path) {
return -1;
}
-int tree_replace(struct tree *origin, const char *path, struct tree *sub) {
+int tree_replace(struct augeas *aug, const char *path, struct tree *sub) {
struct tree *parent;
struct pathx *p = NULL;
int r;
- if (pathx_parse(origin, NULL, path, true, NULL, &p) != PATHX_NOERROR)
- goto error;
+ p = parse_user_pathx(aug, true, path);
+ ERR_BAIL(aug);
r = tree_rm(p);
if (r == -1)
diff --git a/src/internal.h b/src/internal.h
index 7513d47..c2fc649 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -366,7 +366,7 @@ struct tree *make_tree(char *label, char *value,
*/
struct tree *make_tree_origin(struct tree *root);
-int tree_replace(struct tree *origin, const char *path, struct tree *sub);
+int tree_replace(struct augeas *aug, const char *path, struct tree *sub);
/* Make a new tree node and append it to parent's children */
struct tree *tree_append(struct tree *parent, char *label, char *value);
diff --git a/src/transform.c b/src/transform.c
index 00552da..fa082c3 100644
--- a/src/transform.c
+++ b/src/transform.c
@@ -497,7 +497,7 @@ static int load_file(struct augeas *aug, struct lens *lens,
goto done;
}
- tree_replace(aug->origin, path, tree);
+ tree_replace(aug, path, tree);
tree = NULL;
result = 0;
diff --git a/tests/test-load.c b/tests/test-load.c
index fe92305..2daf49c 100644
--- a/tests/test-load.c
+++ b/tests/test-load.c
@@ -28,8 +28,8 @@
#include "internal.h"
#define CuAssertPositive(tc, n) CuAssertTrue(tc, (n) > 0)
-#define CuAssertZero(tc, n) CuAssertTrue(tc, (n) == 0)
-#define CuAssertRetSuccess(tc, n) CuAssertTrue(tc, (n) == 0)
+#define CuAssertZero(tc, n) CuAssertIntEquals(tc, 0, (n))
+#define CuAssertRetSuccess(tc, n) CuAssertIntEquals(tc, 0, (n))
static const char *abs_top_srcdir;
static const char *abs_top_builddir;
@@ -400,6 +400,53 @@ static void testReloadDeletedMeta(CuTest *tc) {
aug_close(aug);
}
+/* BZ 613967 - segfault when reloading a file that has been externally
+ * modified, and we have a variable pointing into the old tree
+ */
+static void testReloadExternalMod(CuTest *tc) {
+ augeas *aug = NULL;
+ int r, created;
+ const char *aug_root;
+
+ aug = setup_writable_hosts(tc);
+
+ r = aug_load(aug);
+ CuAssertRetSuccess(tc, r);
+
+ /* Set up a new entry and save */
+ r = aug_defnode(aug, "new", "/files/etc/hosts/3", NULL, &created);
+ CuAssertIntEquals(tc, 1, r);
+ CuAssertIntEquals(tc, 1, created);
+
+ r = aug_set(aug, "$new/ipaddr", "172.31.42.1");
+ CuAssertRetSuccess(tc, r);
+
+ r = aug_set(aug, "$new/canonical", "new.example.com");
+ CuAssertRetSuccess(tc, r);
+
+ r = aug_save(aug);
+ CuAssertRetSuccess(tc, r);
+
+ /* Now modify the file outside of Augeas */
+ r = aug_get(aug, "/augeas/root", &aug_root);
+ CuAssertIntEquals(tc, 1, r);
+
+ run(tc, "sed -i -e '1,2d' %setc/hosts", aug_root);
+
+ /* Reload and save again */
+ r = aug_load(aug);
+ CuAssertRetSuccess(tc, r);
+
+ r = aug_save(aug);
+ CuAssertRetSuccess(tc, r);
+
+ r = aug_match(aug, "/files/etc/hosts/#comment", NULL);
+ CuAssertIntEquals(tc, 2, r);
+
+ r = aug_match(aug, "/files/etc/hosts/*", NULL);
+ CuAssertIntEquals(tc, 5, r);
+}
+
int main(void) {
char *output = NULL;
CuSuite* suite = CuSuiteNew();
@@ -416,6 +463,7 @@ int main(void) {
SUITE_ADD_TEST(suite, testReloadDirty);
SUITE_ADD_TEST(suite, testReloadDeleted);
SUITE_ADD_TEST(suite, testReloadDeletedMeta);
+ SUITE_ADD_TEST(suite, testReloadExternalMod);
abs_top_srcdir = getenv("abs_top_srcdir");
if (abs_top_srcdir == NULL)
--
1.7.2
More information about the augeas-devel
mailing list