Skip to content

Commit e0329ce

Browse files
author
git-core
committed
Inherit the environment of the caller process for a new process image
1 parent 070fc98 commit e0329ce

File tree

2 files changed

+37
-2
lines changed

2 files changed

+37
-2
lines changed

su.c

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ static struct su_initiator su_from = {
5757
.uid = 0,
5858
.bin = "",
5959
.args = "",
60+
.env = "",
61+
.envp = { NULL, },
6062
};
6163

6264
static struct su_request su_to = {
@@ -72,6 +74,7 @@ static int from_init(struct su_initiator *from)
7274
ssize_t len;
7375
int i;
7476
int err;
77+
size_t j;
7578

7679
from->uid = getuid();
7780
from->pid = getppid();
@@ -126,6 +129,30 @@ static int from_init(struct su_initiator *from)
126129
strncpy(from->bin, argv0, sizeof(from->bin));
127130
from->bin[sizeof(from->bin)-1] = '\0';
128131

132+
/* Get the environment of the calling process */
133+
snprintf(path, sizeof(path), "/proc/%u/environ", from->pid);
134+
fd = open(path, O_RDONLY);
135+
if (fd < 0) {
136+
PLOGE("Opening environment");
137+
goto out;
138+
}
139+
len = read(fd, from->env, sizeof(from->env));
140+
close(fd);
141+
if (len < 0 || len == sizeof(from->env)) {
142+
PLOGE("Reading environment");
143+
goto out;
144+
}
145+
from->env[len] = '\0';
146+
147+
from->envp[0] = &from->env[0];
148+
for (i = 0, j = 0; i < len && j < ARRAY_SIZE(from->envp); i++) {
149+
if (from->env[i] == '\0') {
150+
from->envp[++j] = &from->env[i + 1];
151+
}
152+
}
153+
from->envp[j] = NULL;
154+
155+
out:
129156
return 0;
130157
}
131158

@@ -269,6 +296,7 @@ static void allow(char *shell, mode_t mask)
269296
struct su_initiator *from = &su_from;
270297
struct su_request *to = &su_to;
271298
char *exe = NULL;
299+
char **envp = environ;
272300

273301
umask(mask);
274302
send_intent(&su_from, &su_to, "", 1, 1);
@@ -277,14 +305,17 @@ static void allow(char *shell, mode_t mask)
277305
strcpy(shell , "/system/bin/sh");
278306
}
279307
exe = strrchr (shell, '/') + 1;
308+
if (from->envp[0]) {
309+
envp = from->envp;
310+
}
280311
setresgid(to->uid, to->uid, to->uid);
281312
setresuid(to->uid, to->uid, to->uid);
282313
LOGD("%u %s executing %u %s using shell %s : %s", from->uid, from->bin,
283314
to->uid, to->command, shell, exe);
284315
if (strcmp(to->command, DEFAULT_COMMAND)) {
285-
execl(shell, exe, "-c", to->command, (char*)NULL);
316+
execle(shell, exe, "-c", to->command, (char*)NULL, envp);
286317
} else {
287-
execl(shell, exe, "-", (char*)NULL);
318+
execle(shell, exe, "-", (char*)NULL, envp);
288319
}
289320
PLOGE("exec");
290321
exit(EXIT_SUCCESS);

su.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ struct su_initiator {
3838
unsigned uid;
3939
char bin[PATH_MAX];
4040
char args[4096];
41+
char env[ARG_MAX];
42+
char *envp[512];
4143
};
4244

4345
struct su_request {
@@ -65,4 +67,6 @@ extern int send_intent(struct su_initiator *from, struct su_request *to, const c
6567
#define PLOGE(fmt,args...) LOGE(fmt " failed with %d: %s" , ## args , errno, strerror(errno))
6668
#define PLOGEV(fmt,err,args...) LOGE(fmt " failed with %d: %s" , ## args , err, strerror(err))
6769

70+
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
71+
6872
#endif

0 commit comments

Comments
 (0)