Uploaded image for project: 'RESTEasy'
  1. RESTEasy
  2. RESTEASY-744

Bugs because of misusing concurrent collections

    XMLWordPrintable

Details

    • Bug
    • Resolution: Won't Do
    • Major
    • 2.3.5.Final
    • 2.3.4.Final
    • jaxrs

    Description

      My name is Yu Lin. I'm a Ph.D. student in the CS department at
      UIUC. I'm currently doing research on mining Java concurrent library
      misusages. I found some misusages of ConcurrentHashMap in RestEasy
      2.3.4, which may result in potential atomicity violation bugs.

      The code below is a snapshot of the code in file
      providers/jaxb/src/main/java/org/jboss/resteasy/plugins/providers/jaxb/XmlJAXBContextFinder.java
      from line 64 to 71

      L64 CacheKey key = new CacheKey(classes);
      L65 JAXBContext ctx = collectionCache.get(key);
      L66 if (ctx != null) return ctx;

      L68 ctx = createContext(paraAnnotations, classes);
      L69 collectionCache.put(key, ctx);

      L71 return ctx;

      In the code above, an atomicity violation may occur between line 67
      and 69. Suppose a thread T1 executes line 65 and finds out the
      concurrent hashmap "collectionCache" does not contain the key
      "key". Before it gets to execute line 69, another thread T2 puts a
      pair <key, v> in the concurrent hashmap "collectionCache". Now thread
      T1 resumes execution and it will overwrite the value written by thread
      T2. Thus, the code no longer preserves the "put-if-absent"
      semantics. We can fix this by using "putIfAbsent" method at line 69.

      I also found other 4 places in the code that have this problem:
      XmlJAXBContextFinder.java line 82; JsonJAXBContextFinder.java lines
      111 and 119; SimpleServerCache.java line 83. I attach a patch that can
      fix it.

      Meanwhile, there are also misusages on "putIfAbsent" operation. For
      example, here is the code in
      security/resteasy-oauth/src/main/java/org/jboss/resteasy/auth/oauth/OAuthMemoryProvider.java
      from line 140 to 146

      L140 OAuthConsumer consumer = consumers.get(consumerKey);
      L141 if (consumer == null)

      { L142 return consumer; L143 }

      L144 consumer = new OAuthConsumer(consumerKey, "therealfrog", displayName, connectURI);
      L145 consumers.putIfAbsent(consumerKey, consumer);
      L146 return consumer;

      Suppose thread T1 executes line 140 and finds out the concurrent
      hashmap "consumers" does not contain the key "consumerKey". Before it
      gets to execute line 145, another thread T2 puts a pair <consumerKey,
      v> into the concurrent hashmap "consumers". Now thread T1 resumes
      execution but it won't put the "consumer" into the map because T2
      already put a value with key "consumerKey". Thus, the "consumer"
      returned by T1 isn't in the map actually.

      I also find 5 other places in the code that misuse the "putIfAbsent":
      JAXBCache.java line 71; JsonJAXBContextFinder.java line 149;
      ResourceLocator.java line 135; SimpleSecurityDomain.java line 26.

      Attachments

        Activity

          People

            rsigal@redhat.com Ronald Sigal
            jacklondongood Yu Lin (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: