blob: 9315f8561a9f8b70546788a485416aefb9e133b9 [file] [log] [blame]
Brad Bishopd5ae7d92018-06-14 09:52:03 -07001From c79c48a79710d0e2ef68062435596ac455cd9f71 Mon Sep 17 00:00:00 2001
2From: Richard Purdie <richard.purdie@linuxfoundation.org>
3Date: Wed, 9 Mar 2016 22:49:02 +0000
4Subject: [PATCH] qemu: Limit paths searched during user mode emulation
5
Patrick Williamsd8c66bc2016-06-20 12:57:21 -05006By default qemu builds a complete list of directories within the user
7emulation sysroot (-L option). The OE sysroot directory is large and
8this is confusing, for example it indexes all pkgdata. In particular this
9confuses strace of qemu binaries with tons of irrelevant paths.
10
11This patch stops the code indexing up front and instead only indexes
12things if/as/when it needs to. This drastically reduces the files it
13reads and reduces memory usage and cleans up strace.
14
15It would also avoid the infinite directory traversal bug in [YOCTO #6996]
Brad Bishopd5ae7d92018-06-14 09:52:03 -070016although the code could still be vulnerable if it parsed those specific
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050017paths.
18
19RP
202016/3/9
21Upstream-Status: Pending
Brad Bishopd5ae7d92018-06-14 09:52:03 -070022---
23 util/path.c | 44 ++++++++++++++++++++++----------------------
24 1 file changed, 22 insertions(+), 22 deletions(-)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050025
Brad Bishopd5ae7d92018-06-14 09:52:03 -070026diff --git a/util/path.c b/util/path.c
27index 7f9fc27..a416cd4 100644
28--- a/util/path.c
29+++ b/util/path.c
30@@ -15,6 +15,7 @@ struct pathelem
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050031 char *name;
32 /* Full path name, eg. /usr/gnemul/x86-linux/lib. */
33 char *pathname;
34+ int populated_entries;
35 struct pathelem *parent;
36 /* Children */
37 unsigned int num_entries;
Brad Bishopd5ae7d92018-06-14 09:52:03 -070038@@ -45,6 +46,7 @@ static struct pathelem *new_entry(const char *root,
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050039 new->name = g_strdup(name);
40 new->pathname = g_strdup_printf("%s/%s", root, name);
41 new->num_entries = 0;
42+ new->populated_entries = 0;
43 return new;
44 }
45
Brad Bishopd5ae7d92018-06-14 09:52:03 -070046@@ -53,15 +55,16 @@ static struct pathelem *new_entry(const char *root,
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050047 /* Not all systems provide this feature */
48 #if defined(DT_DIR) && defined(DT_UNKNOWN) && defined(DT_LNK)
49 # define dirent_type(dirent) ((dirent)->d_type)
50-# define is_dir_maybe(type) \
51- ((type) == DT_DIR || (type) == DT_UNKNOWN || (type) == DT_LNK)
52+# define is_not_dir(type) \
53+ ((type) != DT_DIR && (type) != DT_UNKNOWN && (type) != DT_LNK)
54 #else
55 # define dirent_type(dirent) (1)
56-# define is_dir_maybe(type) (type)
57+# define is_not_dir(type) (0)
58 #endif
59
60 static struct pathelem *add_dir_maybe(struct pathelem *path)
61 {
62+ unsigned int i;
63 DIR *dir;
64
65 if ((dir = opendir(path->pathname)) != NULL) {
Brad Bishopd5ae7d92018-06-14 09:52:03 -070066@@ -74,6 +77,11 @@ static struct pathelem *add_dir_maybe(struct pathelem *path)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050067 }
68 closedir(dir);
69 }
70+
71+ for (i = 0; i < path->num_entries; i++)
72+ (path->entries[i])->parent = path;
73+
74+ path->populated_entries = 1;
75 return path;
76 }
77
Brad Bishopd5ae7d92018-06-14 09:52:03 -070078@@ -89,26 +97,16 @@ static struct pathelem *add_entry(struct pathelem *root, const char *name,
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050079 e = &root->entries[root->num_entries-1];
80
81 *e = new_entry(root->pathname, root, name);
82- if (is_dir_maybe(type)) {
83- *e = add_dir_maybe(*e);
84+ if (is_not_dir(type)) {
85+ (*e)->populated_entries = 1;
86 }
87
88 return root;
89 }
90
91-/* This needs to be done after tree is stabilized (ie. no more reallocs!). */
92-static void set_parents(struct pathelem *child, struct pathelem *parent)
93-{
94- unsigned int i;
95-
96- child->parent = parent;
97- for (i = 0; i < child->num_entries; i++)
98- set_parents(child->entries[i], child);
99-}
100-
101 /* FIXME: Doesn't handle DIR/.. where DIR is not in emulated dir. */
102 static const char *
103-follow_path(const struct pathelem *cursor, const char *name)
104+follow_path(struct pathelem *cursor, struct pathelem **source, const char *name)
105 {
106 unsigned int i, namelen;
107
Brad Bishopd5ae7d92018-06-14 09:52:03 -0700108@@ -119,14 +117,18 @@ follow_path(const struct pathelem *cursor, const char *name)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500109 return cursor->pathname;
110
111 if (strneq(name, namelen, ".."))
112- return follow_path(cursor->parent, name + namelen);
113+ return follow_path(cursor->parent, &cursor->parent, name + namelen);
114
115 if (strneq(name, namelen, "."))
116- return follow_path(cursor, name + namelen);
117+ return follow_path(cursor, source, name + namelen);
118+
119+ if (!cursor->populated_entries)
120+ *source = add_dir_maybe(cursor);
121+ cursor = *source;
122
123 for (i = 0; i < cursor->num_entries; i++)
124 if (strneq(name, namelen, cursor->entries[i]->name))
125- return follow_path(cursor->entries[i], name + namelen);
126+ return follow_path(cursor->entries[i], &cursor->entries[i], name + namelen);
127
128 /* Not found */
129 return NULL;
Brad Bishopd5ae7d92018-06-14 09:52:03 -0700130@@ -160,8 +162,6 @@ void init_paths(const char *prefix)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500131 g_free(base->name);
132 g_free(base);
133 base = NULL;
134- } else {
135- set_parents(base, base);
136 }
137 }
138
Brad Bishopd5ae7d92018-06-14 09:52:03 -0700139@@ -173,5 +173,5 @@ const char *path(const char *name)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500140 if (!base || !name || name[0] != '/')
141 return name;
142
143- return follow_path(base, name) ?: name;
144+ return follow_path(base, &base, name) ?: name;
145 }