aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2017-03-26 17:35:35 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2017-03-26 17:35:35 -0400
commitc804c00d38f6a848f0d7e57a05ea5468fc5762b2 (patch)
treeed77860bee1d1cc34979f455ee99b751f816cdf0 /src
parent5674a258fd7e6eb496a4e91b0907077dfa7ee336 (diff)
downloadpostgresql-c804c00d38f6a848f0d7e57a05ea5468fc5762b2.tar.gz
postgresql-c804c00d38f6a848f0d7e57a05ea5468fc5762b2.zip
Fix unportable disregard of alignment requirements in RADIUS code.
The compiler is entitled to store a char[] local variable with no particular alignment requirement. Our RADIUS code cavalierly took such a local variable and cast its address to a struct type that does have alignment requirements. On an alignment-picky machine this would lead to bus errors. To fix, declare the local variable honestly, and then cast its address to char * for use in the I/O calls. Given the lack of field complaints, there must be very few if any people affected; but nonetheless this is a clear portability issue, so back-patch to all supported branches. Noted while looking at a Coverity complaint in the same code.
Diffstat (limited to 'src')
-rw-r--r--src/backend/libpq/auth.c21
1 files changed, 12 insertions, 9 deletions
diff --git a/src/backend/libpq/auth.c b/src/backend/libpq/auth.c
index 127c6cf45e9..f585ae0aed9 100644
--- a/src/backend/libpq/auth.c
+++ b/src/backend/libpq/auth.c
@@ -2355,14 +2355,16 @@ CheckCertAuth(Port *port)
*/
/*
- * RADIUS authentication is described in RFC2865 (and several
- * others).
+ * RADIUS authentication is described in RFC2865 (and several others).
*/
#define RADIUS_VECTOR_LENGTH 16
#define RADIUS_HEADER_LENGTH 20
#define RADIUS_MAX_PASSWORD_LENGTH 128
+/* Maximum size of a RADIUS packet we will create or accept */
+#define RADIUS_BUFFER_SIZE 1024
+
typedef struct
{
uint8 attribute;
@@ -2376,6 +2378,8 @@ typedef struct
uint8 id;
uint16 length;
uint8 vector[RADIUS_VECTOR_LENGTH];
+ /* this is a bit longer than strictly necessary: */
+ char pad[RADIUS_BUFFER_SIZE - RADIUS_VECTOR_LENGTH];
} radius_packet;
/* RADIUS packet types */
@@ -2392,9 +2396,6 @@ typedef struct
/* RADIUS service types */
#define RADIUS_AUTHENTICATE_ONLY 8
-/* Maximum size of a RADIUS packet we will create or accept */
-#define RADIUS_BUFFER_SIZE 1024
-
/* Seconds to wait - XXX: should be in a config variable! */
#define RADIUS_TIMEOUT 3
@@ -2429,10 +2430,12 @@ CheckRADIUSAuth(Port *port)
{
char *passwd;
char *identifier = "postgresql";
- char radius_buffer[RADIUS_BUFFER_SIZE];
- char receive_buffer[RADIUS_BUFFER_SIZE];
- radius_packet *packet = (radius_packet *) radius_buffer;
- radius_packet *receivepacket = (radius_packet *) receive_buffer;
+ radius_packet radius_send_pack;
+ radius_packet radius_recv_pack;
+ radius_packet *packet = &radius_send_pack;
+ radius_packet *receivepacket = &radius_recv_pack;
+ char *radius_buffer = (char *) &radius_send_pack;
+ char *receive_buffer = (char *) &radius_recv_pack;
int32 service = htonl(RADIUS_AUTHENTICATE_ONLY);
uint8 *cryptvector;
int encryptedpasswordlen;