[Openswan dev] Re: PATCH: X.509 Off by one bug in crl processing (aka crl.pem crash bug)

Andreas Steffen andreas.steffen at strongsec.com
Tue Apr 20 11:09:19 CEST 2004


Hi Ken,

I checked my original code and I still think that it is correct.

I ran the following practical example:

   #define CRL_PATH   "/etc/ipsec.d/crls"  sizeof(CRL_PATH) = 18

the terminating null character is included by sizeof()

   filename = "cert.crl"                   strlen(filename) =  8

the terminating null character is not included by strlen()

   crl_uri.len = 7 + sizeof(CRL_PATH) + strlen(filename) = 33

crl_uri.len is the length of the composite string without the
terminating null character.

   allocate_bytes(crl_uri.len + 1) i.e. 34 bytes are allocated

the additional allocated byte is for the terminating null character
which will not be used by the crl fetching routine because
the ASN.1 coded crlDistributionPoints extracted from X.509 certificates
are *not* null terminated.

   sprintf(crl_uri.ptr, "file://%s/%s", CRL_PATH, filename);

results in the crlDistributionPoint

   "file:///etc/ipsec.d/crls/cert.crl"

with

    strlen(crl_uri.ptr) = 33

so the 34 allocated bytes are sufficient to store the
crlDistributionPoint *plus* the unused null character at the end.

Of course it is a safer approach to restrict the sprintf operation to the
maximum available memory. Thus the modification should be

   snprintf(crl_uri.ptr, crl_uri.len+1, "file://%s/%s", CRL_PATH, filename);

taking into account that an additional byte was allocated. Thus crl_uri.len
should not be increased by one and the following patch results:

@@ -336,7 +336,8 @@
                     crl_uri.ptr = alloc_bytes(crl_uri.len + 1, "crl uri");

                     /* build CRL file URI */
-                   sprintf(crl_uri.ptr, "file://%s/%s", CRL_PATH, filename);
+                   snprintf(crl_uri.ptr, crl_uri.len + 1, "file://%s/%s"
+                       , CRL_PATH, filename);

                     insert_crl(blob, crl_uri);
                 }

In openswan-2 the header file certs.h defines

   #define CRL_PATH	  plutopaths.crls.path

I don't know if sizeof(CRL_PATH) will still give the correct result
because the content of plutopaths.crls.path is assigned dynamically in log.c
during runtime. Probably a safer approach would be

-		    crl_uri.len = 7 + sizeof(CRL_PATH) + strlen(filename);
+		    crl_uri.len = 8 + strlen(CRL_PATH) + strlen(filename);

Regards

Andreas

Bantoft wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> 
> Hi Andreas,
> 
> We (myself + dhr + mcr) tracked down the 'crl.pem' bug to an off-by-one 
> error in x509.c, which is still present in Strongswan 2.0.2
> 
> Attached is a patch, and we switched to snprintf too, as dhr's been 
> snprintf happy for dealing with /proc stuff, as it's all been changed by 
> 2.4.25 kernels and higher.
> 
> This is against 1.4.8, but Strongswan 2.0.2 has the same code.
> 
> Note that in running pluto through valgrind, I also uncovered a read 
> error buried in the id.c code:
> 
> ==22686== Invalid read of size 1
> ==22686==    at 0x4207A995: strnlen (in /lib/tls/libc-2.3.2.so)
> ==22686==    by 0x420478C7: _IO_vfprintf_internal (in /lib/tls/libc-2.3.2.so)
> ==22686==    by 0x4206A363: _IO_vsnprintf (in /lib/tls/libc-2.3.2.so)
> ==22686==    by 0x4204F513: snprintf (in /lib/tls/libc-2.3.2.so)
> ==22686==    by 0x805D4D9: idtoa (id.c:325)
> ==22686==    by 0x805CD9C: calc_myid_str (id.c:82)
> ==22686==    by 0x805D008: set_myFQDN (id.c:142)
> ==22686==    by 0x805CD65: init_id (id.c:73)
> ==22686==  Address 0x75080362 is 0 bytes after a block of size 22 alloc'd
> ==22686==    at 0x7501D858: malloc (vg_replace_malloc.c:105)
> ==22686==    by 0x809676C: clone_bytes (alloc.c:179)
> ==22686==    by 0x805CFEC: set_myFQDN (id.c:140)
> 
> 
> The actual line that valgrind catches is
> 
> 
>     case ID_FQDN:
>         n = snprintf(dst, dstlen, "@%.*s", (int)id->name.len, id->name.ptr);
>         break;
> 
> However since variations of that snprintf() are above/below, it's really 
> elsewhere.
> 
> Ken
> 
> 
> Index: x509.c
> ===================================================================
> RCS file: /xelerance/master/openswan-2/programs/pluto/x509.c,v
> retrieving revision 1.9
> retrieving revision 1.10
> diff -u -d -r1.9 -r1.10
> - --- x509.c	21 Mar 2004 05:00:18 -0000	1.9
> +++ x509.c	20 Apr 2004 00:27:29 -0000	1.10
> @@ -1767,12 +1767,11 @@
>  		if (load_coded_file(filename, NULL, "crl", &blob, &pgp))
>  		{
>  		    chunk_t crl_uri;
> - -		    crl_uri.len = 7 + sizeof(CRL_PATH) + strlen(filename);
> +		    crl_uri.len = 8 + sizeof(CRL_PATH) + strlen(filename);
>  		    crl_uri.ptr = alloc_bytes(crl_uri.len + 1, "crl uri");
>  
>  		    /* build CRL file URI */
> - -		    sprintf(crl_uri.ptr, "file://%s/%s", CRL_PATH, filename);
> - -
> +		    snprintf(crl_uri.ptr, crl_uri.len, "file://%s/%s", CRL_PATH, filename);
>  		    insert_crl(blob, crl_uri);
>  		}
>  		free(filelist[n]);
> 
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.2.1 (GNU/Linux)
> 
> iD8DBQFAhHc4PiOgilmwgkgRAu0tAKCJfVsW6p/Q3Lrt2apgeqIOh4mB6wCeOpRF
> va8GQ9ABm0Z0CgYJiY2Tk5Q=
> =LNxZ
> -----END PGP SIGNATURE-----

=======================================================================
Andreas Steffen                   e-mail: andreas.steffen at strongsec.com
strongSec GmbH                    home:   http://www.strongsec.com
Alter Zürichweg 20                phone:  +41 1 730 80 64
CH-8952 Schlieren (Switzerland)   fax:    +41 1 730 80 65
==========================================[strong internet security]===



More information about the Dev mailing list