Merge branch 'dev/11/fp3/security-aosp-rvc-release' into int/11/fp3

* dev/11/fp3/security-aosp-rvc-release:
  Fix Heap-use-after-free in MDnsSdListener::Monitor::run

Change-Id: Ibdf9e58199410637bd19233398cf664da39f3b1a
diff --git a/server/MDnsSdListener.cpp b/server/MDnsSdListener.cpp
index 42dcddf..d551d37 100644
--- a/server/MDnsSdListener.cpp
+++ b/server/MDnsSdListener.cpp
@@ -29,6 +29,7 @@
 #include <sys/poll.h>
 #include <sys/socket.h>
 #include <sys/types.h>
+#include <thread>
 
 #define LOG_TAG "MDnsDS"
 #define DBG 1
@@ -527,12 +528,18 @@
     mPollSize = 10;
     socketpair(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0, mCtrlSocketPair);
 
-    const int rval = ::android::netdutils::threadLaunch(this);
-    if (rval != 0) {
-        ALOGW("Error spawning monitor thread: %s (%d)", strerror(-rval), -rval);
-    }
+    mRescanThread = new std::thread(&Monitor::run, this);
+    if (!mRescanThread->joinable()) ALOGE("Unable to launch thread.");
 }
 
+MDnsSdListener::Monitor::~Monitor() {
+    if (VDBG) ALOGD("Monitor recycling");
+    close(mCtrlSocketPair[1]);  // interrupt poll in MDnsSdListener::Monitor::run() and revent will
+                                // be 17 = POLLIN | POLLHUP
+    mRescanThread->join();
+    delete mRescanThread;
+    if (VDBG) ALOGD("Monitor recycled");
+}
 #define NAP_TIME 200  // 200 ms between polls
 static int wait_for_property(const char *name, const char *desired_value, int maxwait)
 {
@@ -611,14 +618,18 @@
                 }
             }
             if (VDBG) ALOGD("controlSocket shows revent= %d", mPollFds[0].revents);
-            switch (mPollFds[0].revents) {
-                case POLLIN: {
-                    char readBuf[2];
-                    read(mCtrlSocketPair[0], &readBuf, 1);
-                    if (DBG) ALOGD("MDnsSdListener::Monitor got %c", readBuf[0]);
-                    if (memcmp(RESCAN, readBuf, 1) == 0) {
-                        pollCount = rescan();
-                    }
+            if (mPollFds[0].revents & POLLHUP) {
+                free(mPollFds);
+                free(mPollRefs);
+                if (VDBG) ALOGD("Monitor thread leaving.");
+                return;
+            }
+            if (mPollFds[0].revents == POLLIN) {
+                char readBuf[2];
+                read(mCtrlSocketPair[0], &readBuf, 1);
+                if (DBG) ALOGD("MDnsSdListener::Monitor got %c", readBuf[0]);
+                if (memcmp(RESCAN, readBuf, 1) == 0) {
+                    pollCount = rescan();
                 }
             }
             mPollFds[0].revents = 0;
diff --git a/server/MDnsSdListener.h b/server/MDnsSdListener.h
index 83cf23e..196419b 100644
--- a/server/MDnsSdListener.h
+++ b/server/MDnsSdListener.h
@@ -22,6 +22,7 @@
 #include <sysutils/FrameworkListener.h>
 #include <mutex>
 #include <string>
+#include <thread>
 
 #include "NetdCommand.h"
 
@@ -71,7 +72,7 @@
     class Monitor {
     public:
         Monitor();
-        virtual ~Monitor() {}
+        ~Monitor();
         DNSServiceRef *allocateServiceRef(int id, Context *c);
         void startMonitoring(int id);
         DNSServiceRef *lookupServiceRef(int id);
@@ -102,6 +103,7 @@
         int mPollSize;
         int mCtrlSocketPair[2];
         std::mutex mMutex;
+        std::thread* mRescanThread;
     };
 
     class Handler : public NetdCommand {