aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Fleming <matt.fleming@intel.com>2012-03-07 15:18:51 +0000
committerMatt Fleming <matt.fleming@intel.com>2012-03-23 16:56:16 +0000
commit2fb06e3ff4cad75633c78f56f99b4b3e3652b633 (patch)
tree67152777af6c4fee41982b07b21e959a726fe254
parentdb63acbdcd3603bbd42238dac19902ce00fe5d59 (diff)
downloadsyslinux-2fb06e3ff4cad75633c78f56f99b4b3e3652b633.tar.gz
syslinux-2fb06e3ff4cad75633c78f56f99b4b3e3652b633.tar.xz
syslinux-2fb06e3ff4cad75633c78f56f99b4b3e3652b633.zip
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@intel.com>
-rw-r--r--com32/elflink/ldlinux/readconfig.c3
-rw-r--r--core/elflink/load_env32.c9
-rw-r--r--core/fs/fs.c2
-rw-r--r--core/include/fs.h1
4 files changed, 13 insertions, 2 deletions
diff --git a/com32/elflink/ldlinux/readconfig.c b/com32/elflink/ldlinux/readconfig.c
index 573d7246..4f7a4d22 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 75f56296..2dd4a7bc 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 a4fb4f77..d8f8660c 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 a554a46d..fd8e4834 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 */