Skip to content

Commit 690dcc6

Browse files
committed
Merge pull request ChainsDD#4 from git-core/master
Fix potential security flaw in creation of sockets/directories
2 parents 233b1d0 + 1fe89ff commit 690dcc6

File tree

3 files changed

+21
-38
lines changed

3 files changed

+21
-38
lines changed

db.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@
2828
sqlite3 *database_init()
2929
{
3030
sqlite3 *db;
31-
int version, rc, databaseStatus = 0;
32-
char *zErrMsg = 0;
31+
int rc;
3332

3433
rc = sqlite3_open_v2(REQUESTOR_DATABASE_PATH, &db, SQLITE_OPEN_READONLY, NULL);
3534
if ( rc ) {
@@ -48,8 +47,7 @@ int database_check(sqlite3 *db, struct su_initiator *from, struct su_request *to
4847
char *zErrmsg;
4948
char **result;
5049
int nrow,ncol;
51-
int allow;
52-
struct timeval tv;
50+
int allow = DB_INTERACTIVE;
5351

5452
sqlite3_snprintf(
5553
sizeof(sql), sql,
@@ -70,7 +68,7 @@ int database_check(sqlite3 *db, struct su_initiator *from, struct su_request *to
7068
}
7169

7270
if (nrow == 0 || ncol != 3)
73-
return DB_INTERACTIVE;
71+
goto out;
7472

7573
if (strcmp(result[0], "_id") == 0 && strcmp(result[2], "allow") == 0) {
7674
if (strcmp(result[5], "1") == 0) {
@@ -80,10 +78,10 @@ int database_check(sqlite3 *db, struct su_initiator *from, struct su_request *to
8078
} else {
8179
allow = DB_DENY;
8280
}
83-
return allow;
8481
}
8582

83+
out:
8684
sqlite3_free_table(result);
8785

88-
return DB_INTERACTIVE;
86+
return allow;
8987
}

su.c

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ static int from_init(struct su_initiator *from)
7171
int fd;
7272
ssize_t len;
7373
int i;
74+
int err;
7475

7576
from->uid = getuid();
7677
from->pid = getppid();
@@ -83,9 +84,10 @@ static int from_init(struct su_initiator *from)
8384
return -1;
8485
}
8586
len = read(fd, args, sizeof(args));
87+
err = errno;
8688
close(fd);
8789
if (len < 0 || len == sizeof(args)) {
88-
PLOGE("Reading command line");
90+
PLOGEV("Reading command line", err);
8991
return -1;
9092
}
9193

@@ -144,10 +146,10 @@ static void cleanup_signal(int sig)
144146
exit(sig);
145147
}
146148

147-
static int socket_create_temp(unsigned req_uid)
149+
static int socket_create_temp(void)
148150
{
149151
static char buf[PATH_MAX];
150-
int fd, err;
152+
int fd;
151153

152154
struct sockaddr_un sun;
153155

@@ -174,18 +176,6 @@ static int socket_create_temp(unsigned req_uid)
174176
}
175177
}
176178

177-
if (chmod(sun.sun_path, 0600) < 0) {
178-
PLOGE("chmod(socket)");
179-
unlink(sun.sun_path);
180-
return -1;
181-
}
182-
183-
if (chown(sun.sun_path, req_uid, req_uid) < 0) {
184-
PLOGE("chown(socket)");
185-
unlink(sun.sun_path);
186-
return -1;
187-
}
188-
189179
if (listen(fd, 1) < 0) {
190180
PLOGE("listen");
191181
return -1;
@@ -222,7 +212,6 @@ static int socket_accept(int serv_fd)
222212
static int socket_receive_result(int serv_fd, char *result, ssize_t result_len)
223213
{
224214
ssize_t len;
225-
char buf[64];
226215

227216
for (;;) {
228217
int fd = socket_accept(serv_fd);
@@ -275,19 +264,19 @@ static void deny(void)
275264
exit(EXIT_FAILURE);
276265
}
277266

278-
static void allow(char *shell)
267+
static void allow(char *shell, mode_t mask)
279268
{
280269
struct su_initiator *from = &su_from;
281270
struct su_request *to = &su_to;
282271
char *exe = NULL;
283272

273+
umask(mask);
284274
send_intent(&su_from, &su_to, "", 1, 1);
285275

286276
if (!strcmp(shell, "")) {
287277
strcpy(shell , "/system/bin/sh");
288278
}
289279
exe = strrchr (shell, '/') + 1;
290-
setgroups(0, NULL);
291280
setresgid(to->uid, to->uid, to->uid);
292281
setresuid(to->uid, to->uid, to->uid);
293282
LOGD("%u %s executing %u %s using shell %s : %s", from->uid, from->bin,
@@ -307,7 +296,7 @@ int main(int argc, char *argv[])
307296
static int socket_serv_fd = -1;
308297
char buf[64], shell[PATH_MAX], *result;
309298
int i, dballow;
310-
unsigned req_uid;
299+
mode_t orig_umask;
311300

312301
for (i = 1; i < argc; i++) {
313302
if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--command")) {
@@ -356,8 +345,10 @@ int main(int argc, char *argv[])
356345
deny();
357346
}
358347

348+
orig_umask = umask(027);
349+
359350
if (su_from.uid == AID_ROOT || su_from.uid == AID_SHELL)
360-
allow(shell);
351+
allow(shell, orig_umask);
361352

362353
if (stat(REQUESTOR_DATA_PATH, &st) < 0) {
363354
PLOGE("stat");
@@ -371,10 +362,8 @@ int main(int argc, char *argv[])
371362
deny();
372363
}
373364

374-
req_uid = st.st_uid;
375-
376-
if (mkdir(REQUESTOR_CACHE_PATH, 0771) >= 0) {
377-
chown(REQUESTOR_CACHE_PATH, req_uid, req_uid);
365+
if (mkdir(REQUESTOR_CACHE_PATH, 0770) >= 0) {
366+
chown(REQUESTOR_CACHE_PATH, st.st_uid, st.st_gid);
378367
}
379368

380369
setgroups(0, NULL);
@@ -400,12 +389,12 @@ int main(int argc, char *argv[])
400389

401390
switch (dballow) {
402391
case DB_DENY: deny();
403-
case DB_ALLOW: allow(shell);
392+
case DB_ALLOW: allow(shell, orig_umask);
404393
case DB_INTERACTIVE: break;
405394
default: deny();
406395
}
407396

408-
socket_serv_fd = socket_create_temp(req_uid);
397+
socket_serv_fd = socket_create_temp();
409398
if (socket_serv_fd < 0) {
410399
deny();
411400
}
@@ -432,7 +421,7 @@ int main(int argc, char *argv[])
432421
if (!strcmp(result, "DENY")) {
433422
deny();
434423
} else if (!strcmp(result, "ALLOW")) {
435-
allow(shell);
424+
allow(shell, orig_umask);
436425
} else {
437426
LOGE("unknown response from Superuser Requestor: %s", result);
438427
deny();

su.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,6 @@
2424
#define REQUESTOR_DATABASES_PATH REQUESTOR_DATA_PATH "/databases"
2525
#define REQUESTOR_DATABASE_PATH REQUESTOR_DATABASES_PATH "/permissions.sqlite"
2626

27-
#define APPS_TABLE_DEFINITION "CREATE TABLE IF NOT EXISTS apps (_id INTEGER, uid INTEGER, package TEXT, name TEXT, exec_uid INTEGER, exec_cmd TEXT, allow INTEGER, PRIMARY KEY (_id), UNIQUE (uid,exec_uid,exec_cmd));"
28-
#define LOGS_TABLE_DEFINITION "CREATE TABLE IF NOT EXISTS logs (_id INTEGER, uid INTEGER, name INTEGER, app_id INTEGER, date INTEGER, type INTEGER, PRIMARY KEY (_id));"
29-
#define PREFS_TABLE_DEFINITION "CREATE TABLE IF NOT EXISTS prefs (_id INTEGER, key TEXT, value TEXT, PRIMARY KEY(_id));"
30-
3127
#define DEFAULT_COMMAND "/system/bin/sh"
3228

3329
#define SOCKET_PATH_TEMPLATE REQUESTOR_CACHE_PATH "/.socketXXXXXX"

0 commit comments

Comments
 (0)