Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d81a53f2 authored by Luke Huang's avatar Luke Huang Committed by android-build-merger
Browse files

Merge "Fix race condition caused by fd reused for DnsResolver" into qt-dev am: 7187dbc4

am: f7e2b55a

Change-Id: Id36255acac9f5c0d7200156eecd11bb15bc624f6
parents 86d3edd1 f7e2b55a
Loading
Loading
Loading
Loading
+17 −2
Original line number Diff line number Diff line
@@ -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;
                });
    }