From: Andreas Steffen Date: Sat, 11 May 2013 11:31:56 +0200 Subject: [PATCH] Check buffer size in atodn --- diff -urN strongswan-2.8.11/programs/pluto/connections.c strongswan-2.8.11-patched/programs/pluto/connections.c --- strongswan-2.8.11/programs/pluto/connections.c 2007-09-24 20:38:02.000000000 +0200 +++ strongswan-2.8.11-patched/programs/pluto/connections.c 2013-05-11 11:19:34.649252803 +0200 @@ -847,6 +847,7 @@ err_t ugh; dst->ca.ptr = temporary_cyclic_buffer(); + dst->ca.len = BUF_LEN; ugh = atodn(src->ca, &dst->ca); if (ugh != NULL) { diff -urN strongswan-2.8.11/programs/pluto/id.c strongswan-2.8.11-patched/programs/pluto/id.c --- strongswan-2.8.11/programs/pluto/id.c 2005-08-15 22:07:08.000000000 +0200 +++ strongswan-2.8.11-patched/programs/pluto/id.c 2013-05-11 11:19:34.653252849 +0200 @@ -165,7 +165,7 @@ /* we interpret this as an ASCII X.501 ID_DER_ASN1_DN */ id->kind = ID_DER_ASN1_DN; id->name.ptr = temporary_cyclic_buffer(); /* assign temporary buffer */ - id->name.len = 0; + id->name.len = BUF_LEN; /* convert from LDAP style or openssl x509 -subject style to ASN.1 DN * discard optional @ character in front of DN */ diff -urN strongswan-2.8.11/programs/pluto/x509.c strongswan-2.8.11-patched/programs/pluto/x509.c --- strongswan-2.8.11/programs/pluto/x509.c 2006-04-10 18:08:33.000000000 +0200 +++ strongswan-2.8.11-patched/programs/pluto/x509.c 2013-05-11 11:19:34.653252849 +0200 @@ -669,13 +669,14 @@ int whitespace = 0; int rdn_seq_len = 0; int rdn_set_len = 0; + int rdn_len = 0; int dn_seq_len = 0; int pos = 0; err_t ugh = NULL; u_char *dn_ptr = dn->ptr + 4; - + size_t max_len = dn->len - 4; state_t state = SEARCH_OID; do @@ -746,6 +747,16 @@ rdn_set_len = 1 + asn1_rdn_seq_len.len + rdn_seq_len; code_asn1_length(rdn_set_len, &asn1_rdn_set_len); + /* compute the length of the relative distinguished name */ + rdn_len = 1 + asn1_rdn_set_len.len + rdn_set_len; + + /* do we have sufficient buffer_space */ + if (dn_seq_len + rdn_len > max_len) + { + ugh = "insufficient buffer space for atodn()"; + break; + } + /* encode the relative distinguished name */ *dn_ptr++ = ASN1_SET; chunkcpy(dn_ptr, asn1_rdn_set_len); @@ -761,7 +772,7 @@ chunkcpy(dn_ptr, name); /* accumulate the length of the distinguished name sequence */ - dn_seq_len += 1 + asn1_rdn_set_len.len + rdn_set_len; + dn_seq_len += rdn_len; /* reset name and change state */ name = empty_chunk; @@ -771,7 +782,7 @@ case UNKNOWN_OID: break; } - } while (*src++ != '\0'); + } while (*src++ != '\0' && ugh == NULL); /* complete the distinguished name sequence*/ code_asn1_length(dn_seq_len, &asn1_dn_seq_len); @@ -780,6 +791,7 @@ dn_ptr = dn->ptr; *dn_ptr++ = ASN1_SEQUENCE; chunkcpy(dn_ptr, asn1_dn_seq_len); + return ugh; }