[oe-commits] [openembedded-core] 07/12: qemu: Limit paths searched during user mode emulation

git at git.openembedded.org git at git.openembedded.org
Thu Mar 10 23:14:31 UTC 2016


rpurdie pushed a commit to branch master
in repository openembedded-core.

commit 9ac5017b3328a18561c2912edfda2d7d97c675f2
Author: Richard Purdie <richard.purdie at linuxfoundation.org>
AuthorDate: Wed Mar 9 22:49:02 2016 +0000

    qemu: Limit paths searched during user mode emulation
    
    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.
    
    Signed-off-by: Richard Purdie <richard.purdie at linuxfoundation.org>
---
 meta/recipes-devtools/qemu/qemu/pathlimit.patch | 137 ++++++++++++++++++++++++
 meta/recipes-devtools/qemu/qemu_2.5.0.bb        |   1 +
 2 files changed, 138 insertions(+)

diff --git a/meta/recipes-devtools/qemu/qemu/pathlimit.patch b/meta/recipes-devtools/qemu/qemu/pathlimit.patch
new file mode 100644
index 0000000..57ab981
--- /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 4398a18..e9d9a8d 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"

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Openembedded-commits mailing list