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

Commitfccef77

Browse files
committed
Fix portability bugs in use of credentials control messages for peer auth.
Even though our existing code for handling credentials control messages hasbeen basically unchanged since 2001, it was fundamentally wrong: it did notensure proper alignment of the supplied buffer, and it was calculatingbuffer sizes and message sizes incorrectly. This led to failures onplatforms where alignment padding is relevant, for instance FreeBSD on64-bit platforms, as seen in a recent Debian bug report passed on byMartin Pitt (http://bugs.debian.org//cgi-bin/bugreport.cgi?bug=612888).Rewrite to do the message-whacking using the macros specified in RFC 2292,following a suggestion from Theo de Raadt in that thread. Tested by meon Debian/kFreeBSD-amd64; since OpenBSD and NetBSD document the identicalCMSG API, it should work there too.Back-patch to all supported branches.
1 parent6d24189 commitfccef77

File tree

2 files changed

+46
-34
lines changed

2 files changed

+46
-34
lines changed

‎src/backend/libpq/hba.c

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,7 +1449,7 @@ static bool
14491449
ident_unix(intsock,char*ident_user)
14501450
{
14511451
#if defined(HAVE_GETPEEREID)
1452-
/* OpenBSD style: */
1452+
/* OpenBSD(also Mac OS X)style:use getpeereid() */
14531453
uid_tuid;
14541454
gid_tgid;
14551455
structpasswd*pass;
@@ -1508,9 +1508,7 @@ ident_unix(int sock, char *ident_user)
15081508

15091509
return true;
15101510
#elif defined(HAVE_STRUCT_CMSGCRED)|| defined(HAVE_STRUCT_FCRED)|| (defined(HAVE_STRUCT_SOCKCRED)&& defined(LOCAL_CREDS))
1511-
structmsghdrmsg;
1512-
1513-
/* Credentials structure */
1511+
/* Assorted BSDen: use a credentials control message */
15141512
#if defined(HAVE_STRUCT_CMSGCRED)
15151513
typedefstructcmsgcredCred;
15161514

@@ -1524,43 +1522,55 @@ ident_unix(int sock, char *ident_user)
15241522

15251523
#definecruid sc_uid
15261524
#endif
1527-
Cred*cred;
1528-
1529-
/* Compute size without padding */
1530-
charcmsgmem[ALIGN(sizeof(structcmsghdr))+ALIGN(sizeof(Cred))];/* for NetBSD */
1531-
1532-
/* Point to start of first structure */
1533-
structcmsghdr*cmsg= (structcmsghdr*)cmsgmem;
15341525

1526+
structmsghdrmsg;
1527+
structcmsghdr*cmsg;
1528+
union
1529+
{
1530+
structcmsghdrhdr;
1531+
unsignedcharbuf[CMSG_SPACE(sizeof(Cred))];
1532+
}cmsgbuf;
15351533
structioveciov;
15361534
charbuf;
1535+
Cred*cred;
15371536
structpasswd*pw;
15381537

1539-
memset(&msg,0,sizeof(msg));
1540-
msg.msg_iov=&iov;
1541-
msg.msg_iovlen=1;
1542-
msg.msg_control= (char*)cmsg;
1543-
msg.msg_controllen=sizeof(cmsgmem);
1544-
memset(cmsg,0,sizeof(cmsgmem));
1545-
15461538
/*
1547-
* The one characterwhich is received here is not meaningful; its
1548-
*purposesis only to make sure that recvmsg() blocks long enough for the
1549-
*otherside to send its credentials.
1539+
* The one characterthat is received here is not meaningful; its purpose
1540+
* is only to make sure that recvmsg() blocks long enough for the other
1541+
* side to send its credentials.
15501542
*/
15511543
iov.iov_base=&buf;
15521544
iov.iov_len=1;
15531545

1554-
if (recvmsg(sock,&msg,0)<0||
1555-
cmsg->cmsg_len<sizeof(cmsgmem)||
1556-
cmsg->cmsg_type!=SCM_CREDS)
1546+
memset(&msg,0,sizeof(msg));
1547+
msg.msg_iov=&iov;
1548+
msg.msg_iovlen=1;
1549+
msg.msg_control=&cmsgbuf.buf;
1550+
msg.msg_controllen=sizeof(cmsgbuf.buf);
1551+
memset(&cmsgbuf,0,sizeof(cmsgbuf));
1552+
1553+
if (recvmsg(sock,&msg,0)<0)
15571554
{
15581555
ereport(LOG,
15591556
(errcode_for_socket_access(),
15601557
errmsg("could not get peer credentials: %m")));
15611558
return false;
15621559
}
15631560

1561+
cmsg=CMSG_FIRSTHDR(&msg);
1562+
if (msg.msg_flags& (MSG_TRUNC |MSG_CTRUNC)||
1563+
cmsg==NULL||
1564+
cmsg->cmsg_len<CMSG_LEN(sizeof(Cred))||
1565+
cmsg->cmsg_level!=SOL_SOCKET||
1566+
cmsg->cmsg_type!=SCM_CREDS)
1567+
{
1568+
ereport(LOG,
1569+
(errcode(ERRCODE_PROTOCOL_VIOLATION),
1570+
errmsg("could not get peer credentials: incorrect control message")));
1571+
return false;
1572+
}
1573+
15641574
cred= (Cred*)CMSG_DATA(cmsg);
15651575

15661576
pw=getpwuid(cred->cruid);

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

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -343,11 +343,12 @@ pg_local_sendauth(char *PQerrormsg, PGconn *conn)
343343
structmsghdrmsg;
344344

345345
#ifdefHAVE_STRUCT_CMSGCRED
346-
/* Prevent padding */
347-
charcmsgmem[sizeof(structcmsghdr)+sizeof(structcmsgcred)];
348-
349-
/* Point to start of first structure */
350-
structcmsghdr*cmsg= (structcmsghdr*)cmsgmem;
346+
structcmsghdr*cmsg;
347+
union
348+
{
349+
structcmsghdrhdr;
350+
unsignedcharbuf[CMSG_SPACE(sizeof(structcmsgcred))];
351+
}cmsgbuf;
351352
#endif
352353

353354
/*
@@ -363,11 +364,12 @@ pg_local_sendauth(char *PQerrormsg, PGconn *conn)
363364
msg.msg_iovlen=1;
364365

365366
#ifdefHAVE_STRUCT_CMSGCRED
366-
/* Create control header, FreeBSD */
367-
msg.msg_control=cmsg;
368-
msg.msg_controllen=sizeof(cmsgmem);
369-
memset(cmsg,0,sizeof(cmsgmem));
370-
cmsg->cmsg_len=sizeof(cmsgmem);
367+
/* FreeBSD needs us to set up a message that will be filled in by kernel */
368+
memset(&cmsgbuf,0,sizeof(cmsgbuf));
369+
msg.msg_control=&cmsgbuf.buf;
370+
msg.msg_controllen=sizeof(cmsgbuf.buf);
371+
cmsg=CMSG_FIRSTHDR(&msg);
372+
cmsg->cmsg_len=CMSG_LEN(sizeof(structcmsgcred));
371373
cmsg->cmsg_level=SOL_SOCKET;
372374
cmsg->cmsg_type=SCM_CREDS;
373375
#endif

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp