https://bz.apache.org/bugzilla/show_bug.cgi?id=69814
Bug ID: 69814 Summary: HttpSession.isNew() may return true on an existing session due to a race condition Product: Tomcat 10 Version: 10.1.44 Hardware: PC Status: NEW Severity: normal Priority: P2 Component: Catalina Assignee: dev@tomcat.apache.org Reporter: csa...@gmail.com Target Milestone: ------ In a stateful application where HttpSession is used, session.isNew() should return true in the request where the session is just created anew; and false when it is retrieved from an existing one. However, very infrequently, it could return TRUE under some particular execution sequence as follows: 1) Client sends the 1st request 2) Server receives the 1st request and processes it in thread T1. Session S is created. Its "isnew" field is set to true. Response is flushed. T1 is paused (e.g. due to context switching) before calling StandardSession.endAccess(). 3) Client receives the response, including the JSESSIONID 4) Client sends the 2nd request with the JSESSIONID 5) Server receives the 2nd request and processes it in thread T2. StandardManager finds the session S using the given JSESSIONID successfully. The application calls session.isNew() which unexpectedly returns TRUE. Response is then returned to client 6) Server's thread T1 continues to run StandardSession.endAccess() after outputting the response, which set the session S's isnew field to false: https://github.com/apache/tomcat/blob/10.1.45/java/org/apache/catalina/session/StandardSession.java#L535 (also see the attached thread dump 1st_request_thread_dump.txt) 7) In subsequent requests, isnew() returns false as expected. Normally, session.isNew() is false if 6) occurs before 5), but when the server is slow or client is too fast, the above sequence will trigger the bug. I could easily reproduce it on Linux and Windows with the help of a debugger to enforce such a sequence. How to reproduce: Set a breakpoint to pause at StandardSession.endAccess() and fire two requests successively. 1) Deploy the attached demo application (attached TomcatApp.war): set JAVA_OPTS in startup.sh/.bat script to enable remote debugging: JAVA_OPTS=-agentlib:jdwp=transport=dt_socket,address=*:9999,server=y,suspend=n" override the conf/server.xml with the attached that sets the listening port to 9080 and disables TLS redirection. 2) Open the demo project (attached TomcatHello.zip) in IntelliJ IDEA 3) Set breakpoint at StandardSession.endAccess() 4) Set remote JVM debug to localhost:9999 5) Open a console 6) Run the following in sequence: curl -c cookies.txt http://localhost:9080/TomcatApp/hello (breakpoint hit) (output: Session isNew? true) curl -b cookies.txt http://localhost:9080/TomcatApp/hello (output: Session isNew? true) (Detach the debugger) curl -b cookies.txt http://localhost:9080/TomcatApp/hello (output: Session isNew? false) (See also the attached video demo.mp4) Regards, Sammy Chan -- You are receiving this mail because: You are the assignee for the bug. --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org