diff options
author | Peter A. Bigot <pab@pabigot.com> | 2013-08-25 19:40:06 -0500 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2013-09-06 23:03:20 +0100 |
commit | eb34e8d8cee816dc64ad7ffc0eaa8cdc9a04d5eb (patch) | |
tree | 81a50112cae25f4fe7d2908149f624f861c79b46 /meta/recipes-devtools/pseudo/files | |
parent | 3dccd57360894d0e401285fc636413d85edbe62d (diff) | |
download | poky-eb34e8d8cee816dc64ad7ffc0eaa8cdc9a04d5eb.tar.gz |
pseudo: fix memory leak and missed privilege drop
qemu.bbclass adds PSEUDO_UNLOAD=1 in qemu_run_binary to avoid reference to
pseudo functions that may not exist in the target environment. This patch
detects the addition of that variable within the environment to which the
call applies, even if not present in the parent environment.
As a side effect it fixes a memory leak.
[YOCTO #4843]
(From OE-Core rev: 9ea32ef507c914f906b3dcc0bb29813a4e0dacba)
Signed-off-by: Peter A. Bigot <pab@pabigot.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-devtools/pseudo/files')
-rw-r--r-- | meta/recipes-devtools/pseudo/files/0001-pseudo_has_unload-add-function.patch | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/meta/recipes-devtools/pseudo/files/0001-pseudo_has_unload-add-function.patch b/meta/recipes-devtools/pseudo/files/0001-pseudo_has_unload-add-function.patch new file mode 100644 index 0000000000..b5c81c9d3e --- /dev/null +++ b/meta/recipes-devtools/pseudo/files/0001-pseudo_has_unload-add-function.patch | |||
@@ -0,0 +1,190 @@ | |||
1 | From be97cb958f2934fa398fc8e344b25b84ebd4e90c Mon Sep 17 00:00:00 2001 | ||
2 | From: "Peter A. Bigot" <pab@pabigot.com> | ||
3 | Date: Sun, 25 Aug 2013 19:22:09 -0500 | ||
4 | Subject: [PATCH] pseudo_has_unload: add function | ||
5 | |||
6 | Various wrappers checked for a non-null pseudo_get_value("PSEUDO_UNLOAD") to | ||
7 | determine whether the environment should include the pseudo variables. None | ||
8 | of those checks freed the returned value when it was not null. The new | ||
9 | check function does. | ||
10 | |||
11 | The new check function also sees whether PSEUDO_UNLOAD was defined in the | ||
12 | environment that should be used in the wrapped system call. This allows | ||
13 | pkg_postinst scripts to strip out the LD_PRELOAD setting, for example before | ||
14 | invoking qemu to execute commands in an environment that does not have | ||
15 | libpseudo.so. | ||
16 | |||
17 | [YOCTO #4843] | ||
18 | |||
19 | Upstream-Status: Pending | ||
20 | Signed-off-by: Peter A. Bigot <pab@pabigot.com> | ||
21 | --- | ||
22 | ports/common/guts/execv.c | 2 +- | ||
23 | ports/common/guts/execve.c | 2 +- | ||
24 | ports/common/guts/execvp.c | 2 +- | ||
25 | ports/common/guts/fork.c | 2 +- | ||
26 | ports/linux/newclone/pseudo_wrappers.c | 2 +- | ||
27 | ports/linux/oldclone/pseudo_wrappers.c | 2 +- | ||
28 | ports/unix/guts/popen.c | 2 +- | ||
29 | ports/unix/guts/system.c | 2 +- | ||
30 | pseudo.h | 1 + | ||
31 | pseudo_util.c | 27 +++++++++++++++++++++++++++ | ||
32 | 10 files changed, 36 insertions(+), 8 deletions(-) | ||
33 | |||
34 | diff --git a/ports/common/guts/execv.c b/ports/common/guts/execv.c | ||
35 | index 763e1f9..3e1f820 100644 | ||
36 | --- a/ports/common/guts/execv.c | ||
37 | +++ b/ports/common/guts/execv.c | ||
38 | @@ -19,7 +19,7 @@ | ||
39 | } | ||
40 | |||
41 | pseudo_setupenv(); | ||
42 | - if (pseudo_get_value("PSEUDO_UNLOAD")) | ||
43 | + if (pseudo_has_unload(NULL)) | ||
44 | pseudo_dropenv(); | ||
45 | |||
46 | /* if exec() fails, we may end up taking signals unexpectedly... | ||
47 | diff --git a/ports/common/guts/execve.c b/ports/common/guts/execve.c | ||
48 | index a003657..ff6a44e 100644 | ||
49 | --- a/ports/common/guts/execve.c | ||
50 | +++ b/ports/common/guts/execve.c | ||
51 | @@ -20,7 +20,7 @@ | ||
52 | } | ||
53 | |||
54 | new_environ = pseudo_setupenvp(envp); | ||
55 | - if (pseudo_get_value("PSEUDO_UNLOAD")) | ||
56 | + if (pseudo_has_unload(new_environ)) | ||
57 | new_environ = pseudo_dropenvp(new_environ); | ||
58 | |||
59 | /* if exec() fails, we may end up taking signals unexpectedly... | ||
60 | diff --git a/ports/common/guts/execvp.c b/ports/common/guts/execvp.c | ||
61 | index 5e75be7..04253c3 100644 | ||
62 | --- a/ports/common/guts/execvp.c | ||
63 | +++ b/ports/common/guts/execvp.c | ||
64 | @@ -20,7 +20,7 @@ | ||
65 | } | ||
66 | |||
67 | pseudo_setupenv(); | ||
68 | - if (pseudo_get_value("PSEUDO_UNLOAD")) | ||
69 | + if (pseudo_has_unload(NULL)) | ||
70 | pseudo_dropenv(); | ||
71 | |||
72 | /* if exec() fails, we may end up taking signals unexpectedly... | ||
73 | diff --git a/ports/common/guts/fork.c b/ports/common/guts/fork.c | ||
74 | index df8abd7..bebe3b0 100644 | ||
75 | --- a/ports/common/guts/fork.c | ||
76 | +++ b/ports/common/guts/fork.c | ||
77 | @@ -12,7 +12,7 @@ | ||
78 | */ | ||
79 | if (rc == 0) { | ||
80 | pseudo_setupenv(); | ||
81 | - if (!pseudo_get_value("PSEUDO_UNLOAD")) { | ||
82 | + if (!pseudo_has_unload(NULL)) { | ||
83 | pseudo_reinit_libpseudo(); | ||
84 | } else { | ||
85 | pseudo_dropenv(); | ||
86 | diff --git a/ports/linux/newclone/pseudo_wrappers.c b/ports/linux/newclone/pseudo_wrappers.c | ||
87 | index 9dbac42..257e8bb 100644 | ||
88 | --- a/ports/linux/newclone/pseudo_wrappers.c | ||
89 | +++ b/ports/linux/newclone/pseudo_wrappers.c | ||
90 | @@ -28,7 +28,7 @@ int wrap_clone_child(void *args) { | ||
91 | |||
92 | if (!(flags & CLONE_VM)) { | ||
93 | pseudo_setupenv(); | ||
94 | - if (!pseudo_get_value("PSEUDO_UNLOAD")) { | ||
95 | + if (!pseudo_has_unload(NULL)) { | ||
96 | pseudo_reinit_libpseudo(); | ||
97 | } else { | ||
98 | pseudo_dropenv(); | ||
99 | diff --git a/ports/linux/oldclone/pseudo_wrappers.c b/ports/linux/oldclone/pseudo_wrappers.c | ||
100 | index c0ce5dd..598d966 100644 | ||
101 | --- a/ports/linux/oldclone/pseudo_wrappers.c | ||
102 | +++ b/ports/linux/oldclone/pseudo_wrappers.c | ||
103 | @@ -22,7 +22,7 @@ int wrap_clone_child(void *args) { | ||
104 | |||
105 | if (!(flags & CLONE_VM)) { | ||
106 | pseudo_setupenv(); | ||
107 | - if (!pseudo_get_value("PSEUDO_UNLOAD")) { | ||
108 | + if (!pseudo_has_unload(NULL)) { | ||
109 | pseudo_reinit_libpseudo(); | ||
110 | } else { | ||
111 | pseudo_dropenv(); | ||
112 | diff --git a/ports/unix/guts/popen.c b/ports/unix/guts/popen.c | ||
113 | index 0ca16b0..5d44c0e 100644 | ||
114 | --- a/ports/unix/guts/popen.c | ||
115 | +++ b/ports/unix/guts/popen.c | ||
116 | @@ -9,7 +9,7 @@ | ||
117 | * in ways that avoid our usual enforcement of the environment. | ||
118 | */ | ||
119 | pseudo_setupenv(); | ||
120 | - if (pseudo_get_value("PSEUDO_UNLOAD")) | ||
121 | + if (pseudo_has_unload(NULL)) | ||
122 | pseudo_dropenv(); | ||
123 | |||
124 | rc = real_popen(command, mode); | ||
125 | diff --git a/ports/unix/guts/system.c b/ports/unix/guts/system.c | ||
126 | index 028b372..6351592 100644 | ||
127 | --- a/ports/unix/guts/system.c | ||
128 | +++ b/ports/unix/guts/system.c | ||
129 | @@ -9,7 +9,7 @@ | ||
130 | return 1; | ||
131 | |||
132 | pseudo_setupenv(); | ||
133 | - if (pseudo_get_value("PSEUDO_UNLOAD")) | ||
134 | + if (pseudo_has_unload(NULL)) | ||
135 | pseudo_dropenv(); | ||
136 | |||
137 | rc = real_system(command); | ||
138 | diff --git a/pseudo.h b/pseudo.h | ||
139 | index 56760a4..f600793 100644 | ||
140 | --- a/pseudo.h | ||
141 | +++ b/pseudo.h | ||
142 | @@ -28,6 +28,7 @@ extern void pseudo_init_client(void); | ||
143 | void pseudo_dump_env(char **envp); | ||
144 | int pseudo_set_value(const char *key, const char *value); | ||
145 | char *pseudo_get_value(const char *key); | ||
146 | +int pseudo_has_unload(char * const *envp); | ||
147 | |||
148 | #include "pseudo_tables.h" | ||
149 | |||
150 | diff --git a/pseudo_util.c b/pseudo_util.c | ||
151 | index 8d0969e..16c70e0 100644 | ||
152 | --- a/pseudo_util.c | ||
153 | +++ b/pseudo_util.c | ||
154 | @@ -95,6 +95,33 @@ dump_env(char **envp) { | ||
155 | } | ||
156 | #endif | ||
157 | |||
158 | +int | ||
159 | +pseudo_has_unload(char * const *envp) { | ||
160 | + static const char unload[] = "PSEUDO_UNLOAD"; | ||
161 | + static size_t unload_len = strlen(unload); | ||
162 | + size_t i = 0; | ||
163 | + | ||
164 | + /* Is it in the caller environment? */ | ||
165 | + if (NULL != getenv(unload)) | ||
166 | + return 1; | ||
167 | + | ||
168 | + /* Is it in the environment cache? */ | ||
169 | + if (pseudo_util_initted == -1) | ||
170 | + pseudo_init_util(); | ||
171 | + while (pseudo_env[i].key && strcmp(pseudo_env[i].key, unload)) | ||
172 | + ++i; | ||
173 | + if (pseudo_env[i].key && pseudo_env[i].value) | ||
174 | + return 1; | ||
175 | + | ||
176 | + /* Is it in the operational environment? */ | ||
177 | + while (envp && *envp) { | ||
178 | + if ((!strncmp(*envp, unload, unload_len)) && ('=' == (*envp)[unload_len])) | ||
179 | + return 1; | ||
180 | + ++envp; | ||
181 | + } | ||
182 | + return 0; | ||
183 | +} | ||
184 | + | ||
185 | /* Caller must free memory! */ | ||
186 | char * | ||
187 | pseudo_get_value(const char *key) { | ||
188 | -- | ||
189 | 1.7.9.5 | ||
190 | |||