mirror of
https://github.com/postgres/postgres.git
synced 2025-06-29 10:41:53 +03:00
Fix portability bugs in use of credentials control messages for peer auth.
Even though our existing code for handling credentials control messages has been basically unchanged since 2001, it was fundamentally wrong: it did not ensure proper alignment of the supplied buffer, and it was calculating buffer sizes and message sizes incorrectly. This led to failures on platforms where alignment padding is relevant, for instance FreeBSD on 64-bit platforms, as seen in a recent Debian bug report passed on by Martin 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 me on Debian/kFreeBSD-amd64; since OpenBSD and NetBSD document the identical CMSG API, it should work there too. Back-patch to all supported branches.
This commit is contained in:
@ -709,11 +709,12 @@ pg_local_sendauth(PGconn *conn)
|
||||
struct msghdr msg;
|
||||
|
||||
#ifdef HAVE_STRUCT_CMSGCRED
|
||||
/* Prevent padding */
|
||||
char cmsgmem[sizeof(struct cmsghdr) + sizeof(struct cmsgcred)];
|
||||
|
||||
/* Point to start of first structure */
|
||||
struct cmsghdr *cmsg = (struct cmsghdr *) cmsgmem;
|
||||
struct cmsghdr *cmsg;
|
||||
union
|
||||
{
|
||||
struct cmsghdr hdr;
|
||||
unsigned char buf[CMSG_SPACE(sizeof(struct cmsgcred))];
|
||||
} cmsgbuf;
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -729,11 +730,12 @@ pg_local_sendauth(PGconn *conn)
|
||||
msg.msg_iovlen = 1;
|
||||
|
||||
#ifdef HAVE_STRUCT_CMSGCRED
|
||||
/* Create control header, FreeBSD */
|
||||
msg.msg_control = cmsg;
|
||||
msg.msg_controllen = sizeof(cmsgmem);
|
||||
memset(cmsg, 0, sizeof(cmsgmem));
|
||||
cmsg->cmsg_len = sizeof(cmsgmem);
|
||||
/* FreeBSD needs us to set up a message that will be filled in by kernel */
|
||||
memset(&cmsgbuf, 0, sizeof(cmsgbuf));
|
||||
msg.msg_control = &cmsgbuf.buf;
|
||||
msg.msg_controllen = sizeof(cmsgbuf.buf);
|
||||
cmsg = CMSG_FIRSTHDR(&msg);
|
||||
cmsg->cmsg_len = CMSG_LEN(sizeof(struct cmsgcred));
|
||||
cmsg->cmsg_level = SOL_SOCKET;
|
||||
cmsg->cmsg_type = SCM_CREDS;
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user