Thread: org.postgresql.Driver not thread-safe
Hi all, It seems that org.postgresql.Driver isn't thread safe, as it stores details from the connection URL to the connect method in an instance variable "props" - and there is no synchronisation. The DriverManager (java.sql.DriverManager) returns the same instance of the org.postgresql.Driver to each getDriver(String url ) method and probably all of the others. Hence the problem with multiple threads connecting at the same time, the threads obtain the same Driver instance and the connection details from different threads can become muddled. I observed this bug on my production server using Jakarta Tomcat 4.1.27 and Jakarta Commons DBCP 1.0 which uses the DriverManager.getDriver(String url) method to obtain a Driver object, and then calls the connect method on the driver. The getConnection() method in DriverManager are all synchronized so it is the getting of the Driver and then calling connect on that which has revealed this issue. I've made a simple patch against the REL_7_3_STABLE branch of Driver.java.in which removes the use of the instance variable. I'm going to test this patch immediately. Kind regards, Karl cvs diff Driver.java.in (in directory C:\DEVELOPMENT\pgsql\src\interfaces\jdbc\org\postgresql) Index: Driver.java.in =================================================================== RCS file: /projects/cvsroot/pgsql-server/src/interfaces/jdbc/org/postgresql/Driver.jav a.in,v retrieving revision 1.22.2.7 diff -r1.22.2.7 Driver.java.in 109a110 > Properties props; 122c123 < con.openConnection (host(), port(), props, database(), url, this); --- > con.openConnection (host(props), port(props), props, > database(props), url, this); 232,233d232 < private Properties props; < 350c349 < public String host() --- > public String host(Properties props) 358c357 < public int port() --- > public int port(Properties props) 366c365 < public String database() --- > public String database(Properties props) 375c374 < public String property(String name) --- > public String property(Properties props, String name) 394c393 < * @param int logLevel sets the level which logging will respond to --- > * @param logLevel sets the level which logging will respond to
On Sun, 16 Nov 2003, Karl von Randow wrote: > Hi all, > > It seems that org.postgresql.Driver isn't thread safe, as it stores details > from the connection URL to the connect method in an instance variable > "props" - and there is no synchronisation. The DriverManager > (java.sql.DriverManager) returns the same instance of the > org.postgresql.Driver to each getDriver(String url ) method and probably all > of the others. Hence the problem with multiple threads connecting at the > same time, the threads obtain the same Driver instance and the connection > details from different threads can become muddled. Yes, good catch. > I've made a simple patch against the REL_7_3_STABLE branch of Driver.java.in > which removes the use of the instance variable. I'm going to test this patch > immediately. In the future when submitting patches please use a context diff (-c) format and attach it to the email so it avoids line wrapping. Here is the corresponding patch against cvs tip which should also apply cleanly to the 7.4 branch. Kris Jurka
Attachment
Thanks Kris, I'll do that. It was a funny one to see happening on my server as you can imagine. The bug could cause some security problems in shared hosting environments - repeatedly opening connections on the driver until you got someone else's database etc. The patched version appears to run AOK on my production server now. Cheers, k@rl -----Original Message----- From: Kris Jurka [mailto:books@ejurka.com] Sent: Sunday, 16 November 2003 2:17 p.m. To: Karl von Randow Cc: pgsql-jdbc@postgresql.org Subject: Re: [JDBC] org.postgresql.Driver not thread-safe On Sun, 16 Nov 2003, Karl von Randow wrote: > Hi all, > > It seems that org.postgresql.Driver isn't thread safe, as it stores > details from the connection URL to the connect method in an instance > variable "props" - and there is no synchronisation. The DriverManager > (java.sql.DriverManager) returns the same instance of the > org.postgresql.Driver to each getDriver(String url ) method and > probably all of the others. Hence the problem with multiple threads > connecting at the same time, the threads obtain the same Driver > instance and the connection details from different threads can become > muddled. Yes, good catch. > I've made a simple patch against the REL_7_3_STABLE branch of > Driver.java.in which removes the use of the instance variable. I'm > going to test this patch immediately. In the future when submitting patches please use a context diff (-c) format and attach it to the email so it avoids line wrapping. Here is the corresponding patch against cvs tip which should also apply cleanly to the 7.4 branch. Kris Jurka