[syslinux:elflink] ldlinux: Avoid initialised data memory corruption

syslinux-bot for Matt Fleming matt.fleming at intel.com
Mon Mar 26 15:36:06 PDT 2012


Commit-ID:  2fb06e3ff4cad75633c78f56f99b4b3e3652b633
Gitweb:     http://www.syslinux.org/commit/2fb06e3ff4cad75633c78f56f99b4b3e3652b633
Author:     Matt Fleming <matt.fleming at intel.com>
AuthorDate: Wed, 7 Mar 2012 15:18:51 +0000
Committer:  Matt Fleming <matt.fleming at intel.com>
CommitDate: Fri, 23 Mar 2012 16:56:16 +0000

ldlinux: Avoid initialised data memory corruption

We can't realloc() 'PATH' because realloc() may just extend the
malloc'd region if the adjacent region is free, as opposed to
allocating a new region and then copying the data. This behaviour is
fine in most circumstances but not with initialised string data, such
as 'PATH'. The reason is that other string data pointers may point to
characters in 'PATH' and if we modify it after realloc()'ing, we'll
appear to corrupt unrelated string data.

For example, the string "/" is used in chdir() and the address of that
string is the last "/" in 'PATH'. If we realloc() and then append
"foo" to 'PATH' the string pointer in chdir() will now point to "/foo".

Initialise 'PATH' at runtime using malloc() and free() to avoid
corrupting string data.

Signed-off-by: Matt Fleming <matt.fleming at intel.com>

---
 com32/elflink/ldlinux/readconfig.c |    3 ++-
 core/elflink/load_env32.c          |    9 +++++++++
 core/fs/fs.c                       |    2 +-
 core/include/fs.h                  |    1 +
 4 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/com32/elflink/ldlinux/readconfig.c b/com32/elflink/ldlinux/readconfig.c
index 573d724..4f7a4d2 100644
--- a/com32/elflink/ldlinux/readconfig.c
+++ b/com32/elflink/ldlinux/readconfig.c
@@ -1315,12 +1315,13 @@ do_include:
 		new_path = refstrdup(skipspace(p + 4));
 		len = strlen(PATH);
 		new_len = strlen(new_path);
-		_p = realloc(PATH, len + new_len + 2);
+		_p = malloc(len + new_len + 2);
 		if (_p) {
 			strncpy(_p, PATH, len);
 			_p[len++] = ':';
 			strncpy(_p + len, new_path, new_len);
 			_p[len + new_len] = '\0';
+			free(PATH);
 			PATH = _p;
 		} else
 			eprintf("Failed to realloc PATH\n");
diff --git a/core/elflink/load_env32.c b/core/elflink/load_env32.c
index 75f5629..2dd4a7b 100644
--- a/core/elflink/load_env32.c
+++ b/core/elflink/load_env32.c
@@ -139,6 +139,15 @@ void load_env32(com32sys_t * regs)
 	dprintf("Starting 32 bit elf module subsystem...\n");
 	call_constr();
 
+	PATH = malloc(strlen(PATH_DEFAULT) + 1);
+	if (!PATH) {
+		printf("Couldn't allocate memory for PATH\n");
+		return;
+	}
+
+	strcpy(PATH, PATH_DEFAULT);
+	PATH[strlen(PATH_DEFAULT)] = '\0';
+
 	init_module_subsystem(&core_module);
 
 	start_ldlinux(argv);
diff --git a/core/fs/fs.c b/core/fs/fs.c
index a4fb4f7..d8f8660 100644
--- a/core/fs/fs.c
+++ b/core/fs/fs.c
@@ -8,7 +8,7 @@
 #include "fs.h"
 #include "cache.h"
 
-char *PATH = ".:/bin/";
+char *PATH;
 
 /* The currently mounted filesystem */
 struct fs_info *this_fs = NULL;		/* Root filesystem */
diff --git a/core/include/fs.h b/core/include/fs.h
index a554a46..fd8e483 100644
--- a/core/include/fs.h
+++ b/core/include/fs.h
@@ -179,6 +179,7 @@ static inline struct file *handle_to_file(uint16_t handle)
     return handle ? &files[handle-1] : NULL;
 }
 
+#define PATH_DEFAULT	".:/bin/"
 extern char *PATH;
 
 /* fs.c */


More information about the Syslinux-commits mailing list