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