JDK-4779253 : Race Condition in class java.util.logging.Logger
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util.logging
  • Affected Version: 1.4.0,1.4.1,7
  • Priority: P4
  • Status: Closed
  • Resolution: Fixed
  • OS: generic,solaris_7,windows_2000
  • CPU: generic,x86,sparc
  • Submitted: 2002-11-14
  • Updated: 2011-04-19
  • Resolved: 2011-04-19
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7 b16Fixed
Description

Name: rmT116609			Date: 11/14/2002


FULL PRODUCT VERSION :
java version "1.4.1_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1_01-b01)
Java HotSpot(TM) Client VM (build 1.4.1_01-b01, mixed mode)

FULL OPERATING SYSTEM VERSION :
Microsoft Windows 2000 [Version5.00.2195]

A DESCRIPTION OF THE PROBLEM :
This report is based on examining the source code shipped with J2SDK
1.4.1_01.

There is a classic race condition in the implementation of
java.util.logging.Logger.  The field 'filter' is only accessed in the
methods setFilter, getFilter, and log(LogRecord).  Log accesses
'filter' in the following manner:

	synchronized (this) {
	    if
(filter != null && !filter.isLoggable(record)) {
	        return;
	    
}
	}

That is, 'filter' is checked against null before being
dereferenced.  This is done in a synchronized block presumably to prevent
'filter' from being set to null after it has been found to be non-null.  The
problem is that setFilter() does not use synchronization at all, and is
explicitly allowed to set 'filter' to null.  The critical section in
log(LogRecord) is thus completely useless.

Method setFilter()
should be declared synchronized to avoid the race condition.  Method
getFilter() should declared synchronized otherwise the Java Memory
Model allows it to return out-of-date values.


REPRODUCIBILITY :
This bug can be reproduced rarely.

CUSTOMER WORKAROUND :
Caller of setFilter() should synchronize on the Logger object before
invoking setFilter().
(Review ID: 167038) 
======================================================================

Comments
SUGGESTED FIX This is the fix suggested in the bug description: % sccs sccsdiff -r1.58 -r1.59 Logger.java ------- Logger.java ------- 442c442 < public void setFilter(Filter newFilter) throws SecurityException { --- > public synchronized void setFilter(Filter newFilter) throws SecurityException { 452c452 < public Filter getFilter() { --- > public synchronized Filter getFilter() {
07-06-2007

EVALUATION This problem is very clear from the bug description. The SR is against 1.4 and 1.4.1. But it exists in all jdk versions including jdk7. So, it must be fixed in jdk7 first and then backported to older releases.
04-06-2007