Fix file descriptor leakage in adbd

adb_auth_init in adb_auth_client.cpp sets FD_CLOEXEC on the control
socket, which prevents the leakage. However if ro.adb.secure
property is unset (as it is on the emulator), adb_auth_init is not
invoked, which results in the control socket fd leaking into any
process started by the deamon (specifically, any command executed
through adb shell).

Split the fd cleanup into a separate function that is called
unconditionally.

Change-Id: I73ea84977542ddfc4ac20599593ecf3745ae9108
This commit is contained in:
Pavel Labath 2015-03-17 11:03:36 -07:00 committed by Dan Albert
parent 928cbdd2c3
commit 64d9adcea8
3 changed files with 20 additions and 10 deletions

View File

@ -23,7 +23,6 @@ extern "C" {
extern int auth_enabled;
void adb_auth_init(void);
int adb_auth_keygen(const char* filename);
void adb_auth_verified(atransport *t);
@ -40,6 +39,7 @@ void send_auth_publickey(atransport *t);
#if ADB_HOST
void adb_auth_init(void);
int adb_auth_sign(void *key, const unsigned char* token, size_t token_size,
unsigned char* sig);
void *adb_auth_nextkey(void *current);
@ -58,6 +58,8 @@ static inline int adb_auth_sign(void* key, const unsigned char* token,
static inline void *adb_auth_nextkey(void *current) { return NULL; }
static inline int adb_auth_get_userkey(unsigned char *data, size_t len) { return 0; }
void adbd_auth_init(void);
void adbd_cloexec_auth_socket();
int adb_auth_generate_token(void *token, size_t token_size);
int adb_auth_verify(uint8_t* token, uint8_t* sig, int siglen);
void adb_auth_confirm_key(unsigned char *data, size_t len, atransport *t);

View File

@ -249,19 +249,23 @@ static void adb_auth_listener(int fd, unsigned events, void *data)
}
}
void adb_auth_init(void)
{
int fd, ret;
fd = android_get_control_socket("adbd");
if (fd < 0) {
void adbd_cloexec_auth_socket() {
int fd = android_get_control_socket("adbd");
if (fd == -1) {
D("Failed to get adbd socket\n");
return;
}
fcntl(fd, F_SETFD, FD_CLOEXEC);
}
ret = listen(fd, 4);
if (ret < 0) {
void adbd_auth_init(void) {
int fd = android_get_control_socket("adbd");
if (fd == -1) {
D("Failed to get adbd socket\n");
return;
}
if (listen(fd, 4) == -1) {
D("Failed to listen on '%d'\n", fd);
return;
}

View File

@ -273,10 +273,14 @@ int adb_main(int is_daemon, int server_port)
exit(1);
}
#else
// We need to call this even if auth isn't enabled because the file
// descriptor will always be open.
adbd_cloexec_auth_socket();
property_get("ro.adb.secure", value, "0");
auth_enabled = !strcmp(value, "1");
if (auth_enabled)
adb_auth_init();
adbd_auth_init();
// Our external storage path may be different than apps, since
// we aren't able to bind mount after dropping root.