jdwp: switch to libbase's ReceiveFileDescriptors.
There are some missing checks in the previous use of cmsg(3) to receive
file descriptors, which could result in an fd leak (if we received two
file descriptors, since CMSG_SPACE(4) == CMSG_SPACE(8) on 64-bit).
This isn't actually a real issue, because the other end is trusted to do
the right thing, but switch this over to avoid cargo-cult copy/paste
into places where we don't trust the other side.
Bug: http://b/122047630
Test: treehugger
Change-Id: I53347805b91e5a36c20ab42e6761412270ea6c8e
diff --git a/runtime/jdwp/jdwp_adb.cc b/runtime/jdwp/jdwp_adb.cc
index d64f11f..4fa9984 100644
--- a/runtime/jdwp/jdwp_adb.cc
+++ b/runtime/jdwp/jdwp_adb.cc
@@ -20,7 +20,9 @@
#include <sys/un.h>
#include <unistd.h>
+#include "android-base/cmsg.h"
#include "android-base/stringprintf.h"
+#include "android-base/unique_fd.h"
#include "base/logging.h" // For VLOG.
#include "base/socket_peer_is_trusted.h"
@@ -162,31 +164,8 @@
*/
int JdwpAdbState::ReceiveClientFd() {
char dummy = '!';
- union {
- cmsghdr cm;
- char buffer[CMSG_SPACE(sizeof(int))];
- } cm_un;
-
- iovec iov;
- iov.iov_base = &dummy;
- iov.iov_len = 1;
-
- msghdr msg;
- msg.msg_name = nullptr;
- msg.msg_namelen = 0;
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- msg.msg_flags = 0;
- msg.msg_control = cm_un.buffer;
- msg.msg_controllen = sizeof(cm_un.buffer);
-
- cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
- cmsg->cmsg_len = msg.msg_controllen;
- cmsg->cmsg_level = SOL_SOCKET;
- cmsg->cmsg_type = SCM_RIGHTS;
- (reinterpret_cast<int*>(CMSG_DATA(cmsg)))[0] = -1;
-
- int rc = TEMP_FAILURE_RETRY(recvmsg(ControlSock(), &msg, 0));
+ android::base::unique_fd client_fd;
+ ssize_t rc = android::base::ReceiveFileDescriptors(ControlSock(), &dummy, 1, &client_fd);
if (rc <= 0) {
if (rc == -1) {
@@ -198,7 +177,7 @@
return -1;
}
- return (reinterpret_cast<int*>(CMSG_DATA(cmsg)))[0];
+ return client_fd.release();
}
/*