[ 
https://issues.apache.org/jira/browse/WW-5826?focusedWorklogId=1051712&page=com.atlassian.jira.plugin.system.issuetabpanels:worklog-tabpanel#worklog-1051712
 ]

ASF GitHub Bot logged work on WW-5826:
--------------------------------------

                Author: ASF GitHub Bot
            Created on: 01/Nov/26 08:10
            Start Date: 01/Nov/26 08:10
    Worklog Time Spent: 10m 
      Work Description: lukaszlenart commented on PR #2082:
URL: https://github.com/apache/struts/pull/2082#issuecomment-6555367576

   Thanks, the analysis holds: `Dispatcher` wraps the session in a new 
`SessionMap` per request (`Dispatcher.java:902`), so `synchronized (o)` never 
excludes two concurrent requests and the static map is mutated without a shared 
monitor. The one-line fix is correct and does not interfere with the 
`o.wait()`/`o.notify()` logic, since the map's own lock is only held inside 
`get`/`put`/`remove`.
   
   Worth saying what the practical effect is, because the PR describes only the 
size counter: every entry left behind after `unlock()` pins a `SessionMap` (and 
through it the request and session) plus the whole `ActionInvocation`. So this 
is a slow leak under concurrent load for applications that use `scope`, not 
just a cosmetic counter. That is the reason to merge it.
   
   Two requests before merging:
   
   1. **The test is too heavy for what it guards.** 8 threads × 40,000 
iterations on every core build, for a one-line change, and it never fails once 
the fix is in. Please cut the iterations to something small (a few hundred per 
thread is enough to keep it as a regression smoke test) and drop the 
reflection: the test is in the same package, so a package-private `static int 
lockCount()` next to `clearLocks()` avoids reaching into a private field.
   2. **The affected-versions note in WW-5826 is inaccurate.** The 6.12.0 tag 
has the same pattern (`locks` is a plain `IdentityHashMap`, `lock()`/`unlock()` 
synchronize on `o`, only `clearLocks()` synchronizes on `locks`), so 6.x is not 
different from 7.x here. Please correct the ticket; which versions get the fix 
is decided on the ticket.
   
   Scope note: please keep the PR to this. Changing what the interceptor locks 
on would be a behaviour change and is out of scope here.
   




Issue Time Tracking
-------------------

    Worklog Id:     (was: 1051712)
    Time Spent: 20m  (was: 10m)

> Make ScopeInterceptor lock table thread-safe
> --------------------------------------------
>
>                 Key: WW-5826
>                 URL: https://issues.apache.org/jira/browse/WW-5826
>             Project: Struts 2
>          Issue Type: Improvement
>          Components: Core
>    Affects Versions: 7.0.0, 7.3.0, 7.4.0
>            Reporter: Gouri Sankar A
>            Priority: Minor
>             Fix For: 7.5.0
>
>          Time Spent: 20m
>  Remaining Estimate: 0h
>
> ScopeInterceptor keeps a static IdentityHashMap named locks. lock() and 
> unlock() modify it inside synchronized (o), where o is the session map. 
> Dispatcher creates a new SessionMap per request, so concurrent requests do 
> not share that monitor and the map is modified without mutual exclusion. 
> Under concurrent use the map's size counter was observed to be corrupted 
> (positive and negative values). This is hardening; no security impact was 
> demonstrated. The interceptor is opt-in: it is declared as "scope" in 
> struts-default.xml but is not part of any bundled interceptor stack, so an 
> application has to reference it explicitly.
> Affected versions: the same code (a static IdentityHashMap locks guarded by 
> synchronized (o)) is present in the 7.0.0, 7.3.0 and 7.4.0 tags, by source 
> inspection. The race itself was only reproduced on main. The 6.12.0 tag 
> differs (lock() synchronizes on locks), so 6.x is not claimed.
> Fix: wrap the map with Collections.synchronizedMap, consistent with the 
> synchronized (locks) in clearLocks().
> Tests: ScopeInterceptorTest#testConcurrentLockAndUnlockLeavesNoEntries. It 
> failed in every run without the fix (25 runs) and passed 20/20 with it. It is 
> statistical: it can pass without the fix on a fast machine.
> Pull request: https://github.com/apache/struts/pull/2082



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

Reply via email to