This is the mail archive of the cluster-cvs@sourceware.org mailing list for the cluster.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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;
 }


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]