Dear maintainer and Waldemar,

Building opendkim with --with-gnutls disables support for ed25519, so I've 
taken a closer look at the problematic code and found the culprit code.

The error comes from the call to the openssl function RSA_sign in 
libopendkim/dkim.c:3945:

RSA_sign takes as fifth argument a reference to an unsigned int (4 byte) 
variable to return the length of the signature.
The opendkim-code uses a reference to the variable l of type size_t (unsigned 
long, 8 bytes on s390x) casted as (signed) int reference for this.
This is fatal for a big endian system.

I've attached to patches:
1.) fix-RSA_sign-call.patch: fixes the call to RSA_sign by using a temporary 
variable ui_l of the correct type unsigned int to get back the length from 
RSA_sign and savely assigns the returned value to l after the call.
2.) fix-printf-types.patch: fixes several calls of printf in dkim.c that use 
the signed int specifier "%d" to print size_t arguments. For C99-code "%zu" 
should be used for size_t variables.

best regards,
Martin
--- a/libopendkim/dkim.c
+++ b/libopendkim/dkim.c
@@ -440,7 +440,7 @@ dkim_add_plist(DKIM *dkim, DKIM_SET *set
 		plist = (DKIM_PLIST *) DKIM_MALLOC(dkim, sizeof(DKIM_PLIST));
 		if (plist == NULL)
 		{
-			dkim_error(dkim, "unable to allocate %d byte(s)",
+			dkim_error(dkim, "unable to allocate %zu byte(s)",
 			           sizeof(DKIM_PLIST));
 			return -1;
 		}
@@ -504,7 +504,7 @@ dkim_process_set(DKIM *dkim, dkim_set_t
 	hcopy = (u_char *) DKIM_MALLOC(dkim, len + 1);
 	if (hcopy == NULL)
 	{
-		dkim_error(dkim, "unable to allocate %d byte(s)", len + 1);
+		dkim_error(dkim, "unable to allocate %zu byte(s)", len + 1);
 		return DKIM_STAT_INTERNAL;
 	}
 	strlcpy((char *) hcopy, (char *) str, len + 1);
@@ -513,7 +513,7 @@ dkim_process_set(DKIM *dkim, dkim_set_t
 	if (set == NULL)
 	{
 		DKIM_FREE(dkim, hcopy);
-		dkim_error(dkim, "unable to allocate %d byte(s)",
+		dkim_error(dkim, "unable to allocate %zu byte(s)",
 		           sizeof(DKIM_SET));
 		return DKIM_STAT_INTERNAL;
 	}
@@ -1146,7 +1146,7 @@ dkim_privkey_load(DKIM *dkim)
 		crypto = DKIM_MALLOC(dkim, sizeof(struct dkim_crypto));
 		if (crypto == NULL)
 		{
-			dkim_error(dkim, "unable to allocate %d byte(s)",
+			dkim_error(dkim, "unable to allocate %zu byte(s)",
 			           sizeof(struct dkim_crypto));
 			return DKIM_STAT_NORESOURCE;
 		}
@@ -1939,7 +1939,7 @@ dkim_siglist_setup(DKIM *dkim)
 	dkim->dkim_siglist = DKIM_MALLOC(dkim, len);
 	if (dkim->dkim_siglist == NULL)
 	{
-		dkim_error(dkim, "unable to allocate %d byte(s)", len);
+		dkim_error(dkim, "unable to allocate %zu byte(s)", len);
 		return DKIM_STAT_NORESOURCE;
 	}
 
@@ -1953,7 +1953,7 @@ dkim_siglist_setup(DKIM *dkim)
 			int n;
 
 			dkim_error(dkim,
-			           "unable to allocate %d byte(s)",
+			           "unable to allocate %zu byte(s)",
 			           sizeof(DKIM_SIGINFO));
 			for (n = 0; n < c; n++)
 				DKIM_FREE(dkim, dkim->dkim_siglist[n]);
@@ -2337,7 +2337,7 @@ dkim_siglist_setup(DKIM *dkim)
 		if (dkim->dkim_siglist[c]->sig_sig == NULL)
 		{
 			dkim_error(dkim,
-			           "unable to allocate %d byte(s)",
+			           "unable to allocate %zu byte(s)",
 			           b64siglen);
 			return DKIM_STAT_NORESOURCE;
 		}
@@ -2904,7 +2904,7 @@ dkim_get_key(DKIM *dkim, DKIM_SIGINFO *s
 			if (sig->sig_key == NULL)
 			{
 				dkim_error(dkim,
-				           "unable to allocate %d byte(s)",
+				           "unable to allocate %zu byte(s)",
 				           osig->sig_b64keylen);
 				return DKIM_STAT_NORESOURCE;
 			}
@@ -3086,7 +3086,7 @@ dkim_get_key(DKIM *dkim, DKIM_SIGINFO *s
 		sig->sig_key = DKIM_MALLOC(dkim, sig->sig_b64keylen);
 		if (sig->sig_key == NULL)
 		{
-			dkim_error(dkim, "unable to allocate %d byte(s)",
+			dkim_error(dkim, "unable to allocate %zu byte(s)",
 			           sig->sig_b64keylen);
 			return DKIM_STAT_NORESOURCE;
 		}
@@ -3368,7 +3368,7 @@ dkim_eoh_sign(DKIM *dkim)
 		dkim->dkim_siglist = DKIM_MALLOC(dkim, sizeof(DKIM_SIGINFO **));
 		if (dkim->dkim_siglist == NULL)
 		{
-			dkim_error(dkim, "failed to allocate %d byte(s)",
+			dkim_error(dkim, "failed to allocate %zu byte(s)",
 			           sizeof(DKIM_SIGINFO *));
 			return DKIM_STAT_NORESOURCE;
 		}
@@ -3377,7 +3377,7 @@ dkim_eoh_sign(DKIM *dkim)
 		                                    sizeof(struct dkim_siginfo));
 		if (dkim->dkim_siglist[0] == NULL)
 		{
-			dkim_error(dkim, "failed to allocate %d byte(s)",
+			dkim_error(dkim, "failed to allocate %zu byte(s)",
 			           sizeof(struct dkim_siginfo));
 			return DKIM_STAT_NORESOURCE;
 		}
@@ -3810,7 +3810,7 @@ dkim_eom_sign(DKIM *dkim)
 	{
 		sig->sig_error = DKIM_SIGERROR_KEYTOOSMALL;
 		dkim_error(dkim,
-		           "private key too small (%d bits, need at least %d)",
+		           "private key too small (%u bits, need at least %u)",
 		           sig->sig_keybits,
 		           dkim->dkim_libhandle->dkiml_minkeybits);
 		return DKIM_STAT_SIGGEN;
@@ -3898,6 +3898,7 @@ dkim_eom_sign(DKIM *dkim)
 		int alg;
 		gnutls_datum_t dd;
 		struct dkim_crypto *crypto;
+		unsigned int ui_l = 0;
 
 		crypto = (struct dkim_crypto *) sig->sig_signature;
 
@@ -3952,7 +3953,7 @@ dkim_eom_sign(DKIM *dkim)
 		{
 			dkim_load_ssl_errors(dkim, 0);
 			dkim_error(dkim,
-			           "signature generation failed (status %d, length %d)",
+			           "signature generation failed (status %d, length %zu)",
 			           status, l);
 
 			RSA_free(crypto->crypto_key);
@@ -4003,7 +4004,7 @@ dkim_eom_sign(DKIM *dkim)
 		{
 			/* dkim_load_ssl_errors(dkim, 0); */
 			dkim_error(dkim,
-			           "signature generation failed (status %d, length %d, %s)",
+			           "signature generation failed (status %d, length %zu, %s)",
 			           status, l, ERR_error_string(ERR_get_error(), NULL));
 
 			RSA_free(crypto->crypto_key);
@@ -4034,7 +4035,7 @@ dkim_eom_sign(DKIM *dkim)
 	dkim->dkim_b64sig = DKIM_MALLOC(dkim, dkim->dkim_b64siglen);
 	if (dkim->dkim_b64sig == NULL)
 	{
-		dkim_error(dkim, "unable to allocate %d byte(s)",
+		dkim_error(dkim, "unable to allocate %zu byte(s)",
 		           dkim->dkim_b64siglen);
 #ifndef USE_GNUTLS
 		BIO_CLOBBER(crypto->crypto_keydata);
@@ -5445,7 +5446,7 @@ dkim_resign(DKIM *new, DKIM *old, _Bool
 	new->dkim_siglist = DKIM_MALLOC(new, sizeof(DKIM_SIGINFO *));
 	if (new->dkim_siglist == NULL)
 	{
-		dkim_error(new, "failed to allocate %d byte(s)",
+		dkim_error(new, "failed to allocate %zu byte(s)",
 		           sizeof(DKIM_SIGINFO *));
 		return DKIM_STAT_NORESOURCE;
 	}
@@ -5453,7 +5454,7 @@ dkim_resign(DKIM *new, DKIM *old, _Bool
 	new->dkim_siglist[0] = DKIM_MALLOC(new, sizeof(struct dkim_siginfo));
 	if (new->dkim_siglist[0] == NULL)
 	{
-		dkim_error(new, "failed to allocate %d byte(s)",
+		dkim_error(new, "failed to allocate %zu byte(s)",
 		           sizeof(struct dkim_siginfo));
 		return DKIM_STAT_NORESOURCE;
 	}
@@ -5640,7 +5641,7 @@ dkim_sig_process(DKIM *dkim, DKIM_SIGINF
 			if (crypto == NULL)
 			{
 				dkim_error(dkim,
-				           "unable to allocate %d byte(s)",
+				           "unable to allocate %zu byte(s)",
 				           sizeof(struct dkim_crypto));
 #ifndef USE_GNUTLS
 				BIO_CLOBBER(key);
@@ -6085,7 +6086,7 @@ dkim_ohdrs(DKIM *dkim, DKIM_SIGINFO *sig
 		dkim->dkim_zdecode = DKIM_MALLOC(dkim, MAXHEADERS);
 		if (dkim->dkim_zdecode == NULL)
 		{
-			dkim_error(dkim, "unable to allocate %d byte(s)",
+			dkim_error(dkim, "unable to allocate %zu byte(s)",
 			           strlen(z));
 			return DKIM_STAT_NORESOURCE;
 		}
@@ -6512,7 +6513,7 @@ dkim_header(DKIM *dkim, u_char *hdr, siz
 
 	if (h == NULL)
 	{
-		dkim_error(dkim, "unable to allocate %d byte(s)",
+		dkim_error(dkim, "unable to allocate %zu byte(s)",
 		           sizeof(struct dkim_header));
 		return DKIM_STAT_NORESOURCE;
 	}
@@ -9369,7 +9370,7 @@ dkim_add_querymethod(DKIM *dkim, const c
 	                                        sizeof(struct dkim_qmethod));
 	if (q == NULL)
 	{
-		dkim_error(dkim, "unable to allocate %d byte(s)",
+		dkim_error(dkim, "unable to allocate %zu byte(s)",
 		           sizeof(struct dkim_qmethod));
 		return DKIM_STAT_NORESOURCE;
 	}
@@ -9378,7 +9379,7 @@ dkim_add_querymethod(DKIM *dkim, const c
 	if (q->qm_type == NULL)
 	{
 		DKIM_FREE(dkim, q);
-		dkim_error(dkim, "unable to allocate %d byte(s)",
+		dkim_error(dkim, "unable to allocate %zu byte(s)",
 		           strlen(type) + 1);
 		return DKIM_STAT_NORESOURCE;
 	}
@@ -9390,7 +9391,7 @@ dkim_add_querymethod(DKIM *dkim, const c
 		{
 			DKIM_FREE(dkim, q->qm_type);
 			DKIM_FREE(dkim, q);
-			dkim_error(dkim, "unable to allocate %d byte(s)",
+			dkim_error(dkim, "unable to allocate %zu byte(s)",
 			           strlen(options) + 1);
 			return DKIM_STAT_NORESOURCE;
 		}
@@ -9497,7 +9498,7 @@ dkim_add_xtag(DKIM *dkim, const char *ta
 	x = (struct dkim_xtag *) DKIM_MALLOC(dkim, sizeof(struct dkim_xtag));
 	if (x == NULL)
 	{
-		dkim_error(dkim, "unable to allocate %d byte(s)",
+		dkim_error(dkim, "unable to allocate %zu byte(s)",
 		           sizeof(struct dkim_xtag));
 		return DKIM_STAT_NORESOURCE;
 	}
@@ -9657,7 +9658,7 @@ dkim_signhdrs(DKIM *dkim, const char **h
 
 			if (dkim->dkim_hdrre == NULL)
 			{
-				dkim_error(dkim, "could not allocate %d bytes",
+				dkim_error(dkim, "could not allocate %zu bytes",
 				           sizeof(regex_t));
 				return DKIM_STAT_INTERNAL;
 			}
--- a/libopendkim/dkim.c
+++ b/libopendkim/dkim.c
@@ -3932,6 +3932,7 @@ dkim_eom_sign(DKIM *dkim)
 	  {
 		int nid;
 		struct dkim_crypto *crypto;
+		unsigned int ui_l = 0;
 
 		crypto = (struct dkim_crypto *) sig->sig_signature;
 
@@ -3942,9 +3943,11 @@ dkim_eom_sign(DKIM *dkim)
 		    sig->sig_hashtype == DKIM_HASHTYPE_SHA256)
 			nid = NID_sha256;
 
+		/* use variable ui_l to savely get the length (unsigned int *) out of RSA_sign and into size_t type l */
 		status = RSA_sign(nid, digest, diglen,
-	                          crypto->crypto_out, (int *) &l,
+	                          crypto->crypto_out, &ui_l,
 		                  crypto->crypto_key);
+		l = ui_l;
 		if (status != 1 || l == 0)
 		{
 			dkim_load_ssl_errors(dkim, 0);

Reply via email to