GnuTLS does not build on OS X 10.6 due to incompatibility with snprintf macro
Camillo Lugaresi
camillo.lugaresi at gmail.com
Wed Dec 29 05:26:42 CET 2010
Code built with gcc on Mac OS X 10.6 uses the object size checking feature of gcc by default (<http://gcc.gnu.org/onlinedocs/gcc/Object-Size-Checking.html>). This involves redefining several functions as macros; one of these functions is snprintf:
#define snprintf(str, len, ...) \
__builtin___snprintf_chk (str, len, 0, __darwin_obsz(str), __VA_ARGS__)
The usage of snprintf in src/serv.c in gnutls-2.10.4 is not compatible with that macro. serv.c attempts to use a macro (tmp2) that expands into two different arguments:
#define tmp2 &http_buffer[strlen(http_buffer)], len-strlen(http_buffer)
snprintf (tmp2, "%.2X", sesid[i]);
Due to how nested macro evaluation works, the snprintf macro sees tmp2 as a single argument, and copies it into __darwin_obsz(); then, when tmp2 is expanded, __darwin_obsz has two arguments, but it is only defined for one, and the result is a compilation error.
One way to work around this issue might be to define _FORTIFY_SOURCE=0 so that the snprintf macro is not defined, or simply doing an #undef snprintf for that file, but it seems safer and more portable to split tmp2 into two macros. I append a patch that does so.
Best regards,
Camillo Lugaresi
diff --git a/src/serv.c b/src/serv.c
index 0307b05..4b6658d 100644
--- a/src/serv.c
+++ b/src/serv.c
@@ -438,7 +438,8 @@ static const char DEFAULT_DATA[] =
/* Creates html with the current session information.
*/
-#define tmp2 &http_buffer[strlen(http_buffer)], len-strlen(http_buffer)
+#define tmp2b &http_buffer[strlen(http_buffer)]
+#define tmp2l len-strlen(http_buffer)
static char *
peer_print_info (gnutls_session_t session, int *ret_length,
const char *header)
@@ -512,11 +513,11 @@ peer_print_info (gnutls_session_t session, int *ret_length,
/* print session_id */
gnutls_session_get_id (session, sesid, &sesid_size);
- snprintf (tmp2, "\n<p>Session ID: <i>");
+ snprintf (tmp2b, tmp2l, "\n<p>Session ID: <i>");
for (i = 0; i < sesid_size; i++)
- snprintf (tmp2, "%.2X", sesid[i]);
- snprintf (tmp2, "</i></p>\n");
- snprintf (tmp2,
+ snprintf (tmp2b, tmp2l, "%.2X", sesid[i]);
+ snprintf (tmp2b, tmp2l, "</i></p>\n");
+ snprintf (tmp2b, tmp2l,
"<h5>If your browser supports session resuming, then you should see the "
"same session ID, when you press the <b>reload</b> button.</h5>\n");
@@ -530,7 +531,7 @@ peer_print_info (gnutls_session_t session, int *ret_length,
if (gnutls_server_name_get (session, dns, &dns_size, &type, 0) == 0)
{
- snprintf (tmp2, "\n<p>Server Name: %s</p>\n", dns);
+ snprintf (tmp2b, tmp2l, "\n<p>Server Name: %s</p>\n", dns);
}
}
@@ -541,7 +542,7 @@ peer_print_info (gnutls_session_t session, int *ret_length,
#ifdef ENABLE_SRP
if (kx_alg == GNUTLS_KX_SRP)
{
- snprintf (tmp2, "<p>Connected as user '%s'.</p>\n",
+ snprintf (tmp2b, tmp2l, "<p>Connected as user '%s'.</p>\n",
gnutls_srp_server_get_username (session));
}
#endif
@@ -549,7 +550,7 @@ peer_print_info (gnutls_session_t session, int *ret_length,
#ifdef ENABLE_PSK
if (kx_alg == GNUTLS_KX_PSK)
{
- snprintf (tmp2, "<p>Connected as user '%s'.</p>\n",
+ snprintf (tmp2b, tmp2l, "<p>Connected as user '%s'.</p>\n",
gnutls_psk_server_get_username (session));
}
#endif
@@ -557,7 +558,7 @@ peer_print_info (gnutls_session_t session, int *ret_length,
#ifdef ENABLE_ANON
if (kx_alg == GNUTLS_KX_ANON_DH)
{
- snprintf (tmp2,
+ snprintf (tmp2b, tmp2l,
"<p> Connect using anonymous DH (prime of %d bits)</p>\n",
gnutls_dh_get_prime_bits (session));
}
@@ -565,7 +566,7 @@ peer_print_info (gnutls_session_t session, int *ret_length,
if (kx_alg == GNUTLS_KX_DHE_RSA || kx_alg == GNUTLS_KX_DHE_DSS)
{
- snprintf (tmp2,
+ snprintf (tmp2b, tmp2l,
"Ephemeral DH using prime of <b>%d</b> bits.<br>\n",
gnutls_dh_get_prime_bits (session));
}
@@ -576,7 +577,7 @@ peer_print_info (gnutls_session_t session, int *ret_length,
tmp = gnutls_protocol_get_name (gnutls_protocol_get_version (session));
if (tmp == NULL)
tmp = str_unknown;
- snprintf (tmp2,
+ snprintf (tmp2b, tmp2l,
"<TABLE border=1><TR><TD>Protocol version:</TD><TD>%s</TD></TR>\n",
tmp);
@@ -587,44 +588,44 @@ peer_print_info (gnutls_session_t session, int *ret_length,
(session));
if (tmp == NULL)
tmp = str_unknown;
- snprintf (tmp2, "<TR><TD>Certificate Type:</TD><TD>%s</TD></TR>\n", tmp);
+ snprintf (tmp2b, tmp2l, "<TR><TD>Certificate Type:</TD><TD>%s</TD></TR>\n", tmp);
}
tmp = gnutls_kx_get_name (kx_alg);
if (tmp == NULL)
tmp = str_unknown;
- snprintf (tmp2, "<TR><TD>Key Exchange:</TD><TD>%s</TD></TR>\n", tmp);
+ snprintf (tmp2b, tmp2l, "<TR><TD>Key Exchange:</TD><TD>%s</TD></TR>\n", tmp);
tmp = gnutls_compression_get_name (gnutls_compression_get (session));
if (tmp == NULL)
tmp = str_unknown;
- snprintf (tmp2, "<TR><TD>Compression</TD><TD>%s</TD></TR>\n", tmp);
+ snprintf (tmp2b, tmp2l, "<TR><TD>Compression</TD><TD>%s</TD></TR>\n", tmp);
tmp = gnutls_cipher_get_name (gnutls_cipher_get (session));
if (tmp == NULL)
tmp = str_unknown;
- snprintf (tmp2, "<TR><TD>Cipher</TD><TD>%s</TD></TR>\n", tmp);
+ snprintf (tmp2b, tmp2l, "<TR><TD>Cipher</TD><TD>%s</TD></TR>\n", tmp);
tmp = gnutls_mac_get_name (gnutls_mac_get (session));
if (tmp == NULL)
tmp = str_unknown;
- snprintf (tmp2, "<TR><TD>MAC</TD><TD>%s</TD></TR>\n", tmp);
+ snprintf (tmp2b, tmp2l, "<TR><TD>MAC</TD><TD>%s</TD></TR>\n", tmp);
tmp = gnutls_cipher_suite_get_name (kx_alg,
gnutls_cipher_get (session),
gnutls_mac_get (session));
if (tmp == NULL)
tmp = str_unknown;
- snprintf (tmp2, "<TR><TD>Ciphersuite</TD><TD>%s</TD></TR></p></TABLE>\n",
+ snprintf (tmp2b, tmp2l, "<TR><TD>Ciphersuite</TD><TD>%s</TD></TR></p></TABLE>\n",
tmp);
if (crtinfo)
{
- snprintf(tmp2, "<hr><PRE>%s\n</PRE>\n", crtinfo);
+ snprintf(tmp2b, tmp2l, "<hr><PRE>%s\n</PRE>\n", crtinfo);
free (crtinfo);
}
- snprintf(tmp2, "<hr><P>Your HTTP header was:<PRE>%s</PRE></P>\n" HTTP_END, header);
+ snprintf(tmp2b, tmp2l, "<hr><P>Your HTTP header was:<PRE>%s</PRE></P>\n" HTTP_END, header);
*ret_length = strlen (http_buffer);
More information about the Gnutls-devel
mailing list