This is the mail archive of the
cluster-cvs@sourceware.org
mailing list for the cluster.
STABLE2 - cman: fix buffer overflow when reading huge config files
- From: "Fabio M. Di Nitto" <fabbione at fedoraproject dot org>
- To: cluster-cvs-relay at redhat dot com
- Date: Thu, 30 Oct 2008 06:12:51 +0000 (UTC)
- Subject: STABLE2 - cman: fix buffer overflow when reading huge config files
Gitweb: http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=5387db82a08b8d8bed5ab20226512816ef29b867
Commit: 5387db82a08b8d8bed5ab20226512816ef29b867
Parent: f30044e43a7b5260b18cc184888509ee3d719033
Author: Fabio M. Di Nitto <fdinitto@redhat.com>
AuthorDate: Thu Oct 30 07:10:29 2008 +0100
Committer: Fabio M. Di Nitto <fdinitto@redhat.com>
CommitterDate: Thu Oct 30 07:10:29 2008 +0100
cman: fix buffer overflow when reading huge config files
it was possible to overflow a buffer when adding more than 52 entries
within the same xml block:
<block>
<entry1...
<entry2...
....
<entry53.. <-
</block>
fix the overflow by increasing the limit to 1024 and fail to start if
we hit the limit.
Bugzilla: #468966
Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
---
cman/daemon/ais.c | 8 +++++++-
cman/daemon/config.c | 49 ++++++++++++++++++++++++++++++++++++++-----------
2 files changed, 45 insertions(+), 12 deletions(-)
diff --git a/cman/daemon/ais.c b/cman/daemon/ais.c
index 77cbf19..3f10f63 100644
--- a/cman/daemon/ais.c
+++ b/cman/daemon/ais.c
@@ -212,7 +212,13 @@ static int cman_readconfig(struct objdb_iface_ver0 *objdb, char **error_string)
logsys_config_subsys_set(CMAN_NAME, LOGSYS_TAG_LOG, LOG_DEBUG);
/* Read low-level totem/aisexec etc config from CCS */
- init_config(objdb);
+ error = init_config(objdb);
+ if (error < 0)
+ {
+ write_cman_pipe("Error reading config from CCS");
+ *error_string = "Error reading config from CCS";
+ return -1;
+ }
/* Read cman-specific config from CCS */
error = read_ccs_config();
diff --git a/cman/daemon/config.c b/cman/daemon/config.c
index a9228f1..29f91a2 100644
--- a/cman/daemon/config.c
+++ b/cman/daemon/config.c
@@ -13,6 +13,10 @@
LOGSYS_DECLARE_SUBSYS (CMAN_NAME, LOG_INFO);
+#ifndef MAXXMLNODES
+#define MAXXMLNODES 1024
+#endif
+
static int read_config_for(int ccs_fd, struct objdb_iface_ver0 *objdb, unsigned int parent,
char *object, char *key, int always_create)
{
@@ -21,7 +25,7 @@ static int read_config_for(int ccs_fd, struct objdb_iface_ver0 *objdb, unsigned
unsigned int object_handle = 0;
char path[256];
int gotcount = 0;
- char *subkeys[52];
+ char *subkeys[MAXXMLNODES];
int subkeycount = 0;
int i;
@@ -91,11 +95,14 @@ static int read_config_for(int ccs_fd, struct objdb_iface_ver0 *objdb, unsigned
break;
}
subkeys[subkeycount++] = str;
+ if (subkeycount >= MAXXMLNODES)
+ return -1;
}
for (i=0; i<subkeycount; i++)
{
int count = 0;
+ int res;
str = subkeys[i];
gotcount++;
@@ -109,31 +116,51 @@ static int read_config_for(int ccs_fd, struct objdb_iface_ver0 *objdb, unsigned
/* Found a subkey, iterate through it's sub sections */
sprintf(subpath, "%s/%s[%d]", key, str, ++count);
- if (!read_config_for(ccs_fd, objdb, object_handle, str, subpath, 0))
+ res = read_config_for(ccs_fd, objdb, object_handle, str, subpath, 0);
+ if (!res)
break;
+ if (res < 0)
+ return -1;
}
free(str);
}
return gotcount;
}
-void init_config(struct objdb_iface_ver0 *objdb)
+int init_config(struct objdb_iface_ver0 *objdb)
{
- int cd;
+ int cd, err;
cd = ccs_force_connect(NULL, 0);
if (cd < 0)
- return;
+ return -1;
/* These first few are just versions of openais.conf */
- read_config_for(cd, objdb, OBJECT_PARENT_HANDLE, "totem", "totem", 1);
- read_config_for(cd, objdb, OBJECT_PARENT_HANDLE, "logging", "logging", 1);
- read_config_for(cd, objdb, OBJECT_PARENT_HANDLE, "event", "event", 1);
- read_config_for(cd, objdb, OBJECT_PARENT_HANDLE, "aisexec", "aisexec", 1);
- read_config_for(cd, objdb, OBJECT_PARENT_HANDLE, "amf", "amf", 1);
+ err = read_config_for(cd, objdb, OBJECT_PARENT_HANDLE, "totem", "totem", 1);
+ if (err < 0)
+ goto fail;
+
+ err = read_config_for(cd, objdb, OBJECT_PARENT_HANDLE, "logging", "logging", 1);
+ if (err < 0)
+ goto fail;
+
+ err = read_config_for(cd, objdb, OBJECT_PARENT_HANDLE, "event", "event", 1);
+ if (err < 0)
+ goto fail;
+
+ err = read_config_for(cd, objdb, OBJECT_PARENT_HANDLE, "aisexec", "aisexec", 1);
+ if (err < 0)
+ goto fail;
+
+ err = read_config_for(cd, objdb, OBJECT_PARENT_HANDLE, "amf", "amf", 1);
+ if (err < 0)
+ goto fail;
/* This is stuff specific to us, eg quorum device timeout */
- read_config_for(cd, objdb, OBJECT_PARENT_HANDLE, "cman", "cman", 1);
+ err = read_config_for(cd, objdb, OBJECT_PARENT_HANDLE, "cman", "cman", 1);
+fail:
ccs_disconnect(cd);
+
+ return err;
}