aboutsummaryrefslogtreecommitdiffstats
path: root/meta/recipes-devtools/pseudo/files/0001-pseudo_has_unload-add-function.patch
blob: b5c81c9d3e0184b62e0b840cb9ca5db03f46e686 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
From be97cb958f2934fa398fc8e344b25b84ebd4e90c Mon Sep 17 00:00:00 2001
From: "Peter A. Bigot" <pab@pabigot.com>
Date: Sun, 25 Aug 2013 19:22:09 -0500
Subject: [PATCH] pseudo_has_unload: add function

Various wrappers checked for a non-null pseudo_get_value("PSEUDO_UNLOAD") to
determine whether the environment should include the pseudo variables.  None
of those checks freed the returned value when it was not null.  The new
check function does.

The new check function also sees whether PSEUDO_UNLOAD was defined in the
environment that should be used in the wrapped system call.  This allows
pkg_postinst scripts to strip out the LD_PRELOAD setting, for example before
invoking qemu to execute commands in an environment that does not have
libpseudo.so.

[YOCTO #4843]

Upstream-Status: Pending
Signed-off-by: Peter A. Bigot <pab@pabigot.com>
---
 ports/common/guts/execv.c              |    2 +-
 ports/common/guts/execve.c             |    2 +-
 ports/common/guts/execvp.c             |    2 +-
 ports/common/guts/fork.c               |    2 +-
 ports/linux/newclone/pseudo_wrappers.c |    2 +-
 ports/linux/oldclone/pseudo_wrappers.c |    2 +-
 ports/unix/guts/popen.c                |    2 +-
 ports/unix/guts/system.c               |    2 +-
 pseudo.h                               |    1 +
 pseudo_util.c                          |   27 +++++++++++++++++++++++++++
 10 files changed, 36 insertions(+), 8 deletions(-)

diff --git a/ports/common/guts/execv.c b/ports/common/guts/execv.c
index 763e1f9..3e1f820 100644
--- a/ports/common/guts/execv.c
+++ b/ports/common/guts/execv.c
@@ -19,7 +19,7 @@
 	}
 
 	pseudo_setupenv();
-	if (pseudo_get_value("PSEUDO_UNLOAD"))
+	if (pseudo_has_unload(NULL))
 		pseudo_dropenv();
 
 	/* if exec() fails, we may end up taking signals unexpectedly...
diff --git a/ports/common/guts/execve.c b/ports/common/guts/execve.c
index a003657..ff6a44e 100644
--- a/ports/common/guts/execve.c
+++ b/ports/common/guts/execve.c
@@ -20,7 +20,7 @@
         }
 
 	new_environ = pseudo_setupenvp(envp);
-	if (pseudo_get_value("PSEUDO_UNLOAD"))
+	if (pseudo_has_unload(new_environ))
 		new_environ = pseudo_dropenvp(new_environ);
 
 	/* if exec() fails, we may end up taking signals unexpectedly...
diff --git a/ports/common/guts/execvp.c b/ports/common/guts/execvp.c
index 5e75be7..04253c3 100644
--- a/ports/common/guts/execvp.c
+++ b/ports/common/guts/execvp.c
@@ -20,7 +20,7 @@
         }
 
 	pseudo_setupenv();
-	if (pseudo_get_value("PSEUDO_UNLOAD"))
+	if (pseudo_has_unload(NULL))
 		pseudo_dropenv();
 
 	/* if exec() fails, we may end up taking signals unexpectedly...
diff --git a/ports/common/guts/fork.c b/ports/common/guts/fork.c
index df8abd7..bebe3b0 100644
--- a/ports/common/guts/fork.c
+++ b/ports/common/guts/fork.c
@@ -12,7 +12,7 @@
 	 */
 	if (rc == 0) {
 		pseudo_setupenv();
-		if (!pseudo_get_value("PSEUDO_UNLOAD")) {
+		if (!pseudo_has_unload(NULL)) {
 			pseudo_reinit_libpseudo();
 		} else {
 			pseudo_dropenv();
diff --git a/ports/linux/newclone/pseudo_wrappers.c b/ports/linux/newclone/pseudo_wrappers.c
index 9dbac42..257e8bb 100644
--- a/ports/linux/newclone/pseudo_wrappers.c
+++ b/ports/linux/newclone/pseudo_wrappers.c
@@ -28,7 +28,7 @@ int wrap_clone_child(void *args) {
 
 	if (!(flags & CLONE_VM)) {
 		pseudo_setupenv();
-		if (!pseudo_get_value("PSEUDO_UNLOAD")) {
+		if (!pseudo_has_unload(NULL)) {
 			pseudo_reinit_libpseudo();
 		} else {
 			pseudo_dropenv();
diff --git a/ports/linux/oldclone/pseudo_wrappers.c b/ports/linux/oldclone/pseudo_wrappers.c
index c0ce5dd..598d966 100644
--- a/ports/linux/oldclone/pseudo_wrappers.c
+++ b/ports/linux/oldclone/pseudo_wrappers.c
@@ -22,7 +22,7 @@ int wrap_clone_child(void *args) {
 
 	if (!(flags & CLONE_VM)) {
 		pseudo_setupenv();
-		if (!pseudo_get_value("PSEUDO_UNLOAD")) {
+		if (!pseudo_has_unload(NULL)) {
 			pseudo_reinit_libpseudo();
 		} else {
 			pseudo_dropenv();
diff --git a/ports/unix/guts/popen.c b/ports/unix/guts/popen.c
index 0ca16b0..5d44c0e 100644
--- a/ports/unix/guts/popen.c
+++ b/ports/unix/guts/popen.c
@@ -9,7 +9,7 @@
 	 * in ways that avoid our usual enforcement of the environment.
 	 */
 	pseudo_setupenv();
-	if (pseudo_get_value("PSEUDO_UNLOAD"))
+	if (pseudo_has_unload(NULL))
 		pseudo_dropenv();
 
 	rc = real_popen(command, mode);
diff --git a/ports/unix/guts/system.c b/ports/unix/guts/system.c
index 028b372..6351592 100644
--- a/ports/unix/guts/system.c
+++ b/ports/unix/guts/system.c
@@ -9,7 +9,7 @@
 		return 1;
 
 	pseudo_setupenv();
-	if (pseudo_get_value("PSEUDO_UNLOAD"))
+	if (pseudo_has_unload(NULL))
 		pseudo_dropenv();
 
 	rc = real_system(command);
diff --git a/pseudo.h b/pseudo.h
index 56760a4..f600793 100644
--- a/pseudo.h
+++ b/pseudo.h
@@ -28,6 +28,7 @@ extern void pseudo_init_client(void);
 void pseudo_dump_env(char **envp);
 int pseudo_set_value(const char *key, const char *value);
 char *pseudo_get_value(const char *key);
+int pseudo_has_unload(char * const *envp);
 
 #include "pseudo_tables.h"
 
diff --git a/pseudo_util.c b/pseudo_util.c
index 8d0969e..16c70e0 100644
--- a/pseudo_util.c
+++ b/pseudo_util.c
@@ -95,6 +95,33 @@ dump_env(char **envp) {
 }
 #endif
 
+int
+pseudo_has_unload(char * const *envp) {
+	static const char unload[] = "PSEUDO_UNLOAD";
+	static size_t unload_len = strlen(unload);
+	size_t i = 0;
+
+	/* Is it in the caller environment? */
+	if (NULL != getenv(unload))
+		return 1;
+
+	/* Is it in the environment cache? */
+	if (pseudo_util_initted == -1)
+		pseudo_init_util();
+	while (pseudo_env[i].key && strcmp(pseudo_env[i].key, unload))
+	       ++i;
+	if (pseudo_env[i].key && pseudo_env[i].value)
+		return 1;
+
+	/* Is it in the operational environment? */
+	while (envp && *envp) {
+		if ((!strncmp(*envp, unload, unload_len)) && ('=' == (*envp)[unload_len]))
+			return 1;
+		++envp;
+	}
+	return 0;
+}
+
 /* Caller must free memory! */
 char *
 pseudo_get_value(const char *key) {
-- 
1.7.9.5