blob: 4b2f0137ebfe99acf18253475f9ba5aa273ec44a [file] [log] [blame]
Brad Bishop19323692019-04-05 15:28:33 -04001From 02f80ee81681b6307a8032128a07686183662270 Mon Sep 17 00:00:00 2001
Brad Bishopd5ae7d92018-06-14 09:52:03 -07002From: 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 Bishop19323692019-04-05 15:28:33 -040022
Brad Bishopd5ae7d92018-06-14 09:52:03 -070023---
24 util/path.c | 44 ++++++++++++++++++++++----------------------
25 1 file changed, 22 insertions(+), 22 deletions(-)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050026
Brad Bishopd5ae7d92018-06-14 09:52:03 -070027diff --git a/util/path.c b/util/path.c
Brad Bishop19323692019-04-05 15:28:33 -040028index 7f9fc272..a416cd4a 100644
Brad Bishopd5ae7d92018-06-14 09:52:03 -070029--- a/util/path.c
30+++ b/util/path.c
31@@ -15,6 +15,7 @@ struct pathelem
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050032 char *name;
33 /* Full path name, eg. /usr/gnemul/x86-linux/lib. */
34 char *pathname;
35+ int populated_entries;
36 struct pathelem *parent;
37 /* Children */
38 unsigned int num_entries;
Brad Bishopd5ae7d92018-06-14 09:52:03 -070039@@ -45,6 +46,7 @@ static struct pathelem *new_entry(const char *root,
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050040 new->name = g_strdup(name);
41 new->pathname = g_strdup_printf("%s/%s", root, name);
42 new->num_entries = 0;
43+ new->populated_entries = 0;
44 return new;
45 }
46
Brad Bishopd5ae7d92018-06-14 09:52:03 -070047@@ -53,15 +55,16 @@ static struct pathelem *new_entry(const char *root,
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050048 /* Not all systems provide this feature */
49 #if defined(DT_DIR) && defined(DT_UNKNOWN) && defined(DT_LNK)
50 # define dirent_type(dirent) ((dirent)->d_type)
51-# define is_dir_maybe(type) \
52- ((type) == DT_DIR || (type) == DT_UNKNOWN || (type) == DT_LNK)
53+# define is_not_dir(type) \
54+ ((type) != DT_DIR && (type) != DT_UNKNOWN && (type) != DT_LNK)
55 #else
56 # define dirent_type(dirent) (1)
57-# define is_dir_maybe(type) (type)
58+# define is_not_dir(type) (0)
59 #endif
60
61 static struct pathelem *add_dir_maybe(struct pathelem *path)
62 {
63+ unsigned int i;
64 DIR *dir;
65
66 if ((dir = opendir(path->pathname)) != NULL) {
Brad Bishopd5ae7d92018-06-14 09:52:03 -070067@@ -74,6 +77,11 @@ static struct pathelem *add_dir_maybe(struct pathelem *path)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050068 }
69 closedir(dir);
70 }
71+
72+ for (i = 0; i < path->num_entries; i++)
73+ (path->entries[i])->parent = path;
74+
75+ path->populated_entries = 1;
76 return path;
77 }
78
Brad Bishopd5ae7d92018-06-14 09:52:03 -070079@@ -89,26 +97,16 @@ static struct pathelem *add_entry(struct pathelem *root, const char *name,
Patrick Williamsd8c66bc2016-06-20 12:57:21 -050080 e = &root->entries[root->num_entries-1];
81
82 *e = new_entry(root->pathname, root, name);
83- if (is_dir_maybe(type)) {
84- *e = add_dir_maybe(*e);
85+ if (is_not_dir(type)) {
86+ (*e)->populated_entries = 1;
87 }
88
89 return root;
90 }
91
92-/* This needs to be done after tree is stabilized (ie. no more reallocs!). */
93-static void set_parents(struct pathelem *child, struct pathelem *parent)
94-{
95- unsigned int i;
96-
97- child->parent = parent;
98- for (i = 0; i < child->num_entries; i++)
99- set_parents(child->entries[i], child);
100-}
101-
102 /* FIXME: Doesn't handle DIR/.. where DIR is not in emulated dir. */
103 static const char *
104-follow_path(const struct pathelem *cursor, const char *name)
105+follow_path(struct pathelem *cursor, struct pathelem **source, const char *name)
106 {
107 unsigned int i, namelen;
108
Brad Bishopd5ae7d92018-06-14 09:52:03 -0700109@@ -119,14 +117,18 @@ follow_path(const struct pathelem *cursor, const char *name)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500110 return cursor->pathname;
111
112 if (strneq(name, namelen, ".."))
113- return follow_path(cursor->parent, name + namelen);
114+ return follow_path(cursor->parent, &cursor->parent, name + namelen);
115
116 if (strneq(name, namelen, "."))
117- return follow_path(cursor, name + namelen);
118+ return follow_path(cursor, source, name + namelen);
119+
120+ if (!cursor->populated_entries)
121+ *source = add_dir_maybe(cursor);
122+ cursor = *source;
123
124 for (i = 0; i < cursor->num_entries; i++)
125 if (strneq(name, namelen, cursor->entries[i]->name))
126- return follow_path(cursor->entries[i], name + namelen);
127+ return follow_path(cursor->entries[i], &cursor->entries[i], name + namelen);
128
129 /* Not found */
130 return NULL;
Brad Bishopd5ae7d92018-06-14 09:52:03 -0700131@@ -160,8 +162,6 @@ void init_paths(const char *prefix)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500132 g_free(base->name);
133 g_free(base);
134 base = NULL;
135- } else {
136- set_parents(base, base);
137 }
138 }
139
Brad Bishopd5ae7d92018-06-14 09:52:03 -0700140@@ -173,5 +173,5 @@ const char *path(const char *name)
Patrick Williamsd8c66bc2016-06-20 12:57:21 -0500141 if (!base || !name || name[0] != '/')
142 return name;
143
144- return follow_path(base, name) ?: name;
145+ return follow_path(base, &base, name) ?: name;
146 }