diff options
| author | Luke Huang <huangluke@google.com> | 2019-06-11 08:52:18 -0700 |
|---|---|---|
| committer | android-build-merger <android-build-merger@google.com> | 2019-06-11 08:52:18 -0700 |
| commit | cc949037c3cc041ad7f374765b435b7d2d2eee6e (patch) | |
| tree | e4561f4f6a2b20783eddca8e9e4ae9accd7e5020 /core/java | |
| parent | 95376bb829679b70dae393b75f60ec8352c3a101 (diff) | |
| parent | f8a2c15ca1118e1cd70e33481e1d6275b22117ed (diff) | |
Merge "Fix race condition caused by fd reused for DnsResolver" am: 3f2aa4190d
am: f8a2c15ca1
Change-Id: I93e0d4a8664a16f2814763346ff00e6c874efd02
Diffstat (limited to 'core/java')
| -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; }); } |
