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

Commite73bd1e

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 parent73bd34c commite73bd1e

File tree

2 files changed

+47
-35
lines changed

2 files changed

+47
-35
lines changed

‎src/backend/libpq/auth.c

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1758,7 +1758,7 @@ static bool
17581758
ident_unix(intsock,char*ident_user)
17591759
{
17601760
#if defined(HAVE_GETPEEREID)
1761-
/* OpenBSD style: */
1761+
/* OpenBSD(also Mac OS X)style:use getpeereid() */
17621762
uid_tuid;
17631763
gid_tgid;
17641764
structpasswd*pass;
@@ -1817,7 +1817,7 @@ ident_unix(int sock, char *ident_user)
18171817

18181818
return true;
18191819
#elif defined(HAVE_GETPEERUCRED)
1820-
/* Solaris > 10 */
1820+
/* Solaris > 10: use getpeerucred() */
18211821
uid_tuid;
18221822
structpasswd*pass;
18231823
ucred_t*ucred;
@@ -1854,9 +1854,7 @@ ident_unix(int sock, char *ident_user)
18541854

18551855
return true;
18561856
#elif defined(HAVE_STRUCT_CMSGCRED)|| defined(HAVE_STRUCT_FCRED)|| (defined(HAVE_STRUCT_SOCKCRED)&& defined(LOCAL_CREDS))
1857-
structmsghdrmsg;
1858-
1859-
/* Credentials structure */
1857+
/* Assorted BSDen: use a credentials control message */
18601858
#if defined(HAVE_STRUCT_CMSGCRED)
18611859
typedefstructcmsgcredCred;
18621860

@@ -1870,43 +1868,55 @@ ident_unix(int sock, char *ident_user)
18701868

18711869
#definecruid sc_uid
18721870
#endif
1873-
Cred*cred;
1874-
1875-
/* Compute size without padding */
1876-
charcmsgmem[ALIGN(sizeof(structcmsghdr))+ALIGN(sizeof(Cred))];/* for NetBSD */
1877-
1878-
/* Point to start of first structure */
1879-
structcmsghdr*cmsg= (structcmsghdr*)cmsgmem;
18801871

1872+
structmsghdrmsg;
1873+
structcmsghdr*cmsg;
1874+
union
1875+
{
1876+
structcmsghdrhdr;
1877+
unsignedcharbuf[CMSG_SPACE(sizeof(Cred))];
1878+
}cmsgbuf;
18811879
structioveciov;
18821880
charbuf;
1881+
Cred*cred;
18831882
structpasswd*pw;
18841883

1885-
memset(&msg,0,sizeof(msg));
1886-
msg.msg_iov=&iov;
1887-
msg.msg_iovlen=1;
1888-
msg.msg_control= (char*)cmsg;
1889-
msg.msg_controllen=sizeof(cmsgmem);
1890-
memset(cmsg,0,sizeof(cmsgmem));
1891-
18921884
/*
1893-
* The one characterwhich is received here is not meaningful; its
1894-
*purposesis only to make sure that recvmsg() blocks long enough for the
1895-
*otherside to send its credentials.
1885+
* The one characterthat is received here is not meaningful; its purpose
1886+
* is only to make sure that recvmsg() blocks long enough for the other
1887+
* side to send its credentials.
18961888
*/
18971889
iov.iov_base=&buf;
18981890
iov.iov_len=1;
18991891

1900-
if (recvmsg(sock,&msg,0)<0||
1901-
cmsg->cmsg_len<sizeof(cmsgmem)||
1902-
cmsg->cmsg_type!=SCM_CREDS)
1892+
memset(&msg,0,sizeof(msg));
1893+
msg.msg_iov=&iov;
1894+
msg.msg_iovlen=1;
1895+
msg.msg_control=&cmsgbuf.buf;
1896+
msg.msg_controllen=sizeof(cmsgbuf.buf);
1897+
memset(&cmsgbuf,0,sizeof(cmsgbuf));
1898+
1899+
if (recvmsg(sock,&msg,0)<0)
19031900
{
19041901
ereport(LOG,
19051902
(errcode_for_socket_access(),
19061903
errmsg("could not get peer credentials: %m")));
19071904
return false;
19081905
}
19091906

1907+
cmsg=CMSG_FIRSTHDR(&msg);
1908+
if (msg.msg_flags& (MSG_TRUNC |MSG_CTRUNC)||
1909+
cmsg==NULL||
1910+
cmsg->cmsg_len<CMSG_LEN(sizeof(Cred))||
1911+
cmsg->cmsg_level!=SOL_SOCKET||
1912+
cmsg->cmsg_type!=SCM_CREDS)
1913+
{
1914+
ereport(LOG,
1915+
(errcode(ERRCODE_PROTOCOL_VIOLATION),
1916+
errmsg("could not get peer credentials: incorrect control message")));
1917+
return false;
1918+
}
1919+
19101920
cred= (Cred*)CMSG_DATA(cmsg);
19111921

19121922
pw=getpwuid(cred->cruid);

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

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -694,11 +694,12 @@ pg_local_sendauth(PGconn *conn)
694694
structmsghdrmsg;
695695

696696
#ifdefHAVE_STRUCT_CMSGCRED
697-
/* Prevent padding */
698-
charcmsgmem[sizeof(structcmsghdr)+sizeof(structcmsgcred)];
699-
700-
/* Point to start of first structure */
701-
structcmsghdr*cmsg= (structcmsghdr*)cmsgmem;
697+
structcmsghdr*cmsg;
698+
union
699+
{
700+
structcmsghdrhdr;
701+
unsignedcharbuf[CMSG_SPACE(sizeof(structcmsgcred))];
702+
}cmsgbuf;
702703
#endif
703704

704705
/*
@@ -714,11 +715,12 @@ pg_local_sendauth(PGconn *conn)
714715
msg.msg_iovlen=1;
715716

716717
#ifdefHAVE_STRUCT_CMSGCRED
717-
/* Create control header, FreeBSD */
718-
msg.msg_control=cmsg;
719-
msg.msg_controllen=sizeof(cmsgmem);
720-
memset(cmsg,0,sizeof(cmsgmem));
721-
cmsg->cmsg_len=sizeof(cmsgmem);
718+
/* FreeBSD needs us to set up a message that will be filled in by kernel */
719+
memset(&cmsgbuf,0,sizeof(cmsgbuf));
720+
msg.msg_control=&cmsgbuf.buf;
721+
msg.msg_controllen=sizeof(cmsgbuf.buf);
722+
cmsg=CMSG_FIRSTHDR(&msg);
723+
cmsg->cmsg_len=CMSG_LEN(sizeof(structcmsgcred));
722724
cmsg->cmsg_level=SOL_SOCKET;
723725
cmsg->cmsg_type=SCM_CREDS;
724726
#endif

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp