Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitfad2b99

Browse files
committed
Arrange to ignore SIGPIPE during SSL_read() and SSL_shutdown(), as these
are known to write on the socket sometimes and thus we are vulnerable tobeing killed by the signal if the server happens to go away unexpectedly.Noticed while trying (futilely) to reproduce bug #3902.This bug has been there all along, but since the situation is usuallyonly of interest to developers, I chose not to back-patch the changes.
1 parentcf9990c commitfad2b99

File tree

1 file changed

+63
-30
lines changed

1 file changed

+63
-30
lines changed

‎src/interfaces/libpq/fe-secure.c

Lines changed: 63 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.101 2008/01/01 19:46:00 momjian Exp $
14+
* $PostgreSQL: pgsql/src/interfaces/libpq/fe-secure.c,v 1.102 2008/01/29 02:03:39 tgl Exp $
1515
*
1616
* NOTES
1717
* [ Most of these notes are wrong/obsolete, but perhaps not all ]
@@ -162,6 +162,50 @@ static bool pq_initssllib = true;
162162
staticSSL_CTX*SSL_context=NULL;
163163
#endif
164164

165+
/*
166+
* Macros to handle disabling and then restoring the state of SIGPIPE handling.
167+
* Note that DISABLE_SIGPIPE() must appear at the start of a block.
168+
*/
169+
170+
#ifndefWIN32
171+
#ifdefENABLE_THREAD_SAFETY
172+
173+
#defineDISABLE_SIGPIPE(failaction) \
174+
sigset_tosigmask; \
175+
boolsigpipe_pending; \
176+
boolgot_epipe = false; \
177+
\
178+
if (pq_block_sigpipe(&osigmask, &sigpipe_pending) < 0) \
179+
failaction
180+
181+
#defineREMEMBER_EPIPE(cond) \
182+
do { \
183+
if (cond) \
184+
got_epipe = true; \
185+
} while (0)
186+
187+
#defineRESTORE_SIGPIPE() \
188+
pq_reset_sigpipe(&osigmask, sigpipe_pending, got_epipe)
189+
190+
#else/* !ENABLE_THREAD_SAFETY */
191+
192+
#defineDISABLE_SIGPIPE(failaction) \
193+
pqsigfuncoldsighandler = pqsignal(SIGPIPE, SIG_IGN)
194+
195+
#defineREMEMBER_EPIPE(cond)
196+
197+
#defineRESTORE_SIGPIPE() \
198+
pqsignal(SIGPIPE, oldsighandler)
199+
200+
#endif/* ENABLE_THREAD_SAFETY */
201+
#else/* WIN32 */
202+
203+
#defineDISABLE_SIGPIPE(failaction)
204+
#defineREMEMBER_EPIPE(cond)
205+
#defineRESTORE_SIGPIPE()
206+
207+
#endif/* WIN32 */
208+
165209
/* ------------------------------------------------------------ */
166210
/* Procedures common to all secure sessions*/
167211
/* ------------------------------------------------------------ */
@@ -268,6 +312,9 @@ pqsecure_read(PGconn *conn, void *ptr, size_t len)
268312
{
269313
interr;
270314

315+
/* SSL_read can write to the socket, so we need to disable SIGPIPE */
316+
DISABLE_SIGPIPE(return-1);
317+
271318
rloop:
272319
n=SSL_read(conn->ssl,ptr,len);
273320
err=SSL_get_error(conn->ssl,n);
@@ -292,9 +339,12 @@ pqsecure_read(PGconn *conn, void *ptr, size_t len)
292339
charsebuf[256];
293340

294341
if (n==-1)
342+
{
343+
REMEMBER_EPIPE(SOCK_ERRNO==EPIPE);
295344
printfPQExpBuffer(&conn->errorMessage,
296345
libpq_gettext("SSL SYSCALL error: %s\n"),
297346
SOCK_STRERROR(SOCK_ERRNO,sebuf,sizeof(sebuf)));
347+
}
298348
else
299349
{
300350
printfPQExpBuffer(&conn->errorMessage,
@@ -325,6 +375,8 @@ pqsecure_read(PGconn *conn, void *ptr, size_t len)
325375
n=-1;
326376
break;
327377
}
378+
379+
RESTORE_SIGPIPE();
328380
}
329381
else
330382
#endif
@@ -341,19 +393,7 @@ pqsecure_write(PGconn *conn, const void *ptr, size_t len)
341393
{
342394
ssize_tn;
343395

344-
#ifndefWIN32
345-
#ifdefENABLE_THREAD_SAFETY
346-
sigset_tosigmask;
347-
boolsigpipe_pending;
348-
boolgot_epipe= false;
349-
350-
351-
if (pq_block_sigpipe(&osigmask,&sigpipe_pending)<0)
352-
return-1;
353-
#else
354-
pqsigfuncoldsighandler=pqsignal(SIGPIPE,SIG_IGN);
355-
#endif/* ENABLE_THREAD_SAFETY */
356-
#endif/* WIN32 */
396+
DISABLE_SIGPIPE(return-1);
357397

358398
#ifdefUSE_SSL
359399
if (conn->ssl)
@@ -384,10 +424,7 @@ pqsecure_write(PGconn *conn, const void *ptr, size_t len)
384424

385425
if (n==-1)
386426
{
387-
#if defined(ENABLE_THREAD_SAFETY)&& !defined(WIN32)
388-
if (SOCK_ERRNO==EPIPE)
389-
got_epipe= true;
390-
#endif
427+
REMEMBER_EPIPE(SOCK_ERRNO==EPIPE);
391428
printfPQExpBuffer(&conn->errorMessage,
392429
libpq_gettext("SSL SYSCALL error: %s\n"),
393430
SOCK_STRERROR(SOCK_ERRNO,sebuf,sizeof(sebuf)));
@@ -426,19 +463,10 @@ pqsecure_write(PGconn *conn, const void *ptr, size_t len)
426463
#endif
427464
{
428465
n=send(conn->sock,ptr,len,0);
429-
#if defined(ENABLE_THREAD_SAFETY)&& !defined(WIN32)
430-
if (n<0&&SOCK_ERRNO==EPIPE)
431-
got_epipe= true;
432-
#endif
466+
REMEMBER_EPIPE(n<0&&SOCK_ERRNO==EPIPE);
433467
}
434468

435-
#ifndefWIN32
436-
#ifdefENABLE_THREAD_SAFETY
437-
pq_reset_sigpipe(&osigmask,sigpipe_pending,got_epipe);
438-
#else
439-
pqsignal(SIGPIPE,oldsighandler);
440-
#endif/* ENABLE_THREAD_SAFETY */
441-
#endif/* WIN32 */
469+
RESTORE_SIGPIPE();
442470

443471
returnn;
444472
}
@@ -1092,9 +1120,13 @@ close_SSL(PGconn *conn)
10921120
{
10931121
if (conn->ssl)
10941122
{
1123+
DISABLE_SIGPIPE((void)0);
10951124
SSL_shutdown(conn->ssl);
10961125
SSL_free(conn->ssl);
10971126
conn->ssl=NULL;
1127+
/* We have to assume we got EPIPE */
1128+
REMEMBER_EPIPE(true);
1129+
RESTORE_SIGPIPE();
10981130
}
10991131

11001132
if (conn->peer)
@@ -1167,6 +1199,7 @@ PQgetssl(PGconn *conn)
11671199
}
11681200
#endif/* USE_SSL */
11691201

1202+
11701203
#if defined(ENABLE_THREAD_SAFETY)&& !defined(WIN32)
11711204

11721205
/*
@@ -1251,4 +1284,4 @@ pq_reset_sigpipe(sigset_t *osigset, bool sigpipe_pending, bool got_epipe)
12511284
SOCK_ERRNO_SET(save_errno);
12521285
}
12531286

1254-
#endif/* ENABLE_THREAD_SAFETY */
1287+
#endif/* ENABLE_THREAD_SAFETY&& !WIN32*/

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp