Skip to content

Commit fb9f063

Browse files
author
git-core
committed
Preliminary fix for security issue reported via private email
This commit will be dropped in the near future. The fix has to be reimplemented. The details of the issue and the reporter info will be published later.
1 parent b9a681d commit fb9f063

File tree

2 files changed

+60
-18
lines changed

2 files changed

+60
-18
lines changed

su.c

Lines changed: 59 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -209,26 +209,53 @@ static int socket_accept(int serv_fd)
209209
return fd;
210210
}
211211

212-
static int socket_receive_result(int serv_fd, char *result, ssize_t result_len)
212+
static int socket_send_request(int fd, struct su_initiator *from, struct su_request *to)
213+
{
214+
size_t len;
215+
size_t bin_size, cmd_size;
216+
217+
#define write_token(fd, data) \
218+
do { \
219+
uint32_t __data = htonl(data); \
220+
size_t __count = sizeof(__data); \
221+
size_t __len = write((fd), &__data, __count); \
222+
if (__len != __count) { \
223+
PLOGE("write(" #data ")"); \
224+
return -1; \
225+
} \
226+
} while (0)
227+
228+
write_token(fd, PROTO_VERSION);
229+
write_token(fd, PATH_MAX);
230+
write_token(fd, ARG_MAX);
231+
write_token(fd, from->uid);
232+
write_token(fd, to->uid);
233+
bin_size = strlen(from->bin) + 1;
234+
write_token(fd, bin_size);
235+
len = write(fd, from->bin, bin_size);
236+
if (len != bin_size) {
237+
PLOGE("write(bin)");
238+
return -1;
239+
}
240+
cmd_size = strlen(to->command) + 1;
241+
write_token(fd, cmd_size);
242+
len = write(fd, to->command, cmd_size);
243+
if (len != cmd_size) {
244+
PLOGE("write(cmd)");
245+
return -1;
246+
}
247+
return 0;
248+
}
249+
250+
static int socket_receive_result(int fd, char *result, ssize_t result_len)
213251
{
214252
ssize_t len;
215253

216-
for (;;) {
217-
int fd = socket_accept(serv_fd);
218-
if (fd < 0)
219-
return -1;
220-
221-
len = read(fd, result, result_len-1);
222-
if (len < 0) {
223-
PLOGE("read(result)");
224-
return -1;
225-
}
226-
227-
if (len > 0) {
228-
break;
229-
}
254+
len = read(fd, result, result_len-1);
255+
if (len < 0) {
256+
PLOGE("read(result)");
257+
return -1;
230258
}
231-
232259
result[len] = '\0';
233260

234261
return 0;
@@ -293,7 +320,7 @@ static void allow(char *shell, mode_t mask)
293320
int main(int argc, char *argv[])
294321
{
295322
struct stat st;
296-
static int socket_serv_fd = -1;
323+
int socket_serv_fd, fd;
297324
char buf[64], shell[PATH_MAX], *result;
298325
int i, dballow;
299326
mode_t orig_umask;
@@ -408,15 +435,29 @@ int main(int argc, char *argv[])
408435
deny();
409436
}
410437

411-
if (socket_receive_result(socket_serv_fd, buf, sizeof(buf)) < 0) {
438+
fd = socket_accept(socket_serv_fd);
439+
if (fd < 0) {
440+
deny();
441+
}
442+
if (socket_send_request(fd, &su_from, &su_to)) {
443+
deny();
444+
}
445+
if (socket_receive_result(fd, buf, sizeof(buf))) {
412446
deny();
413447
}
414448

449+
close(fd);
415450
close(socket_serv_fd);
416451
socket_cleanup();
417452

418453
result = buf;
419454

455+
#define SOCKET_RESPONSE "socket:"
456+
if (strncmp(result, SOCKET_RESPONSE, sizeof(SOCKET_RESPONSE) - 1))
457+
LOGW("SECURITY RISK: Requestor still receives credentials in intent");
458+
else
459+
result += sizeof(SOCKET_RESPONSE) - 1;
460+
420461
if (!strcmp(result, "DENY")) {
421462
deny();
422463
} else if (!strcmp(result, "ALLOW")) {

su.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#define VERSION_CODE 15
3434

3535
#define DATABASE_VERSION 6
36+
#define PROTO_VERSION 0
3637

3738
struct su_initiator {
3839
pid_t pid;

0 commit comments

Comments
 (0)