[kernel/f18] Patch from David Howells to fix overflow on 32-bit X.509 certs (rhbz 861322)

Josh Boyer jwboyer at fedoraproject.org
Tue Oct 2 13:59:31 UTC 2012


commit 8c28af15557a250657c73cacfd0374c40cc28eae
Author: Josh Boyer <jwboyer at redhat.com>
Date:   Tue Oct 2 09:56:09 2012 -0400

    Patch from David Howells to fix overflow on 32-bit X.509 certs (rhbz 861322)

 kernel.spec               |    5 +-
 modsign-post-KS-jwb.patch |  174 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 178 insertions(+), 1 deletions(-)
---
diff --git a/kernel.spec b/kernel.spec
index 2048f27..db1dabf 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -62,7 +62,7 @@ Summary: The Linux kernel
 # For non-released -rc kernels, this will be appended after the rcX and
 # gitX tags, so a 3 here would become part of release "0.rcX.gitX.3"
 #
-%global baserelease 1
+%global baserelease 2
 %global fedora_build %{baserelease}
 
 # base_sublevel is the kernel version we're starting with and patching
@@ -2320,6 +2320,9 @@ fi
 #                 ||----w |
 #                 ||     ||
 %changelog
+* Tue Oct 02 2012 Josh Boyer <jwboyer at redhat.com>
+- Patch from David Howells to fix overflow on 32-bit X.509 certs (rhbz 861322)
+
 * Tue Oct  2 2012 Peter Robinson <pbrobinson at fedoraproject.org>
 - Update ARM configs for 3.6 final
 - Add highbank SATA driver for stability
diff --git a/modsign-post-KS-jwb.patch b/modsign-post-KS-jwb.patch
index 6dd81ff..ec61f34 100644
--- a/modsign-post-KS-jwb.patch
+++ b/modsign-post-KS-jwb.patch
@@ -9151,3 +9151,177 @@ index 83eb505..2beea56 100644
 -- 
 1.7.11.4
 
+The current choice of lifetime for the autogenerated X.509 of 100 years,
+putting the validTo date in 2112, causes problems on 32-bit systems where a
+32-bit time_t wraps in 2106.  64-bit x86_64 systems seem to be unaffected.
+
+This can result in something like:
+
+	Loading module verification certificates
+	X.509: Cert 6e03943da0f3b015ba6ed7f5e0cac4fe48680994 has expired
+	MODSIGN: Problem loading in-kernel X.509 certificate (-127)
+
+Or:
+
+	X.509: Cert 6e03943da0f3b015ba6ed7f5e0cac4fe48680994 is not yet valid
+	MODSIGN: Problem loading in-kernel X.509 certificate (-129)
+
+Instead of turning the dates into time_t values and comparing, turn the system
+clock and the ASN.1 dates into tm structs and compare those piecemeal instead.
+
+Reported-by: Rusty Russell <rusty at rustcorp.com.au>
+Signed-off-by: David Howells <dhowells at redhat.com>
+---
+
+ crypto/asymmetric_keys/x509_cert_parser.c |   25 ++++++++---------
+ crypto/asymmetric_keys/x509_parser.h      |    4 +--
+ crypto/asymmetric_keys/x509_public_key.c  |   42 ++++++++++++++++++++++++++---
+ 3 files changed, 51 insertions(+), 20 deletions(-)
+
+
+diff --git a/crypto/asymmetric_keys/x509_cert_parser.c b/crypto/asymmetric_keys/x509_cert_parser.c
+index 8fcac94..db07e8c 100644
+--- a/crypto/asymmetric_keys/x509_cert_parser.c
++++ b/crypto/asymmetric_keys/x509_cert_parser.c
+@@ -434,11 +434,10 @@ int x509_process_extension(void *context, size_t hdrlen,
+ /*
+  * Record a certificate time.
+  */
+-static int x509_note_time(time_t *_time,  size_t hdrlen,
++static int x509_note_time(struct tm *tm,  size_t hdrlen,
+ 			  unsigned char tag,
+ 			  const unsigned char *value, size_t vlen)
+ {
+-	unsigned YY, MM, DD, hh, mm, ss;
+ 	const unsigned char *p = value;
+ 
+ #define dec2bin(X) ((X) - '0')
+@@ -448,30 +447,30 @@ static int x509_note_time(time_t *_time,  size_t hdrlen,
+ 		/* UTCTime: YYMMDDHHMMSSZ */
+ 		if (vlen != 13)
+ 			goto unsupported_time;
+-		YY = DD2bin(p);
+-		if (YY > 50)
+-			YY += 1900;
++		tm->tm_year = DD2bin(p);
++		if (tm->tm_year >= 50)
++			tm->tm_year += 1900;
+ 		else
+-			YY += 2000;
++			tm->tm_year += 2000;
+ 	} else if (tag == ASN1_GENTIM) {
+ 		/* GenTime: YYYYMMDDHHMMSSZ */
+ 		if (vlen != 15)
+ 			goto unsupported_time;
+-		YY = DD2bin(p) * 100 + DD2bin(p);
++		tm->tm_year = DD2bin(p) * 100 + DD2bin(p);
+ 	} else {
+ 		goto unsupported_time;
+ 	}
+ 
+-	MM = DD2bin(p);
+-	DD = DD2bin(p);
+-	hh = DD2bin(p);
+-	mm = DD2bin(p);
+-	ss = DD2bin(p);
++	tm->tm_year -= 1900;
++	tm->tm_mon  = DD2bin(p) - 1;
++	tm->tm_mday = DD2bin(p);
++	tm->tm_hour = DD2bin(p);
++	tm->tm_min  = DD2bin(p);
++	tm->tm_sec  = DD2bin(p);
+ 
+ 	if (*p != 'Z')
+ 		goto unsupported_time;
+ 
+-	*_time = mktime(YY, MM, DD, hh, mm, ss);
+ 	return 0;
+ 
+ unsupported_time:
+diff --git a/crypto/asymmetric_keys/x509_parser.h b/crypto/asymmetric_keys/x509_parser.h
+index 635053f..f86dc5f 100644
+--- a/crypto/asymmetric_keys/x509_parser.h
++++ b/crypto/asymmetric_keys/x509_parser.h
+@@ -18,8 +18,8 @@ struct x509_certificate {
+ 	char		*subject;		/* Name of certificate subject */
+ 	char		*fingerprint;		/* Key fingerprint as hex */
+ 	char		*authority;		/* Authority key fingerprint as hex */
+-	time_t		valid_from;
+-	time_t		valid_to;
++	struct tm	valid_from;
++	struct tm	valid_to;
+ 	enum pkey_algo	pkey_algo : 8;		/* Public key algorithm */
+ 	enum pkey_algo	sig_pkey_algo : 8;	/* Signature public key algorithm */
+ 	enum pkey_hash_algo sig_hash_algo : 8;	/* Signature hash algorithm */
+diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c
+index 716917c..5ab736d 100644
+--- a/crypto/asymmetric_keys/x509_public_key.c
++++ b/crypto/asymmetric_keys/x509_public_key.c
+@@ -106,7 +106,7 @@ error_no_sig:
+ static int x509_key_preparse(struct key_preparsed_payload *prep)
+ {
+ 	struct x509_certificate *cert;
+-	time_t now;
++	struct tm now;
+ 	size_t srlen, sulen;
+ 	char *desc = NULL;
+ 	int ret;
+@@ -118,7 +118,14 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
+ 	pr_devel("Cert Issuer: %s\n", cert->issuer);
+ 	pr_devel("Cert Subject: %s\n", cert->subject);
+ 	pr_devel("Cert Key Algo: %s\n", pkey_algo[cert->pkey_algo]);
+-	pr_devel("Cert Valid: %lu - %lu\n", cert->valid_from, cert->valid_to);
++	printk("Cert Valid From: %04ld-%02d-%02d %02d:%02d:%02d\n",
++		 cert->valid_from.tm_year + 1900, cert->valid_from.tm_mon + 1,
++		 cert->valid_from.tm_mday, cert->valid_from.tm_hour,
++		 cert->valid_from.tm_min,  cert->valid_from.tm_sec);
++	printk("Cert Valid To: %04ld-%02d-%02d %02d:%02d:%02d\n",
++		 cert->valid_to.tm_year + 1900, cert->valid_to.tm_mon + 1,
++		 cert->valid_to.tm_mday, cert->valid_to.tm_hour,
++		 cert->valid_to.tm_min,  cert->valid_to.tm_sec);
+ 	pr_devel("Cert Signature: %s + %s\n",
+ 		 pkey_algo[cert->sig_pkey_algo],
+ 		 pkey_hash_algo[cert->sig_hash_algo]);
+@@ -130,13 +137,38 @@ static int x509_key_preparse(struct key_preparsed_payload *prep)
+ 		goto error_free_cert;
+ 	}
+ 
+-	now = CURRENT_TIME.tv_sec;
+-	if (now < cert->valid_from) {
++	time_to_tm(CURRENT_TIME.tv_sec, 0, &now);
++	printk("Now: %04ld-%02d-%02d %02d:%02d:%02d\n",
++		 now.tm_year + 1900, now.tm_mon + 1, now.tm_mday,
++		 now.tm_hour, now.tm_min,  now.tm_sec);
++	if (now.tm_year < cert->valid_from.tm_year ||
++	    (now.tm_year == cert->valid_from.tm_year &&
++	     (now.tm_mon < cert->valid_from.tm_mon ||
++	      (now.tm_mon == cert->valid_from.tm_mon &&
++	       (now.tm_mday < cert->valid_from.tm_mday ||
++		(now.tm_mday == cert->valid_from.tm_mday &&
++		 (now.tm_hour < cert->valid_from.tm_hour ||
++		  (now.tm_hour == cert->valid_from.tm_hour &&
++		   (now.tm_min < cert->valid_from.tm_min ||
++		    (now.tm_min == cert->valid_from.tm_min &&
++		     (now.tm_sec < cert->valid_from.tm_sec
++		      ))))))))))) {
+ 		pr_warn("Cert %s is not yet valid\n", cert->fingerprint);
+ 		ret = -EKEYREJECTED;
+ 		goto error_free_cert;
+ 	}
+-	if (now >= cert->valid_to) {
++	if (now.tm_year > cert->valid_to.tm_year ||
++	    (now.tm_year == cert->valid_to.tm_year &&
++	     (now.tm_mon > cert->valid_to.tm_mon ||
++	      (now.tm_mon == cert->valid_to.tm_mon &&
++	       (now.tm_mday > cert->valid_to.tm_mday ||
++		(now.tm_mday == cert->valid_to.tm_mday &&
++		 (now.tm_hour > cert->valid_to.tm_hour ||
++		  (now.tm_hour == cert->valid_to.tm_hour &&
++		   (now.tm_min > cert->valid_to.tm_min ||
++		    (now.tm_min == cert->valid_to.tm_min &&
++		     (now.tm_sec > cert->valid_to.tm_sec
++		      ))))))))))) {
+ 		pr_warn("Cert %s has expired\n", cert->fingerprint);
+ 		ret = -EKEYEXPIRED;
+ 		goto error_free_cert;
+


More information about the scm-commits mailing list