Blob Blame History Raw
From 49c5ff9ad0316960f11b180715b3a6906d42be83 Mon Sep 17 00:00:00 2001
From: Michael Scherer <misc@zarb.org>
Date: Sun, 21 Jul 2013 21:59:28 +0100
Subject: [PATCH] 'struct sockaddr' is not large enough to store a general
 sockaddr.

In particular, if IPv6 is used, then sizeof sockaddr_in6 > sizeof sockaddr,
resulting in a segfault:

https://bugzilla.redhat.com/show_bug.cgi?id=986601

RWMJ:
 - Minor formatting
 - Free tls->addr on normal exit path
---
 src/tls.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/src/tls.c b/src/tls.c
index 08e8638..390b03e 100644
--- a/src/tls.c
+++ b/src/tls.c
@@ -54,7 +54,7 @@
 struct tls {
   const char *name;             /* Can be NULL. */
   size_t instance_num;          /* Can be 0. */
-  struct sockaddr addr;
+  struct sockaddr *addr;
   socklen_t addrlen;
 };
 
@@ -65,6 +65,7 @@ free_tls (void *tlsv)
 {
   struct tls *tls = tlsv;
 
+  free (tls->addr);
   free (tls);
 }
 
@@ -118,8 +119,13 @@ tls_set_sockaddr (struct sockaddr *addr, socklen_t addrlen)
   struct tls *tls = pthread_getspecific (tls_key);
 
   if (tls) {
-    tls->addrlen = addrlen;
-    memcpy (&tls->addr, addr, addrlen);
+    free(tls->addr);
+    tls->addr = calloc (1, addrlen);
+    if (tls->addr == NULL) {
+      perror ("calloc");
+      exit (EXIT_FAILURE);
+    }
+    memcpy(tls->addr, addr, addrlen);
   }
 }
 
-- 
1.8.3.1