[tor-bugs] #32194 [Metrics/Library]: NetworkStatusEntryImpl#parseSLine (and probably other methods) is not thread-safe

Tor Bug Tracker & Wiki blackhole at torproject.org
Tue Oct 22 16:10:06 UTC 2019


#32194: NetworkStatusEntryImpl#parseSLine (and probably other methods) is not
thread-safe
---------------------------------+--------------------------
     Reporter:  karsten          |      Owner:  metrics-team
         Type:  defect           |     Status:  new
     Priority:  High             |  Milestone:
    Component:  Metrics/Library  |    Version:
     Severity:  Normal           |   Keywords:
Actual Points:                   |  Parent ID:
       Points:                   |   Reviewer:
      Sponsor:                   |
---------------------------------+--------------------------
 Turns out that creating multiple `DescriptorReader` instances in separate
 threads can cause thread-safety issues in
 `NetworkStatusEntryImpl#parseSLine`:

 {{{
 18:02:24.650 [Thread-1] INFO
 org.torproject.descriptor.DescriptorSourceFactory - Serving implementation
 org.torproject.descriptor.impl.DescriptorReaderImpl for descriptor.reader.
 18:02:24.650 [Thread-5] INFO
 org.torproject.descriptor.DescriptorSourceFactory - Serving implementation
 org.torproject.descriptor.impl.DescriptorReaderImpl for descriptor.reader.
 18:02:24.650 [Thread-3] INFO
 org.torproject.descriptor.DescriptorSourceFactory - Serving implementation
 org.torproject.descriptor.impl.DescriptorReaderImpl for descriptor.reader.
 18:02:24.947 [Thread-10] ERROR
 org.torproject.descriptor.impl.DescriptorReaderImpl - Bug: uncaught
 exception or error while reading descriptors.
 java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
         at
 org.torproject.descriptor.impl.DescriptorParserImpl.parseOneDescriptor(DescriptorParserImpl.java:236)
         at
 org.torproject.descriptor.impl.DescriptorParserImpl.parseOneOrMoreDescriptors(DescriptorParserImpl.java:213)
         at
 org.torproject.descriptor.impl.DescriptorParserImpl.detectTypeAndParseDescriptors(DescriptorParserImpl.java:61)
         at
 org.torproject.descriptor.impl.DescriptorParserImpl.parseDescriptors(DescriptorParserImpl.java:33)
         at
 org.torproject.descriptor.impl.DescriptorReaderImpl$DescriptorReaderRunnable.readTarball(DescriptorReaderImpl.java:320)
         at
 org.torproject.descriptor.impl.DescriptorReaderImpl$DescriptorReaderRunnable.readTarballs(DescriptorReaderImpl.java:270)
         at
 org.torproject.descriptor.impl.DescriptorReaderImpl$DescriptorReaderRunnable.run(DescriptorReaderImpl.java:161)
         at java.lang.Thread.run(Thread.java:745)
 Caused by: java.lang.reflect.InvocationTargetException: null
         at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native
 Method)
         at
 sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
         at
 sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
         at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
         at
 org.torproject.descriptor.impl.DescriptorParserImpl.parseOneDescriptor(DescriptorParserImpl.java:229)
         ... 7 common frames omitted
 Caused by: java.lang.NullPointerException: null
         at
 org.torproject.descriptor.impl.NetworkStatusEntryImpl.parseSLine(NetworkStatusEntryImpl.java:177)
         at
 org.torproject.descriptor.impl.NetworkStatusEntryImpl.parseStatusEntryBytes(NetworkStatusEntryImpl.java:98)
         at
 org.torproject.descriptor.impl.NetworkStatusEntryImpl.<init>(NetworkStatusEntryImpl.java:58)
         at
 org.torproject.descriptor.impl.RelayNetworkStatusConsensusImpl.parseStatusEntry(RelayNetworkStatusConsensusImpl.java:121)
         at
 org.torproject.descriptor.impl.NetworkStatusImpl.parseStatusEntries(NetworkStatusImpl.java:85)
         at
 org.torproject.descriptor.impl.NetworkStatusImpl.splitAndParseParts(NetworkStatusImpl.java:59)
         at
 org.torproject.descriptor.impl.NetworkStatusImpl.<init>(NetworkStatusImpl.java:27)
         at
 org.torproject.descriptor.impl.RelayNetworkStatusConsensusImpl.<init>(RelayNetworkStatusConsensusImpl.java:28)
         ... 12 common frames omitted
 18:02:24.948 [Thread-1] INFO
 org.torproject.descriptor.DescriptorSourceFactory - Serving implementation
 org.torproject.descriptor.impl.DescriptorReaderImpl for descriptor.reader.
 }}}

 Code to reproduce this in 1 out of 10 cases:

 {{{
 import org.torproject.descriptor.Descriptor;
 import org.torproject.descriptor.DescriptorSourceFactory;
 import org.torproject.descriptor.RelayNetworkStatusConsensus;

 import java.io.File;
 import java.util.SortedSet;
 import java.util.TreeSet;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;

 public class Main {
   public static void main(String[] args) {
     ExecutorService executor = Executors.newFixedThreadPool(15,
         (Runnable r) -> {
           Thread t = new Thread(r);
           //t.setDaemon(true);
           return t;
         });
     SortedSet<File> descriptorFiles = new TreeSet<>();
     for (File descriptorFile : new File("in").listFiles()) {
       descriptorFiles.add(descriptorFile);
     }
     for (int i = 0; i < 5; i++) {
       for (File descriptorFile : descriptorFiles) {
         Thread readerThread = new Thread() {
           @Override
           public void run() {
             parseDescriptorFile(descriptorFile);
           }
         };
         executor.submit(readerThread);
       }
     }
   }
   private static void parseDescriptorFile(File descriptorFile) {
     for (Descriptor descriptor
         : DescriptorSourceFactory.createDescriptorReader()
         .readDescriptors(descriptorFile)) {
       // ignore
       if (descriptor instanceof RelayNetworkStatusConsensus) {
         continue;
       }
     }
   }
 }
 }}}

 There are probably similar issues with other methods.

--
Ticket URL: <https://trac.torproject.org/projects/tor/ticket/32194>
Tor Bug Tracker & Wiki <https://trac.torproject.org/>
The Tor Project: anonymity online


More information about the tor-bugs mailing list