summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--meta/recipes-devtools/qemu/qemu/pathlimit.patch137
-rw-r--r--meta/recipes-devtools/qemu/qemu_2.5.0.bb1
2 files changed, 138 insertions, 0 deletions
diff --git a/meta/recipes-devtools/qemu/qemu/pathlimit.patch b/meta/recipes-devtools/qemu/qemu/pathlimit.patch
new file mode 100644
index 0000000000..57ab981c61
--- /dev/null
+++ b/meta/recipes-devtools/qemu/qemu/pathlimit.patch
@@ -0,0 +1,137 @@
+By default qemu builds a complete list of directories within the user
+emulation sysroot (-L option). The OE sysroot directory is large and
+this is confusing, for example it indexes all pkgdata. In particular this
+confuses strace of qemu binaries with tons of irrelevant paths.
+
+This patch stops the code indexing up front and instead only indexes
+things if/as/when it needs to. This drastically reduces the files it
+reads and reduces memory usage and cleans up strace.
+
+It would also avoid the infinite directory traversal bug in [YOCTO #6996]
+although the code could still be vulnerable if it parsed those specific
+paths.
+
+RP
+2016/3/9
+Upstream-Status: Pending
+
+Index: qemu-2.5.0/util/path.c
+===================================================================
+--- qemu-2.5.0.orig/util/path.c
++++ qemu-2.5.0/util/path.c
+@@ -19,6 +19,7 @@ struct pathelem
+ char *name;
+ /* Full path name, eg. /usr/gnemul/x86-linux/lib. */
+ char *pathname;
++ int populated_entries;
+ struct pathelem *parent;
+ /* Children */
+ unsigned int num_entries;
+@@ -49,6 +50,7 @@ static struct pathelem *new_entry(const
+ new->name = g_strdup(name);
+ new->pathname = g_strdup_printf("%s/%s", root, name);
+ new->num_entries = 0;
++ new->populated_entries = 0;
+ return new;
+ }
+
+@@ -57,15 +59,16 @@ static struct pathelem *new_entry(const
+ /* Not all systems provide this feature */
+ #if defined(DT_DIR) && defined(DT_UNKNOWN) && defined(DT_LNK)
+ # define dirent_type(dirent) ((dirent)->d_type)
+-# define is_dir_maybe(type) \
+- ((type) == DT_DIR || (type) == DT_UNKNOWN || (type) == DT_LNK)
++# define is_not_dir(type) \
++ ((type) != DT_DIR && (type) != DT_UNKNOWN && (type) != DT_LNK)
+ #else
+ # define dirent_type(dirent) (1)
+-# define is_dir_maybe(type) (type)
++# define is_not_dir(type) (0)
+ #endif
+
+ static struct pathelem *add_dir_maybe(struct pathelem *path)
+ {
++ unsigned int i;
+ DIR *dir;
+
+ if ((dir = opendir(path->pathname)) != NULL) {
+@@ -78,6 +81,11 @@ static struct pathelem *add_dir_maybe(st
+ }
+ closedir(dir);
+ }
++
++ for (i = 0; i < path->num_entries; i++)
++ (path->entries[i])->parent = path;
++
++ path->populated_entries = 1;
+ return path;
+ }
+
+@@ -93,26 +101,16 @@ static struct pathelem *add_entry(struct
+ e = &root->entries[root->num_entries-1];
+
+ *e = new_entry(root->pathname, root, name);
+- if (is_dir_maybe(type)) {
+- *e = add_dir_maybe(*e);
++ if (is_not_dir(type)) {
++ (*e)->populated_entries = 1;
+ }
+
+ return root;
+ }
+
+-/* This needs to be done after tree is stabilized (ie. no more reallocs!). */
+-static void set_parents(struct pathelem *child, struct pathelem *parent)
+-{
+- unsigned int i;
+-
+- child->parent = parent;
+- for (i = 0; i < child->num_entries; i++)
+- set_parents(child->entries[i], child);
+-}
+-
+ /* FIXME: Doesn't handle DIR/.. where DIR is not in emulated dir. */
+ static const char *
+-follow_path(const struct pathelem *cursor, const char *name)
++follow_path(struct pathelem *cursor, struct pathelem **source, const char *name)
+ {
+ unsigned int i, namelen;
+
+@@ -123,14 +121,18 @@ follow_path(const struct pathelem *curso
+ return cursor->pathname;
+
+ if (strneq(name, namelen, ".."))
+- return follow_path(cursor->parent, name + namelen);
++ return follow_path(cursor->parent, &cursor->parent, name + namelen);
+
+ if (strneq(name, namelen, "."))
+- return follow_path(cursor, name + namelen);
++ return follow_path(cursor, source, name + namelen);
++
++ if (!cursor->populated_entries)
++ *source = add_dir_maybe(cursor);
++ cursor = *source;
+
+ for (i = 0; i < cursor->num_entries; i++)
+ if (strneq(name, namelen, cursor->entries[i]->name))
+- return follow_path(cursor->entries[i], name + namelen);
++ return follow_path(cursor->entries[i], &cursor->entries[i], name + namelen);
+
+ /* Not found */
+ return NULL;
+@@ -164,8 +166,6 @@ void init_paths(const char *prefix)
+ g_free(base->name);
+ g_free(base);
+ base = NULL;
+- } else {
+- set_parents(base, base);
+ }
+ }
+
+@@ -177,5 +177,5 @@ const char *path(const char *name)
+ if (!base || !name || name[0] != '/')
+ return name;
+
+- return follow_path(base, name) ?: name;
++ return follow_path(base, &base, name) ?: name;
+ }
diff --git a/meta/recipes-devtools/qemu/qemu_2.5.0.bb b/meta/recipes-devtools/qemu/qemu_2.5.0.bb
index 4398a18b02..e9d9a8dce7 100644
--- a/meta/recipes-devtools/qemu/qemu_2.5.0.bb
+++ b/meta/recipes-devtools/qemu/qemu_2.5.0.bb
@@ -10,6 +10,7 @@ SRC_URI += "file://configure-fix-Darwin-target-detection.patch \
file://CVE-2016-1568.patch \
file://CVE-2016-2197.patch \
file://CVE-2016-2198.patch \
+ file://pathlimit.patch \
"
SRC_URI_prepend = "http://wiki.qemu-project.org/download/${BP}.tar.bz2"
SRC_URI[md5sum] = "f469f2330bbe76e3e39db10e9ac4f8db"