32 bit libpq fail to connecting when set a very large "connect_timeout" value

From: chenhj <chjischj(at)163(dot)com>
To: pgsql-bugs(at)postgresql(dot)org
Subject: 32 bit libpq fail to connecting when set a very large "connect_timeout" value
Date: 2014-10-20 06:01:03
Message-ID: 75f4618f.c0f7.1492c250468.Coremail.chjischj@163.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-bugs

Hi,all

This a bug report.

1)The problem
When set a very large value(such as 2147483647 which is the maximum of int ) to connect_timeout,and then connect to the backend using 32 bit psql, a timeout will occur.
For example:

[chenhj(at)node2 ~]$ export PGCONNECT_TIMEOUT=2147483647
[chenhj(at)node2 ~]$ psql
psql: timeout expired

While it's OK when using 64 bit psql.

[chenhj(at)node2 ~]$ export PGCONNECT_TIMEOUT=2147483647
[chenhj(at)node2 ~]$ psql
psql (9.2.8)
Type "help" for help.

postgres=# \q

2)The reason
I looked into the source code, and found the reason is a data overflow when calculating connecting's finish_time as the following.

src\interfaces\libpq\fe-connect.c:
static int
connectDBComplete(PGconn *conn)
{
PostgresPollingStatusType flag = PGRES_POLLING_WRITING;
time_tfinish_time = ((time_t) -1);

if (conn == NULL || conn->status == CONNECTION_BAD)
return 0;

/*
* Set up a time limit, if connect_timeout isn't zero.
*/
if (conn->connect_timeout != NULL)
{
inttimeout = atoi(conn->connect_timeout);

if (timeout > 0)
{
/*
* Rounding could cause connection to fail; need at least 2 secs
*/
if (timeout < 2)
timeout = 2;
/* calculate the finish time based on start + timeout */
finish_time = time(NULL) + timeout;// In 32 bit application time_t is a 32 bit, when timeout is very large, data overflow will occur and finish_time became a negative value.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
}
}
...
}

Of course this is a infrequence bug, but i think it should be fixed, such as the following(may be there's better way to fix it).

finish_time = time(NULL) + timeout;
==>
finish_time = time(NULL) + timeout;
if(finish_time < ((time_t) 0))
{
finish_time = ((time_t) -1);
}

Best Regards
Chen Huajun

Responses

Browse pgsql-bugs by date

  From Date Subject
Next Message Michael Paquier 2014-10-20 06:45:20 Re: BUG #11705: \d(escribe) table shows incorrect check constraint
Previous Message Tom Lane 2014-10-19 20:14:29 Re: BUG #10680: LDAP bind password leaks to log on failed authentication