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

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

                Author: ASF GitHub Bot
            Created on: 31/Oct/26 10:20
            Start Date: 31/Oct/26 10:20
    Worklog Time Spent: 10m 
      Work Description: g0w6y opened a new pull request, #2082:
URL: https://github.com/apache/struts/pull/2082

   Fixes [WW-5826](https://issues.apache.org/jira/browse/WW-5826)
   
   Hardening, no behaviour change. `ScopeInterceptor.locks` is a static 
`IdentityHashMap` shared by all requests. `lock()`/`unlock()` mutate it inside 
`synchronized (o)`, but `o` is the session map, which `Dispatcher` creates per 
request, so concurrent requests never share that monitor and the map is 
modified unsynchronized. It is now `Collections.synchronizedMap(...)`, which 
also matches the `synchronized (locks)` already used by `clearLocks()`.
   
   `ScopeInterceptorTest#testConcurrentLockAndUnlockLeavesNoEntries` runs 8 
threads x 40,000 lock/unlock pairs on distinct objects and asserts the map is 
empty afterwards. Without the change it failed in every run I made (25 runs); 
the observed size varies per run, both positive and negative (for example 229, 
230, 288, 563, -473, -547), i.e. the map's size counter is corrupted. With the 
change it passed 20/20.
   
   The test is statistical: it can pass without the fix on a fast machine, but 
it never fails with the fix. 
   
   Not changed: what `ScopeInterceptor` locks on. Not claiming a security issue 
or any cross-request data exposure; only the corrupted map size was measured. 
The same kind of change for the XSLT plugin's `BeanAdapter` cache is a separate 
PR.
   




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

            Worklog Id:     (was: 1051602)
    Remaining Estimate: 0h
            Time Spent: 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
>          Time Spent: 10m
>  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 (scope and scopedModelDriven stacks, 
> not defaultStack).
> 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.



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

Reply via email to