diff options
author | Natanael Copa <ncopa@alpinelinux.org> | 2013-05-17 09:40:13 +0000 |
---|---|---|
committer | Natanael Copa <ncopa@alpinelinux.org> | 2013-05-17 09:40:13 +0000 |
commit | ca6f0ad926d2fabed66a049927cea2eb176581da (patch) | |
tree | f8628a402e4a6f4f81be2b2963724e80c4a92e67 /main/openswan/openswan-libreswan-backport-949437-atodn.patch | |
parent | 8b2da88e8e533e78dfec86f9d1ed4e5cadfa4ca8 (diff) | |
download | aports-ca6f0ad926d2fabed66a049927cea2eb176581da.tar.bz2 aports-ca6f0ad926d2fabed66a049927cea2eb176581da.tar.xz |
main/openswan: securiy fix remote buffer overflow in atodn() (CVE-2013-2053)
patches are from http://libreswan.org/security/CVE-2013-2053/
fixes #1895
Diffstat (limited to 'main/openswan/openswan-libreswan-backport-949437-atodn.patch')
-rw-r--r-- | main/openswan/openswan-libreswan-backport-949437-atodn.patch | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/main/openswan/openswan-libreswan-backport-949437-atodn.patch b/main/openswan/openswan-libreswan-backport-949437-atodn.patch new file mode 100644 index 0000000000..524a75b20f --- /dev/null +++ b/main/openswan/openswan-libreswan-backport-949437-atodn.patch @@ -0,0 +1,278 @@ +diff -Naur openswan-2.6.32-orig/include/asn1.h openswan-2.6.32/include/asn1.h +--- openswan-2.6.32-orig/include/asn1.h 2010-12-17 20:23:54.000000000 -0500 ++++ openswan-2.6.32/include/asn1.h 2013-04-24 13:11:05.799140126 -0400 +@@ -84,8 +84,10 @@ + #define ASN1_BODY 0x20 + #define ASN1_RAW 0x40 + +-#define ASN1_INVALID_LENGTH 0xffffffff ++#define ASN1_INVALID_LENGTH (~(size_t) 0) /* largest size_t */ + ++#define ASN1_MAX_LEN (1U << (8*3)) /* don't handle objects with length greater than this */ ++#define ASN1_MAX_LEN_LEN 4 /* no coded length takes more than 4 bytes. */ + + /* definition of an ASN.1 object */ + +diff -Naur openswan-2.6.32-orig/include/id.h openswan-2.6.32/include/id.h +--- openswan-2.6.32-orig/include/id.h 2010-12-17 20:23:54.000000000 -0500 ++++ openswan-2.6.32/include/id.h 2013-04-24 13:11:05.799140126 -0400 +@@ -46,7 +46,7 @@ + extern const struct id *resolve_myid(const struct id *id); + extern void set_myFQDN(void); + +-extern err_t atoid(char *src, struct id *id, bool myid_ok); ++extern err_t atoid(char *src, struct id *id, bool myid_ok, bool oe_only); + extern void iptoid(const ip_address *ip, struct id *id); + extern unsigned char* temporary_cyclic_buffer(void); + extern int idtoa(const struct id *id, char *dst, size_t dstlen); +diff -Naur openswan-2.6.32-orig/lib/libopenswan/id.c openswan-2.6.32/lib/libopenswan/id.c +--- openswan-2.6.32-orig/lib/libopenswan/id.c 2010-12-17 20:23:54.000000000 -0500 ++++ openswan-2.6.32/lib/libopenswan/id.c 2013-04-24 13:11:05.799140126 -0400 +@@ -57,27 +57,29 @@ + + /* Convert textual form of id into a (temporary) struct id. + * Note that if the id is to be kept, unshare_id_content will be necessary. ++ * This function should be split into parts so the boolean arguments can be ++ * removed -- Paul + */ + err_t +-atoid(char *src, struct id *id, bool myid_ok) ++atoid(char *src, struct id *id, bool myid_ok, bool oe_only) + { + err_t ugh = NULL; + + *id = empty_id; + +- if (myid_ok && streq("%myid", src)) ++ if (!oe_only && myid_ok && streq("%myid", src)) + { + id->kind = ID_MYID; + } +- else if (streq("%fromcert", src)) ++ else if (!oe_only && streq("%fromcert", src)) + { + id->kind = ID_FROMCERT; + } +- else if (streq("%none", src)) ++ else if (!oe_only && streq("%none", src)) + { + id->kind = ID_NONE; + } +- else if (strchr(src, '=') != NULL) ++ else if (!oe_only && strchr(src, '=') != NULL) + { + /* we interpret this as an ASCII X.501 ID_DER_ASN1_DN */ + id->kind = ID_DER_ASN1_DN; +@@ -111,7 +113,7 @@ + { + if (*src == '@') + { +- if (*(src+1) == '#') ++ if (!oe_only && *(src+1) == '#') + { + /* if there is a second specifier (#) on the line + * we interprete this as ID_KEY_ID +@@ -122,7 +124,7 @@ + ugh = ttodata(src+2, 0, 16, (char *)id->name.ptr + , strlen(src), &id->name.len); + } +- else if (*(src+1) == '~') ++ else if (!oe_only && *(src+1) == '~') + { + /* if there is a second specifier (~) on the line + * we interprete this as a binary ID_DER_ASN1_DN +@@ -133,7 +135,7 @@ + ugh = ttodata(src+2, 0, 16, (char *)id->name.ptr + , strlen(src), &id->name.len); + } +- else if (*(src+1) == '[') ++ else if (!oe_only && *(src+1) == '[') + { + /* if there is a second specifier ([) on the line + * we interprete this as a text ID_KEY_ID, and we remove +diff -Naur openswan-2.6.32-orig/lib/libopenswan/secrets.c openswan-2.6.32/lib/libopenswan/secrets.c +--- openswan-2.6.32-orig/lib/libopenswan/secrets.c 2010-12-17 20:23:54.000000000 -0500 ++++ openswan-2.6.32/lib/libopenswan/secrets.c 2013-04-24 13:11:05.800140140 -0400 +@@ -1299,7 +1299,7 @@ + } + else + { +- ugh = atoid(flp->tok, &id, FALSE); ++ ugh = atoid(flp->tok, &id, FALSE, FALSE); + } + + if (ugh != NULL) +diff -Naur openswan-2.6.32-orig/lib/libopenswan/x509dn.c openswan-2.6.32/lib/libopenswan/x509dn.c +--- openswan-2.6.32-orig/lib/libopenswan/x509dn.c 2010-12-17 20:23:54.000000000 -0500 ++++ openswan-2.6.32/lib/libopenswan/x509dn.c 2013-04-24 13:11:05.801140153 -0400 +@@ -476,7 +476,7 @@ + {"TCGID" , {oid_TCGID, 12}, ASN1_PRINTABLESTRING} + }; + +-#define X501_RDN_ROOF 24 ++#define X501_RDN_ROOF elemsof(x501rdns) + + /* Maximum length of ASN.1 distinquished name */ + #define ASN1_BUF_LEN 512 +@@ -746,11 +746,11 @@ + UNKNOWN_OID = 4 + } state_t; + +- u_char oid_len_buf[3]; +- u_char name_len_buf[3]; +- u_char rdn_seq_len_buf[3]; +- u_char rdn_set_len_buf[3]; +- u_char dn_seq_len_buf[3]; ++ u_char oid_len_buf[ASN1_MAX_LEN_LEN]; ++ u_char name_len_buf[ASN1_MAX_LEN_LEN]; ++ u_char rdn_seq_len_buf[ASN1_MAX_LEN_LEN]; ++ u_char rdn_set_len_buf[ASN1_MAX_LEN_LEN]; ++ u_char dn_seq_len_buf[ASN1_MAX_LEN_LEN]; + + chunk_t asn1_oid_len = { oid_len_buf, 0 }; + chunk_t asn1_name_len = { name_len_buf, 0 }; +@@ -768,7 +768,7 @@ + + err_t ugh = NULL; + +- u_char *dn_ptr = dn->ptr + 4; ++ u_char *dn_ptr = dn->ptr + 1 + ASN1_MAX_LEN_LEN; /* leave room for prefix */ + + state_t state = SEARCH_OID; + +@@ -841,25 +841,37 @@ + code_asn1_length(rdn_set_len, &asn1_rdn_set_len); + + /* encode the relative distinguished name */ +- *dn_ptr++ = ASN1_SET; +- chunkcpy(dn_ptr, asn1_rdn_set_len); +- *dn_ptr++ = ASN1_SEQUENCE; +- chunkcpy(dn_ptr, asn1_rdn_seq_len); +- *dn_ptr++ = ASN1_OID; +- chunkcpy(dn_ptr, asn1_oid_len); +- chunkcpy(dn_ptr, x501rdns[pos].oid); +- /* encode the ASN.1 character string type of the name */ +- *dn_ptr++ = (x501rdns[pos].type == ASN1_PRINTABLESTRING +- && !is_printablestring(name))? ASN1_T61STRING : x501rdns[pos].type; +- chunkcpy(dn_ptr, asn1_name_len); +- chunkcpy(dn_ptr, name); +- +- /* accumulate the length of the distinguished name sequence */ +- dn_seq_len += 1 + asn1_rdn_set_len.len + rdn_set_len; +- +- /* reset name and change state */ +- name = empty_chunk; +- state = SEARCH_OID; ++ if (IDTOA_BUF < dn_ptr - dn->ptr ++ + 1 + asn1_rdn_set_len.len /* set */ ++ + 1 + asn1_rdn_seq_len.len /* sequence */ ++ + 1 + asn1_oid_len.len + x501rdns[pos].oid.len /* oid len, oid */ ++ + 1 + asn1_name_len.len + name.len /* type name */ ++ ) { ++ /* no room! */ ++ ugh = "DN is too big"; ++ state = UNKNOWN_OID; ++ /* I think that it is safe to continue (but perhaps pointless) */ ++ } else { ++ *dn_ptr++ = ASN1_SET; ++ chunkcpy(dn_ptr, asn1_rdn_set_len); ++ *dn_ptr++ = ASN1_SEQUENCE; ++ chunkcpy(dn_ptr, asn1_rdn_seq_len); ++ *dn_ptr++ = ASN1_OID; ++ chunkcpy(dn_ptr, asn1_oid_len); ++ chunkcpy(dn_ptr, x501rdns[pos].oid); ++ /* encode the ASN.1 character string type of the name */ ++ *dn_ptr++ = (x501rdns[pos].type == ASN1_PRINTABLESTRING ++ && !is_printablestring(name))? ASN1_T61STRING : x501rdns[pos].type; ++ chunkcpy(dn_ptr, asn1_name_len); ++ chunkcpy(dn_ptr, name); ++ ++ /* accumulate the length of the distinguished name sequence */ ++ dn_seq_len += 1 + asn1_rdn_set_len.len + rdn_set_len; ++ ++ /* reset name and change state */ ++ name = empty_chunk; ++ state = SEARCH_OID; ++ } + } + break; + case UNKNOWN_OID: +@@ -867,9 +879,10 @@ + } + } while (*src++ != '\0'); + +- /* complete the distinguished name sequence*/ +- code_asn1_length(dn_seq_len, &asn1_dn_seq_len); +- dn->ptr += 3 - asn1_dn_seq_len.len; ++ /* complete the distinguished name sequence: prefix it with ASN1_SEQUENCE and length */ ++ ++ code_asn1_length((size_t)dn_seq_len, &asn1_dn_seq_len); ++ dn->ptr += ASN1_MAX_LEN_LEN + 1 - 1 - asn1_dn_seq_len.len; + dn->len = 1 + asn1_dn_seq_len.len + dn_seq_len; + dn_ptr = dn->ptr; + *dn_ptr++ = ASN1_SEQUENCE; +diff -Naur openswan-2.6.32-orig/programs/pluto/connections.c openswan-2.6.32/programs/pluto/connections.c +--- openswan-2.6.32-orig/programs/pluto/connections.c 2013-04-24 13:10:30.520656796 -0400 ++++ openswan-2.6.32/programs/pluto/connections.c 2013-04-24 13:11:05.802140167 -0400 +@@ -891,7 +891,7 @@ + } + else + { +- err_t ugh = atoid(src->id, &dst->id, TRUE); ++ err_t ugh = atoid(src->id, &dst->id, TRUE, FALSE); + + if (ugh != NULL) + { +diff -Naur openswan-2.6.32-orig/programs/pluto/dnskey.c openswan-2.6.32/programs/pluto/dnskey.c +--- openswan-2.6.32-orig/programs/pluto/dnskey.c 2010-12-17 20:23:54.000000000 -0500 ++++ openswan-2.6.32/programs/pluto/dnskey.c 2013-04-24 13:11:05.803140181 -0400 +@@ -289,8 +289,12 @@ + if (*p == '@') + { + /* gateway specification in this record is @FQDN */ +- err_t ugh = atoid(p, gw_id, FALSE); + ++ if(strspn(p," ") >= IDTOA_BUF) { ++ return builddiag("malformed FQDN in TXT " our_TXT_attr_string ": ID too large for IDTOA_BUF"); ++ } ++ ++ err_t ugh = atoid(p, gw_id, FALSE, TRUE); /* only run OE related parts of atoid() */ + if (ugh != NULL) + return builddiag("malformed FQDN in TXT " our_TXT_attr_string ": %s" + , ugh); +diff -Naur openswan-2.6.32-orig/programs/pluto/myid.c openswan-2.6.32/programs/pluto/myid.c +--- openswan-2.6.32-orig/programs/pluto/myid.c 2010-12-17 20:23:54.000000000 -0500 ++++ openswan-2.6.32/programs/pluto/myid.c 2013-04-24 13:11:05.803140181 -0400 +@@ -103,7 +103,7 @@ + if (idstr != NULL) + { + struct id id; +- err_t ugh = atoid(idstr, &id, FALSE); ++ err_t ugh = atoid(idstr, &id, FALSE, FALSE); + + if (ugh != NULL) + { +diff -Naur openswan-2.6.32-orig/programs/pluto/rcv_whack.c openswan-2.6.32/programs/pluto/rcv_whack.c +--- openswan-2.6.32-orig/programs/pluto/rcv_whack.c 2013-04-24 13:10:30.392655041 -0400 ++++ openswan-2.6.32/programs/pluto/rcv_whack.c 2013-04-24 13:11:05.803140181 -0400 +@@ -243,7 +243,7 @@ + key_add_request(const struct whack_message *msg) + { + struct id keyid; +- err_t ugh = atoid(msg->keyid, &keyid, FALSE); ++ err_t ugh = atoid(msg->keyid, &keyid, FALSE, FALSE); + + if (ugh != NULL) + { +diff -Naur openswan-2.6.32-orig/programs/showhostkey/showhostkey.c openswan-2.6.32/programs/showhostkey/showhostkey.c +--- openswan-2.6.32-orig/programs/showhostkey/showhostkey.c 2010-12-17 20:23:54.000000000 -0500 ++++ openswan-2.6.32/programs/showhostkey/showhostkey.c 2013-04-24 13:11:05.804140194 -0400 +@@ -208,7 +208,7 @@ + struct secret *s; + err_t e; + +- e = atoid(idname, &id, FALSE); ++ e = atoid(idname, &id, FALSE, FALSE); + if(e) { + printf("%s: key '%s' is invalid\n", progname, idname); + exit(4); |