Here is the patch I promised. Please apply to stock pgpool-II 3.0 or
3.0 stable head.
--
Tatsuo Ishii
SRA OSS, Inc. Japan
English: http://www.sraoss.co.jp/index_en.php
Japanese: http://www.sraoss.co.jp

> Thanks! I have examined the patch and I think that your problem only
> occurs when none of replication mode/master slave mode/parallel are
> set *or* you have only one backend. This should explain why I couldn't
> reproduce your proplem. Can you confirm this?  Also I found other
> possible bug with the module. I will come back with the patch along
> with assorted fixes.
> --
> Tatsuo Ishii
> SRA OSS, Inc. Japan
> English: http://www.sraoss.co.jp/index_en.php
> Japanese: http://www.sraoss.co.jp
> 
> From: Rob Shepherd <[email protected]>
> Subject: Re: [Pgpool-general] Segfault when using MD5 auth [working patch]
> Date: Wed, 15 Dec 2010 20:40:14 +0000
> Message-ID: <[email protected]>
> 
>> Tatsuo - Sincere apologies, the last patch was an old broken copy -
>> please ignore it and accept this new one - attached.
>> 
>> http://dpaste.com/hold/287099/
>> 
>> 
>> 
>> 
>> 
>> Tatsuo,
>> 
>> On a whim I attempted the fix found at:
>> 
>> http://abdulyadi.wordpress.com/2010/09/25/pgpool-ii-3-0-bug-fixes/
>> 
>> And it worked!
>> 
>> I used this procedure:
>> 
>> http://bradthemad.org/tech/notes/patching_rpms.php
>> 
>> 
>> I made a patch of the fix found on the blog post, which is attached.
>> 
>> Is there any verification set suite you would like to me to run to
>> test
>> the stability of the system with the applied patch?
>> 
>> Many thanks
>> 
>> Rob
>> 
>> Rob Shepherd wrote:
>>> Tatsuo,
>>>
>>> At last! I finally managed to work out how to use the debuginfo
>>> package.
>>> Here is a stacktrace for the gdb session with debug symbols loaded.
>>>
>>>> (gdb) cont
>>>> Continuing.
>>>>
>>>> Program received signal SIGSEGV, Segmentation fault.
>>>> 0x00000038c6c7c3fc in memcpy () from /lib64/libc.so.6
>>>> (gdb) bt
>>>> #0  0x00000038c6c7c3fc in memcpy () from /lib64/libc.so.6
>>>> #1 0x000000000040a718 in do_md5 (backend=0x15229fd0,
>>>> #frontend=0x15227370, reauth=<value optimized out>,
>>>>     protoMajor=3) at pool_auth.c:990
>>>> #2 0x000000000040ac3f in pool_do_auth (frontend=0x15227370,
>>>> #cp=0x15226340) at pool_auth.c:222
>>>> #3 0x0000000000408978 in connect_backend (unix_fd=4, inet_fd=5) at
>>>> #child.c:1143
>>>> #4  do_child (unix_fd=4, inet_fd=5) at child.c:293
>>>> #5 0x0000000000403c35 in fork_a_child (unix_fd=4, inet_fd=5, id=0) at
>>>> #main.c:1024
>>>> #6  0x0000000000404467 in reaper () at main.c:1921
>>>> #7 0x0000000000406415 in main (argc=<value optimized out>, argv=<value
>>>> #optimized out>) at main.c:557
>>>> (gdb)
>>>
>>>
>>> Please let me know what more I can do.
>>>
>>>
>>> With many thanks and kind regards
>>>
>>> Rob
>>>
>>>
>>> Tatsuo Ishii wrote:
>>>>>> No problem.  However, I have already provided a stacktrace for this
>>>>>> problem.
>>>>>>
>>>>>> Your response to it was:
>>>>>>
>>>>>>      
>>>>>>> Thanks for the backtrace. Unfortunately the binary did not have the
>>>>>>> symbol table and did not give me usefull info. BTW while looking at
>>>>>>> the code, I found a nasty bug with pgpool-II which may or may not
>>>>>>> cause the bug. If user name is long(32 bytes), pgpool-II will crash.
>>>>>>> If this is the case, attached will fix it.  If this does not work, can
>>>>>>> you please run pgpool with -d (debug)option which might give us
>>>>>>> usefull information.
>>>>>>>         
>>>>>> Essentially, the binary doesn't have debug symbols.
>>>>>>
>>>>>> It seems the packager from where I installed the binaries doesn't
>>>>>> provide source-RPMs, so it may be tricky for me to build a debug
>>>>>> version.
>>>>>>
>>>>>> Do you happen to have a RedHat 5/Centos/Fedora debug binary that might
>>>>>> work?
>>>>>>       
>>>>> Where did you get the rpm binary?
>>>>>     
>>>>
>>>> If the rpm came from
>>>> http://yum.pgrpms.org/9.0/redhat/rhel-5-i386/
>>>> or
>>>> http://yum.pgrpms.org/9.0/redhat/rhel-5-x86_64/
>>>> You could obtain debuginfo packages to get stack trace.
>>>> -- 
>>>> Tatsuo Ishii
>>>> SRA OSS, Inc. Japan
>>>> English: http://www.sraoss.co.jp/index_en.php
>>>> Japanese: http://www.sraoss.co.jp
>>>>
>>>>   
>>>
>>>
>> 
>> 
>> -- 
>> Rob Shepherd BEng PhD - Director / Senior Engineer - DataCymru Ltd
>> Reg. England and Wales - 06731289 - TechniumCAST, LL57 4HJ
>> [email protected] - 08452575006 - 07596154845 - www.datacymru.net
>> 
>> 
> _______________________________________________
> Pgpool-general mailing list
> [email protected]
> http://pgfoundry.org/mailman/listinfo/pgpool-general
Index: pool_auth.c
===================================================================
RCS file: /cvsroot/pgpool/pgpool-II/pool_auth.c,v
retrieving revision 1.26
diff -c -r1.26 pool_auth.c
*** pool_auth.c	28 Sep 2010 08:00:48 -0000	1.26
--- pool_auth.c	16 Dec 2010 08:46:46 -0000
***************
*** 1,6 ****
  /* -*-pgsql-c-*- */
  /*
!  * $Header: /cvsroot/pgpool/pgpool-II/pool_auth.c,v 1.26 2010/09/28 08:00:48 t-ishii Exp $
   *
   * pgpool: a language independent connection pool server for PostgreSQL
   * written by Tatsuo Ishii
--- 1,6 ----
  /* -*-pgsql-c-*- */
  /*
!  * $Header: /cvsroot/pgpool/pgpool-II/pool_auth.c,v 1.28 2010/12/16 08:42:36 t-ishii Exp $
   *
   * pgpool: a language independent connection pool server for PostgreSQL
   * written by Tatsuo Ishii
***************
*** 48,54 ****
  static int do_crypt(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor);
  static int do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor);
  static int send_md5auth_request(POOL_CONNECTION *frontend, int protoMajor, char *salt);
! static int read_password_packet(POOL_CONNECTION *frontend, int protoMajor, 	char *password);
  static int send_password_packet(POOL_CONNECTION *backend, int protoMajor, char *password);
  static int send_auth_ok(POOL_CONNECTION *frontend, int protoMajor);
  
--- 48,54 ----
  static int do_crypt(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor);
  static int do_md5(POOL_CONNECTION *backend, POOL_CONNECTION *frontend, int reauth, int protoMajor);
  static int send_md5auth_request(POOL_CONNECTION *frontend, int protoMajor, char *salt);
! static int read_password_packet(POOL_CONNECTION *frontend, int protoMajor, 	char *password, int *pwdSize);
  static int send_password_packet(POOL_CONNECTION *backend, int protoMajor, char *password);
  static int send_auth_ok(POOL_CONNECTION *frontend, int protoMajor);
  
***************
*** 833,839 ****
  	char encbuf[POOL_PASSWD_LEN+1];
  	char *pool_passwd = NULL;
  
! 	if (!RAW_MODE && NUM_BACKENDS > 1)
  	{
  		/* Read password entry from pool_passwd */
  		pool_passwd = pool_get_passwd(frontend->username);
--- 833,839 ----
  	char encbuf[POOL_PASSWD_LEN+1];
  	char *pool_passwd = NULL;
  
! 	if (NUM_BACKENDS > 1)
  	{
  		/* Read password entry from pool_passwd */
  		pool_passwd = pool_get_passwd(frontend->username);
***************
*** 855,861 ****
  			}
  
  			/* Read password packet */
! 			if (read_password_packet(frontend, protoMajor, password))
  			{
  				pool_error("do_md5: read_password_packet failed");
  				return -1;
--- 855,861 ----
  			}
  
  			/* Read password packet */
! 			if (read_password_packet(frontend, protoMajor, password, &size))
  			{
  				pool_error("do_md5: read_password_packet failed");
  				return -1;
***************
*** 914,936 ****
  		}
  		return kind;
  	}
! 	else
  	{
! 		if (!reauth)
! 		{
! 			/* read salt */
! 			if (pool_read(backend, salt, sizeof(salt)))
! 			{
! 				pool_error("do_md5: failed to read salt");
! 				return -1;
! 			}
! 			pool_debug("DB node id: %d salt: %hhx%hhx%hhx%hhx", backend->db_node_id,
! 					   salt[0], salt[1], salt[2], salt[3]);
! 		}
! 		else
  		{
! 			memcpy(salt, backend->salt, sizeof(salt));
  		}
  	}
  
  	/* master? */
--- 914,937 ----
  		}
  		return kind;
  	}
! 
! 	/*
! 	 * Followings are NUM_BACKEND == 1 case.
! 	 */
! 	if (!reauth)
  	{
! 		/* read salt */
! 		if (pool_read(backend, salt, sizeof(salt)))
  		{
! 			pool_error("do_md5: failed to read salt");
! 			return -1;
  		}
+ 		pool_debug("DB node id: %d salt: %hhx%hhx%hhx%hhx", backend->db_node_id,
+ 				   salt[0], salt[1], salt[2], salt[3]);
+ 	}
+ 	else
+ 	{
+ 		memcpy(salt, backend->salt, sizeof(salt));
  	}
  
  	/* master? */
***************
*** 944,950 ****
  		}
  
  		/* Read password packet */
! 		if (read_password_packet(frontend, protoMajor, password))
  		{
  			pool_error("do_md5: read_password_packet failed");
  			return -1;
--- 945,951 ----
  		}
  
  		/* Read password packet */
! 		if (read_password_packet(frontend, protoMajor, password, &size))
  		{
  			pool_error("do_md5: read_password_packet failed");
  			return -1;
***************
*** 954,960 ****
  	/* connection reusing? */
  	if (reauth)
  	{
! 		if ((ntohl(size) - 4) != backend->pwd_size)
  		{
  			pool_debug("do_md5; password size does not match in re-authentication");
  			return -1;
--- 955,961 ----
  	/* connection reusing? */
  	if (reauth)
  	{
! 		if (size != backend->pwd_size)
  		{
  			pool_debug("do_md5; password size does not match in re-authentication");
  			return -1;
***************
*** 986,992 ****
  		}
  
  		backend->auth_kind = 5;
! 		backend->pwd_size = ntohl(size) - 4;
  		memcpy(backend->password, password, backend->pwd_size);
  		memcpy(backend->salt, salt, sizeof(salt));
  	}
--- 987,993 ----
  		}
  
  		backend->auth_kind = 5;
! 		backend->pwd_size = size;
  		memcpy(backend->password, password, backend->pwd_size);
  		memcpy(backend->salt, salt, sizeof(salt));
  	}
***************
*** 1017,1023 ****
  /*
   * Read password packet from frontend
   */
! static int read_password_packet(POOL_CONNECTION *frontend, int protoMajor, 	char *password)
  {
  	int size;
  
--- 1018,1024 ----
  /*
   * Read password packet from frontend
   */
! static int read_password_packet(POOL_CONNECTION *frontend, int protoMajor, 	char *password, int *pwdSize)
  {
  	int size;
  
***************
*** 1051,1061 ****
  		}
  	}
  
! 	if (pool_read(frontend, password, ntohl(size) - 4))
  	{
! 		pool_error("read_password_packet: failed to read password (size: %d)", ntohl(size) - 4);
  		return -1;
  	}
  	return 0;
  }
  
--- 1052,1081 ----
  		}
  	}
  
! 	*pwdSize = ntohl(size) - 4;
! 	if (*pwdSize > MAX_PASSWORD_SIZE)
  	{
! 		pool_error("read_password_packet: too long password string (size: %d)", *pwdSize);
! 		/*
! 		 * We do not read to throw away packet here. Since it is possible that
! 		 * it's a denial of service attack.
! 		 */
  		return -1;
  	}
+ 	else if (*pwdSize <= 0)
+ 	{
+ 		pool_error("read_password_packet: invalid password string size (size: %d)", *pwdSize);
+ 		return -1;
+ 	}
+ 
+ 	if (pool_read(frontend, password, *pwdSize))
+ 	{
+ 		pool_error("read_password_packet: failed to read password (size: %d)", *pwdSize);
+ 		return -1;
+ 	}
+ 	
+ 	password[*pwdSize] = '\0';
+ 
  	return 0;
  }
  
***************
*** 1063,1068 ****
--- 1083,1089 ----
   * Send password packet to backend and receive authentication response
   * packet.  Return value is the last field of authentication
   * response. If it's 0, authentication was successfull.
+  * "password" must be null-terminated.
   */
  static int send_password_packet(POOL_CONNECTION *backend, int protoMajor, char *password)
  {
***************
*** 1074,1082 ****
  	/* Send password packet to backend */
  	if (protoMajor == PROTO_MAJOR_V3)
  		pool_write(backend, "p", 1);
! 	size = htonl(sizeof(size) + strlen(password));
  	pool_write(backend, &size, sizeof(size));
! 	pool_write_and_flush(backend, password, strlen(password));
  
  	if (pool_read(backend, &response, sizeof(response)))
  	{
--- 1095,1103 ----
  	/* Send password packet to backend */
  	if (protoMajor == PROTO_MAJOR_V3)
  		pool_write(backend, "p", 1);
! 	size = htonl(sizeof(size) + strlen(password)+1);
  	pool_write(backend, &size, sizeof(size));
! 	pool_write_and_flush(backend, password, strlen(password)+1);
  
  	if (pool_read(backend, &response, sizeof(response)))
  	{
_______________________________________________
Pgpool-general mailing list
[email protected]
http://pgfoundry.org/mailman/listinfo/pgpool-general

Reply via email to