diff options
| author | 2019-06-11 15:32:17 +0000 | |
|---|---|---|
| committer | 2019-06-11 15:32:17 +0000 | |
| commit | 3f2aa4190dbe2e4779110e47e47df90e4e4992cb (patch) | |
| tree | a43299302be5174c2500f6329ef509f0dcf1c53c | |
| parent | 882558700b08089d02da92a70ff101fd7957e07d (diff) | |
| parent | 5b31126c9dc414cf6bc2b5a20988f2ef4132f6b1 (diff) | |
Merge "Fix race condition caused by fd reused for DnsResolver"
| -rw-r--r-- | core/java/android/net/DnsResolver.java | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/core/java/android/net/DnsResolver.java b/core/java/android/net/DnsResolver.java index 7a85dcbfc830..0b1a84534e38 100644 --- a/core/java/android/net/DnsResolver.java +++ b/core/java/android/net/DnsResolver.java @@ -34,6 +34,7 @@ import android.annotation.NonNull; import android.annotation.Nullable; import android.os.CancellationSignal; import android.os.Looper; +import android.os.MessageQueue; import android.system.ErrnoException; import android.util.Log; @@ -466,10 +467,20 @@ public final class DnsResolver { private void registerFDListener(@NonNull Executor executor, @NonNull FileDescriptor queryfd, @NonNull Callback<? super byte[]> answerCallback, @Nullable CancellationSignal cancellationSignal, @NonNull Object lock) { - Looper.getMainLooper().getQueue().addOnFileDescriptorEventListener( + final MessageQueue mainThreadMessageQueue = Looper.getMainLooper().getQueue(); + mainThreadMessageQueue.addOnFileDescriptorEventListener( queryfd, FD_EVENTS, (fd, events) -> { + // b/134310704 + // Unregister fd event listener before resNetworkResult is called to prevent + // race condition caused by fd reused. + // For example when querying v4 and v6, it's possible that the first query ends + // and the fd is closed before the second request starts, which might return + // the same fd for the second request. By that time, the looper must have + // unregistered the fd, otherwise another event listener can't be registered. + mainThreadMessageQueue.removeOnFileDescriptorEventListener(fd); + executor.execute(() -> { DnsResponse resp = null; ErrnoException exception = null; @@ -490,7 +501,11 @@ public final class DnsResolver { } answerCallback.onAnswer(resp.answerbuf, resp.rcode); }); - // Unregister this fd listener + + // The file descriptor has already been unregistered, so it does not really + // matter what is returned here. In spirit 0 (meaning "unregister this FD") + // is still the closest to what the looper needs to do. When returning 0, + // Looper knows to ignore the fd if it has already been unregistered. return 0; }); } |