Date: Fri, 12 Jun 2015 07:33:56 +0000 (UTC) From: Xin LI <delphij@FreeBSD.org> To: doc-committers@freebsd.org, svn-doc-all@freebsd.org, svn-doc-head@freebsd.org Subject: svn commit: r46817 - in head/share: security/advisories security/patches/SA-15:10 xml Message-ID: <201506120733.t5C7XuXj018873@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: delphij Date: Fri Jun 12 07:33:55 2015 New Revision: 46817 URL: https://svnweb.freebsd.org/changeset/doc/46817 Log: Add advisory for SA-15:10.openssl. Added: head/share/security/advisories/FreeBSD-SA-15:10.openssl.asc (contents, props changed) head/share/security/patches/SA-15:10/ head/share/security/patches/SA-15:10/openssl-10.1.patch (contents, props changed) head/share/security/patches/SA-15:10/openssl-10.1.patch.asc (contents, props changed) head/share/security/patches/SA-15:10/openssl-8.4.patch (contents, props changed) head/share/security/patches/SA-15:10/openssl-8.4.patch.asc (contents, props changed) Modified: head/share/xml/advisories.xml Added: head/share/security/advisories/FreeBSD-SA-15:10.openssl.asc ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/share/security/advisories/FreeBSD-SA-15:10.openssl.asc Fri Jun 12 07:33:55 2015 (r46817) @@ -0,0 +1,202 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA512 + +============================================================================= +FreeBSD-SA-15:10.openssl Security Advisory + The FreeBSD Project + +Topic: Multiple OpenSSL vulnerabilities + +Category: contrib +Module: openssl +Announced: 2015-06-12 +Affects: All supported versions of FreeBSD. +Corrected: 2015-06-11 19:07:45 UTC (stable/10, 10.1-STABLE) + 2015-06-12 07:23:55 UTC (releng/10.1, 10.1-RELEASE-p12) + 2015-06-11 19:39:27 UTC (stable/9, 9.3-STABLE) + 2015-06-12 07:23:55 UTC (releng/9.3, 9.3-RELEASE-p16) + 2015-06-11 19:39:27 UTC (stable/8, 8.4-STABLE) + 2015-06-12 07:23:55 UTC (releng/8.4, 8.4-RELEASE-p30) +CVE Name: CVE-2015-1788, CVE-2015-1789, CVE-2015-1790, CVE-2015-1791 + CVE-2015-1792, CVE-2015-4000 + +For general information regarding FreeBSD Security Advisories, +including descriptions of the fields above, security branches, and the +following sections, please visit <URL:https://security.FreeBSD.org/>. + +I. Background + +FreeBSD includes software from the OpenSSL Project. The OpenSSL Project is +a collaborative effort to develop a robust, commercial-grade, full-featured +Open Source toolkit implementing the Secure Sockets Layer (SSL v2/v3) +and Transport Layer Security (TLS v1) protocols as well as a full-strength +general purpose cryptography library. + +II. Problem Description + +A vulnerability in the TLS protocol would allow a man-in-the-middle +attacker to downgrade vulnerable TLS connections using ephemeral +Diffie-Hellman key exchange to 512-bit export-grade cryptography. +This vulnerability is also known as Logjam [CVE-2015-4000]. + +When processing an ECParameters structure OpenSSL enters an infinite +loop if the curve specified is over a specially malformed binary +polynomial field. [CVE-2015-1788] + +X509_cmp_time does not properly check the length of the ASN1_TIME +string and can read a few bytes out of bounds. In addition, +X509_cmp_time accepts an arbitrary number of fractional seconds in +the time string. [CVE-2015-1789] + +The PKCS#7 parsing code does not handle missing inner EncryptedContent +correctly. [CVE-2015-1790] + +When verifying a signedData message the CMS code can enter an infinite +loop if presented with an unknown hash function OID. [CVE-2015-1792] + +If a NewSessionTicket is received by a multi-threaded client when +attempting to reuse a previous ticket then a race condition can occur, +potentially leading to a double free of the ticket data. [CVE-2015-1791] + +The OpenSSL advisory also describes a problem that is identified as +CVE-2014-8176, which is already fixed by an earlier FreeBSD Errata +Notice, FreeBSD-EN-15:02.openssl. + +III. Impact + +A man-in-the-middle attacker may be able to downgrade vulnerable TLS +connections using ephemeral Diffie-Hellman key exchange to 512-bit +export-grade cryptography. [CVE-2015-4000]. On FreeBSD 10.1, the +patch contains a countermeasure for clients by rejecting handshakes +with DH parameters shorter than 768 bits. + +An attacker who is able to use a certificate to authenticate with +a remote system perform denial of service against any system which +processes public keys, certificate requests or certificates. +[CVE-2015-1788]. This affects FreeBSD 10.1 only, as the problem +was no longer exist in OpenSSL 0.9.8 series since July 2012. + +An attacker can use the CVE-2015-1789 issue by using specifically +crafted certificates and CRLs of various sizes and potentially +cause a segmentation fault, resulting in a DoS on applications that +verify certificates or CRLs. + +An attacker who can create specifically crafted malformed ASN.1-encoded +PKCS#7 blobs with missing content and trigger a NULL pointer dereference +on parsing. [CVE-2015-1790]. Applications that decrypt PKCS#7 data +or otherwise parse PKCS#7 structures from untrusted sources are +affected. OpenSSL clients and servers are not affected. + +An attacker can perform denial of service against any system which +verifies signedData messages using the CMS code. [CVE-2015-1792] + +An attacker may be able to crash multi-thread applications that +supports resumed TLS handshakes. [CVE-2015-1791] + +IV. Workaround + +No workaround is available. + +V. Solution + +Perform one of the following: + +1) Upgrade your vulnerable system to a supported FreeBSD stable or +release / security branch (releng) dated after the correction date. + +2) To update your vulnerable system via a binary patch: + +Systems running a RELEASE version of FreeBSD on the i386 or amd64 +platforms can be updated via the freebsd-update(8) utility: + +# freebsd-update fetch +# freebsd-update install + +3) To update your vulnerable system via a source code patch: + +The following patches have been verified to apply to the applicable +FreeBSD release branches. + +a) Download the relevant patch from the location below, and verify the +detached PGP signature using your PGP utility. + +[FreeBSD 10.1] +# fetch https://security.FreeBSD.org/patches/SA-15:10/openssl-10.1.patch +# fetch https://security.FreeBSD.org/patches/SA-15:10/openssl-10.1.patch.asc +# gpg --verify openssl-10.1.patch.asc + +[FreeBSD 9.3 and 8.4] +# fetch https://security.FreeBSD.org/patches/SA-15:10/openssl-8.4.patch +# fetch https://security.FreeBSD.org/patches/SA-15:10/openssl-8.4.patch.asc +# gpg --verify openssl-8.4.patch.asc + +b) Apply the patch. Execute the following commands as root: + +# cd /usr/src +# patch < /path/to/patch + +c) Recompile the operating system using buildworld and installworld as +described in <URL:https://www.FreeBSD.org/handbook/makeworld.html>. + +Restart all deamons using the library, or reboot the system. + +VI. Correction details + +The following list contains the correction revision numbers for each +affected branch. + +Branch/path Revision +- ------------------------------------------------------------------------- +stable/8/ r284286 +releng/8.4/ r284295 +stable/9/ r284286 +releng/9.3/ r284295 +stable/10/ r284285 +releng/10.1/ r284295 +- ------------------------------------------------------------------------- + +To see which files were modified by a particular revision, run the +following command, replacing NNNNNN with the revision number, on a +machine with Subversion installed: + +# svn diff -cNNNNNN --summarize svn://svn.freebsd.org/base + +Or visit the following URL, replacing NNNNNN with the revision number: + +<URL:https://svnweb.freebsd.org/base?view=revision&revision=NNNNNN> + +VII. References + +<URL:https://www.openssl.org/news/secadv_20150611.txt> + +<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1788> + +<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1789> + +<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1790> + +<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1791> + +<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-1792> + +<URL:https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2015-4000> + +The latest revision of this advisory is available at +<URL:https://security.FreeBSD.org/advisories/FreeBSD-SA-15:10.openssl.asc> +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v2.1.4 (FreeBSD) + +iQIcBAEBCgAGBQJVeopGAAoJEO1n7NZdz2rnzhQP/Ak6el188Y+7QbEYVfCZ7eG8 +BQLj5TMGHV5swSKVlPcEuBlMwTjpgB5Gqhc8luDS0eIAuJGdcMPSrZDdXxWQFtPf +pbfIwp/ElFc7d6ut0Y8t6fFLJbhTOoHJpzTGkFRfJkjinGOx7OZQPeLJsxSubbnL +JKugZ3diH6yk6IPMf9SvhO/kYXUF1VbXQvHNTnqgdhFVkgF6tK22Pkl2XoJ9EHbh +vBXft1yJwiYlZ//DxZuScTUj1pHYzK3bOpg//REJMWCMj1RVwQr2EyDa0Q2cT02d +eRnSZykXD69eybyzEck+BvwnUYYJICimnHuE5t78UIr0D/NWyOAZTQ99z5TID5aV +HXkcil+1E/Q+xBB4+5UOOnESf6cmiWwewQOVvD26ZY39E6oJXvsrWnyxIuCG6DL9 +sLtxB6iTYlTX5Civ/VJX8H7rFiw4UwMembthvGzck22026iHjplWM3GCWz0E8O3R +PrXBHjAzNFawK3owNMxFSUFTuFw/qY7EEwJ3SKCEC+hoxcLOl26NMxrQKRIAUk+I +MMOaZfvOh2uM19y9SJZz8+sqU8gIm7ihDm5fuSkO8kY0jdvLwyS9bXAejN/lZ6oJ +TyfTDDyXDOdaPpnpQehh6vQV0NiaJ+WXfGhfiE8/G/t6b1E0LlCaaGJTpYkildGe +vVCM4Nyx4S9WDFOi76ug +=dyhg +-----END PGP SIGNATURE----- Added: head/share/security/patches/SA-15:10/openssl-10.1.patch ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/share/security/patches/SA-15:10/openssl-10.1.patch Fri Jun 12 07:33:55 2015 (r46817) @@ -0,0 +1,1897 @@ +Index: crypto/openssl/apps/dhparam.c +=================================================================== +--- crypto/openssl/apps/dhparam.c (revision 284286) ++++ crypto/openssl/apps/dhparam.c (working copy) +@@ -130,7 +130,7 @@ + #undef PROG + #define PROG dhparam_main + +-#define DEFBITS 512 ++#define DEFBITS 2048 + + /* -inform arg - input format - default PEM (DER or PEM) + * -outform arg - output format - default PEM +@@ -253,7 +253,7 @@ bad: + BIO_printf(bio_err," -C Output C code\n"); + BIO_printf(bio_err," -2 generate parameters using 2 as the generator value\n"); + BIO_printf(bio_err," -5 generate parameters using 5 as the generator value\n"); +- BIO_printf(bio_err," numbits number of bits in to generate (default 512)\n"); ++ BIO_printf(bio_err," numbits number of bits in to generate (default 2048)\n"); + #ifndef OPENSSL_NO_ENGINE + BIO_printf(bio_err," -engine e use engine e, possibly a hardware device.\n"); + #endif +Index: crypto/openssl/apps/gendh.c +=================================================================== +--- crypto/openssl/apps/gendh.c (revision 284286) ++++ crypto/openssl/apps/gendh.c (working copy) +@@ -78,7 +78,7 @@ + #include <openssl/x509.h> + #include <openssl/pem.h> + +-#define DEFBITS 512 ++#define DEFBITS 2048 + #undef PROG + #define PROG gendh_main + +Index: crypto/openssl/apps/s_server.c +=================================================================== +--- crypto/openssl/apps/s_server.c (revision 284286) ++++ crypto/openssl/apps/s_server.c (working copy) +@@ -214,7 +214,7 @@ static int generate_session_id(const SSL *ssl, uns + unsigned int *id_len); + #ifndef OPENSSL_NO_DH + static DH *load_dh_param(const char *dhfile); +-static DH *get_dh512(void); ++static DH *get_dh2048(void); + #endif + + #ifdef MONOLITH +@@ -222,29 +222,49 @@ static void s_server_init(void); + #endif + + #ifndef OPENSSL_NO_DH +-static unsigned char dh512_p[]={ +- 0xDA,0x58,0x3C,0x16,0xD9,0x85,0x22,0x89,0xD0,0xE4,0xAF,0x75, +- 0x6F,0x4C,0xCA,0x92,0xDD,0x4B,0xE5,0x33,0xB8,0x04,0xFB,0x0F, +- 0xED,0x94,0xEF,0x9C,0x8A,0x44,0x03,0xED,0x57,0x46,0x50,0xD3, +- 0x69,0x99,0xDB,0x29,0xD7,0x76,0x27,0x6B,0xA2,0xD3,0xD4,0x12, +- 0xE2,0x18,0xF4,0xDD,0x1E,0x08,0x4C,0xF6,0xD8,0x00,0x3E,0x7C, +- 0x47,0x74,0xE8,0x33, +- }; +-static unsigned char dh512_g[]={ ++static unsigned char dh2048_p[] = { ++ 0xF6,0x42,0x57,0xB7,0x08,0x7F,0x08,0x17,0x72,0xA2,0xBA,0xD6, ++ 0xA9,0x42,0xF3,0x05,0xE8,0xF9,0x53,0x11,0x39,0x4F,0xB6,0xF1, ++ 0x6E,0xB9,0x4B,0x38,0x20,0xDA,0x01,0xA7,0x56,0xA3,0x14,0xE9, ++ 0x8F,0x40,0x55,0xF3,0xD0,0x07,0xC6,0xCB,0x43,0xA9,0x94,0xAD, ++ 0xF7,0x4C,0x64,0x86,0x49,0xF8,0x0C,0x83,0xBD,0x65,0xE9,0x17, ++ 0xD4,0xA1,0xD3,0x50,0xF8,0xF5,0x59,0x5F,0xDC,0x76,0x52,0x4F, ++ 0x3D,0x3D,0x8D,0xDB,0xCE,0x99,0xE1,0x57,0x92,0x59,0xCD,0xFD, ++ 0xB8,0xAE,0x74,0x4F,0xC5,0xFC,0x76,0xBC,0x83,0xC5,0x47,0x30, ++ 0x61,0xCE,0x7C,0xC9,0x66,0xFF,0x15,0xF9,0xBB,0xFD,0x91,0x5E, ++ 0xC7,0x01,0xAA,0xD3,0x5B,0x9E,0x8D,0xA0,0xA5,0x72,0x3A,0xD4, ++ 0x1A,0xF0,0xBF,0x46,0x00,0x58,0x2B,0xE5,0xF4,0x88,0xFD,0x58, ++ 0x4E,0x49,0xDB,0xCD,0x20,0xB4,0x9D,0xE4,0x91,0x07,0x36,0x6B, ++ 0x33,0x6C,0x38,0x0D,0x45,0x1D,0x0F,0x7C,0x88,0xB3,0x1C,0x7C, ++ 0x5B,0x2D,0x8E,0xF6,0xF3,0xC9,0x23,0xC0,0x43,0xF0,0xA5,0x5B, ++ 0x18,0x8D,0x8E,0xBB,0x55,0x8C,0xB8,0x5D,0x38,0xD3,0x34,0xFD, ++ 0x7C,0x17,0x57,0x43,0xA3,0x1D,0x18,0x6C,0xDE,0x33,0x21,0x2C, ++ 0xB5,0x2A,0xFF,0x3C,0xE1,0xB1,0x29,0x40,0x18,0x11,0x8D,0x7C, ++ 0x84,0xA7,0x0A,0x72,0xD6,0x86,0xC4,0x03,0x19,0xC8,0x07,0x29, ++ 0x7A,0xCA,0x95,0x0C,0xD9,0x96,0x9F,0xAB,0xD0,0x0A,0x50,0x9B, ++ 0x02,0x46,0xD3,0x08,0x3D,0x66,0xA4,0x5D,0x41,0x9F,0x9C,0x7C, ++ 0xBD,0x89,0x4B,0x22,0x19,0x26,0xBA,0xAB,0xA2,0x5E,0xC3,0x55, ++ 0xE9,0x32,0x0B,0x3B, ++}; ++ ++static unsigned char dh2048_g[] = { + 0x02, +- }; ++}; + +-static DH *get_dh512(void) +- { +- DH *dh=NULL; ++DH *get_dh2048() ++{ ++ DH *dh; + +- if ((dh=DH_new()) == NULL) return(NULL); +- dh->p=BN_bin2bn(dh512_p,sizeof(dh512_p),NULL); +- dh->g=BN_bin2bn(dh512_g,sizeof(dh512_g),NULL); +- if ((dh->p == NULL) || (dh->g == NULL)) +- return(NULL); +- return(dh); ++ if ((dh = DH_new()) == NULL) ++ return NULL; ++ dh->p=BN_bin2bn(dh2048_p, sizeof(dh2048_p), NULL); ++ dh->g=BN_bin2bn(dh2048_g, sizeof(dh2048_g), NULL); ++ if (dh->p == NULL || dh->g == NULL) { ++ DH_free(dh); ++ return NULL; + } ++ return dh; ++} + #endif + + +@@ -1661,9 +1681,8 @@ bad: + #endif + + #ifndef OPENSSL_NO_DH +- if (!no_dhe) +- { +- DH *dh=NULL; ++ if (!no_dhe) { ++ DH *dh = NULL; + + if (dhfile) + dh = load_dh_param(dhfile); +@@ -1670,27 +1689,25 @@ bad: + else if (s_cert_file) + dh = load_dh_param(s_cert_file); + +- if (dh != NULL) +- { +- BIO_printf(bio_s_out,"Setting temp DH parameters\n"); ++ if (dh != NULL) { ++ BIO_printf(bio_s_out, "Setting temp DH parameters\n"); ++ } else { ++ BIO_printf(bio_s_out, "Using default temp DH parameters\n"); ++ dh = get_dh2048(); ++ if (dh == NULL) { ++ ERR_print_errors(bio_err); ++ goto end; + } +- else +- { +- BIO_printf(bio_s_out,"Using default temp DH parameters\n"); +- dh=get_dh512(); + } + (void)BIO_flush(bio_s_out); + +- SSL_CTX_set_tmp_dh(ctx,dh); +-#ifndef OPENSSL_NO_TLSEXT +- if (ctx2) +- { +- if (!dhfile) +- { +- DH *dh2=load_dh_param(s_cert_file2); +- if (dh2 != NULL) +- { +- BIO_printf(bio_s_out,"Setting temp DH parameters\n"); ++ SSL_CTX_set_tmp_dh(ctx, dh); ++# ifndef OPENSSL_NO_TLSEXT ++ if (ctx2) { ++ if (!dhfile) { ++ DH *dh2 = load_dh_param(s_cert_file2); ++ if (dh2 != NULL) { ++ BIO_printf(bio_s_out, "Setting temp DH parameters\n"); + (void)BIO_flush(bio_s_out); + + DH_free(dh); +@@ -1697,9 +1714,9 @@ bad: + dh = dh2; + } + } +- SSL_CTX_set_tmp_dh(ctx2,dh); ++ SSL_CTX_set_tmp_dh(ctx2, dh); + } +-#endif ++# endif + DH_free(dh); + } + #endif +Index: crypto/openssl/crypto/bio/bio_lib.c +=================================================================== +--- crypto/openssl/crypto/bio/bio_lib.c (revision 284286) ++++ crypto/openssl/crypto/bio/bio_lib.c (working copy) +@@ -543,8 +543,10 @@ BIO *BIO_dup_chain(BIO *in) + + /* copy app data */ + if (!CRYPTO_dup_ex_data(CRYPTO_EX_INDEX_BIO, &new_bio->ex_data, +- &bio->ex_data)) ++ &bio->ex_data)) { ++ BIO_free(new_bio); + goto err; ++ } + + if (ret == NULL) + { +@@ -559,8 +561,8 @@ BIO *BIO_dup_chain(BIO *in) + } + return(ret); + err: +- if (ret != NULL) +- BIO_free(ret); ++ BIO_free_all(ret); ++ + return(NULL); + } + +Index: crypto/openssl/crypto/bn/bn_gf2m.c +=================================================================== +--- crypto/openssl/crypto/bn/bn_gf2m.c (revision 284286) ++++ crypto/openssl/crypto/bn/bn_gf2m.c (working copy) +@@ -568,10 +568,11 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, co + } + #else + { +- int i, ubits = BN_num_bits(u), +- vbits = BN_num_bits(v), /* v is copy of p */ +- top = p->top; +- BN_ULONG *udp,*bdp,*vdp,*cdp; ++ int i; ++ int ubits = BN_num_bits(u); ++ int vbits = BN_num_bits(v); /* v is copy of p */ ++ int top = p->top; ++ BN_ULONG *udp, *bdp, *vdp, *cdp; + + bn_wexpand(u,top); udp = u->d; + for (i=u->top;i<top;i++) udp[i] = 0; +@@ -611,7 +612,12 @@ int BN_GF2m_mod_inv(BIGNUM *r, const BIGNUM *a, co + ubits--; + } + +- if (ubits<=BN_BITS2 && udp[0]==1) break; ++ if (ubits <= BN_BITS2) { ++ if (udp[0] == 0) /* poly was reducible */ ++ goto err; ++ if (udp[0] == 1) ++ break; ++ } + + if (ubits<vbits) + { +Index: crypto/openssl/crypto/bn/bn_print.c +=================================================================== +--- crypto/openssl/crypto/bn/bn_print.c (revision 284286) ++++ crypto/openssl/crypto/bn/bn_print.c (working copy) +@@ -71,7 +71,12 @@ char *BN_bn2hex(const BIGNUM *a) + char *buf; + char *p; + +- buf=(char *)OPENSSL_malloc(a->top*BN_BYTES*2+2); ++ if (a->neg && BN_is_zero(a)) { ++ /* "-0" == 3 bytes including NULL terminator */ ++ buf = OPENSSL_malloc(3); ++ } else { ++ buf = OPENSSL_malloc(a->top * BN_BYTES * 2 + 2); ++ } + if (buf == NULL) + { + BNerr(BN_F_BN_BN2HEX,ERR_R_MALLOC_FAILURE); +Index: crypto/openssl/crypto/buffer/buffer.c +=================================================================== +--- crypto/openssl/crypto/buffer/buffer.c (revision 284286) ++++ crypto/openssl/crypto/buffer/buffer.c (working copy) +@@ -88,7 +88,7 @@ void BUF_MEM_free(BUF_MEM *a) + + if (a->data != NULL) + { +- memset(a->data,0,(unsigned int)a->max); ++ OPENSSL_cleanse(a->data, a->max); + OPENSSL_free(a->data); + } + OPENSSL_free(a); +Index: crypto/openssl/crypto/cms/cms_smime.c +=================================================================== +--- crypto/openssl/crypto/cms/cms_smime.c (revision 284286) ++++ crypto/openssl/crypto/cms/cms_smime.c (working copy) +@@ -141,7 +141,7 @@ static void do_free_upto(BIO *f, BIO *upto) + BIO_free(f); + f = tbio; + } +- while (f != upto); ++ while (f && f != upto); + } + else + BIO_free_all(f); +Index: crypto/openssl/crypto/ec/ec2_oct.c +=================================================================== +--- crypto/openssl/crypto/ec/ec2_oct.c (revision 284286) ++++ crypto/openssl/crypto/ec/ec2_oct.c (working copy) +@@ -390,7 +390,8 @@ int ec_GF2m_simple_oct2point(const EC_GROUP *group + if (!EC_POINT_set_affine_coordinates_GF2m(group, point, x, y, ctx)) goto err; + } + +- if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */ ++ /* test required by X9.62 */ ++ if (EC_POINT_is_on_curve(group, point, ctx) <= 0) + { + ECerr(EC_F_EC_GF2M_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE); + goto err; +Index: crypto/openssl/crypto/ec/ec_check.c +=================================================================== +--- crypto/openssl/crypto/ec/ec_check.c (revision 284286) ++++ crypto/openssl/crypto/ec/ec_check.c (working copy) +@@ -88,7 +88,7 @@ int EC_GROUP_check(const EC_GROUP *group, BN_CTX * + ECerr(EC_F_EC_GROUP_CHECK, EC_R_UNDEFINED_GENERATOR); + goto err; + } +- if (!EC_POINT_is_on_curve(group, group->generator, ctx)) ++ if (EC_POINT_is_on_curve(group, group->generator, ctx) <= 0) + { + ECerr(EC_F_EC_GROUP_CHECK, EC_R_POINT_IS_NOT_ON_CURVE); + goto err; +Index: crypto/openssl/crypto/ec/ec_key.c +=================================================================== +--- crypto/openssl/crypto/ec/ec_key.c (revision 284286) ++++ crypto/openssl/crypto/ec/ec_key.c (working copy) +@@ -326,7 +326,7 @@ int EC_KEY_check_key(const EC_KEY *eckey) + goto err; + + /* testing whether the pub_key is on the elliptic curve */ +- if (!EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx)) ++ if (EC_POINT_is_on_curve(eckey->group, eckey->pub_key, ctx) <= 0) + { + ECerr(EC_F_EC_KEY_CHECK_KEY, EC_R_POINT_IS_NOT_ON_CURVE); + goto err; +Index: crypto/openssl/crypto/ec/ec_lib.c +=================================================================== +--- crypto/openssl/crypto/ec/ec_lib.c (revision 284286) ++++ crypto/openssl/crypto/ec/ec_lib.c (working copy) +@@ -972,7 +972,15 @@ int EC_POINT_is_at_infinity(const EC_GROUP *group, + } + + +-int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, BN_CTX *ctx) ++/* ++ * Check whether an EC_POINT is on the curve or not. Note that the return ++ * value for this function should NOT be treated as a boolean. Return values: ++ * 1: The point is on the curve ++ * 0: The point is not on the curve ++ * -1: An error occurred ++ */ ++int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, ++ BN_CTX *ctx) + { + if (group->meth->is_on_curve == 0) + { +Index: crypto/openssl/crypto/ec/ecp_oct.c +=================================================================== +--- crypto/openssl/crypto/ec/ecp_oct.c (revision 284286) ++++ crypto/openssl/crypto/ec/ecp_oct.c (working copy) +@@ -416,7 +416,8 @@ int ec_GFp_simple_oct2point(const EC_GROUP *group, + if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) goto err; + } + +- if (!EC_POINT_is_on_curve(group, point, ctx)) /* test required by X9.62 */ ++ /* test required by X9.62 */ ++ if (EC_POINT_is_on_curve(group, point, ctx) <= 0) + { + ECerr(EC_F_EC_GFP_SIMPLE_OCT2POINT, EC_R_POINT_IS_NOT_ON_CURVE); + goto err; +Index: crypto/openssl/crypto/ec/ectest.c +=================================================================== +--- crypto/openssl/crypto/ec/ectest.c (revision 284286) ++++ crypto/openssl/crypto/ec/ectest.c (working copy) +@@ -343,7 +343,7 @@ static void prime_field_tests(void) + + if (!BN_hex2bn(&x, "D")) ABORT; + if (!EC_POINT_set_compressed_coordinates_GFp(group, Q, x, 1, ctx)) ABORT; +- if (!EC_POINT_is_on_curve(group, Q, ctx)) ++ if (EC_POINT_is_on_curve(group, Q, ctx) <= 0) + { + if (!EC_POINT_get_affine_coordinates_GFp(group, Q, x, y, ctx)) ABORT; + fprintf(stderr, "Point is not on curve: x = 0x"); +@@ -439,7 +439,7 @@ static void prime_field_tests(void) + if (!BN_hex2bn(&x, "4A96B5688EF573284664698968C38BB913CBFC82")) ABORT; + if (!BN_hex2bn(&y, "23a628553168947d59dcc912042351377ac5fb32")) ABORT; + if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) ABORT; +- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; ++ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; + if (!BN_hex2bn(&z, "0100000000000000000001F4C8F927AED3CA752257")) ABORT; + if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT; + +@@ -473,7 +473,7 @@ static void prime_field_tests(void) + + if (!BN_hex2bn(&x, "188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012")) ABORT; + if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT; +- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; ++ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; + if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFF99DEF836146BC9B1B4D22831")) ABORT; + if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT; + +@@ -507,7 +507,7 @@ static void prime_field_tests(void) + + if (!BN_hex2bn(&x, "B70E0CBD6BB4BF7F321390B94A03C1D356C21122343280D6115C1D21")) ABORT; + if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT; +- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; ++ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; + if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFF16A2E0B8F03E13DD29455C5C2A3D")) ABORT; + if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT; + +@@ -541,7 +541,7 @@ static void prime_field_tests(void) + + if (!BN_hex2bn(&x, "6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296")) ABORT; + if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT; +- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; ++ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; + if (!BN_hex2bn(&z, "FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E" + "84F3B9CAC2FC632551")) ABORT; + if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT; +@@ -580,7 +580,7 @@ static void prime_field_tests(void) + if (!BN_hex2bn(&x, "AA87CA22BE8B05378EB1C71EF320AD746E1D3B628BA79B" + "9859F741E082542A385502F25DBF55296C3A545E3872760AB7")) ABORT; + if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 1, ctx)) ABORT; +- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; ++ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; + if (!BN_hex2bn(&z, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973")) ABORT; + if (!EC_GROUP_set_generator(group, P, z, BN_value_one())) ABORT; +@@ -624,7 +624,7 @@ static void prime_field_tests(void) + "B521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2FFA8DE3348B" + "3C1856A429BF97E7E31C2E5BD66")) ABORT; + if (!EC_POINT_set_compressed_coordinates_GFp(group, P, x, 0, ctx)) ABORT; +- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; ++ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; + if (!BN_hex2bn(&z, "1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFA51868783BF2F966B7FCC0148F709A5D03BB5" + "C9B8899C47AEBB6FB71E91386409")) ABORT; +@@ -657,7 +657,7 @@ static void prime_field_tests(void) + if (!EC_POINT_copy(Q, P)) ABORT; + if (EC_POINT_is_at_infinity(group, Q)) ABORT; + if (!EC_POINT_dbl(group, P, P, ctx)) ABORT; +- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; ++ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; + if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */ + + if (!EC_POINT_add(group, R, P, Q, ctx)) ABORT; +@@ -771,7 +771,7 @@ static void prime_field_tests(void) + #define CHAR2_CURVE_TEST_INTERNAL(_name, _p, _a, _b, _x, _y, _y_bit, _order, _cof, _degree, _variable) \ + if (!BN_hex2bn(&x, _x)) ABORT; \ + if (!EC_POINT_set_compressed_coordinates_GF2m(group, P, x, _y_bit, ctx)) ABORT; \ +- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; \ ++ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; \ + if (!BN_hex2bn(&z, _order)) ABORT; \ + if (!BN_hex2bn(&cof, _cof)) ABORT; \ + if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \ +@@ -789,7 +789,7 @@ static void prime_field_tests(void) + if (!BN_hex2bn(&x, _x)) ABORT; \ + if (!BN_hex2bn(&y, _y)) ABORT; \ + if (!EC_POINT_set_affine_coordinates_GF2m(group, P, x, y, ctx)) ABORT; \ +- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; \ ++ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; \ + if (!BN_hex2bn(&z, _order)) ABORT; \ + if (!BN_hex2bn(&cof, _cof)) ABORT; \ + if (!EC_GROUP_set_generator(group, P, z, cof)) ABORT; \ +@@ -894,7 +894,7 @@ static void char2_field_tests(void) + if (!BN_hex2bn(&y, "8")) ABORT; + if (!EC_POINT_set_affine_coordinates_GF2m(group, Q, x, y, ctx)) ABORT; + #endif +- if (!EC_POINT_is_on_curve(group, Q, ctx)) ++ if (EC_POINT_is_on_curve(group, Q, ctx) <= 0) + { + /* Change test based on whether binary point compression is enabled or not. */ + #ifdef OPENSSL_EC_BIN_PT_COMP +@@ -1133,7 +1133,7 @@ static void char2_field_tests(void) + if (!EC_POINT_copy(Q, P)) ABORT; + if (EC_POINT_is_at_infinity(group, Q)) ABORT; + if (!EC_POINT_dbl(group, P, P, ctx)) ABORT; +- if (!EC_POINT_is_on_curve(group, P, ctx)) ABORT; ++ if (EC_POINT_is_on_curve(group, P, ctx) <= 0) ABORT; + if (!EC_POINT_invert(group, Q, ctx)) ABORT; /* P = -2Q */ + + if (!EC_POINT_add(group, R, P, Q, ctx)) ABORT; +Index: crypto/openssl/crypto/evp/e_aes.c +=================================================================== +--- crypto/openssl/crypto/evp/e_aes.c (revision 284286) ++++ crypto/openssl/crypto/evp/e_aes.c (working copy) +@@ -50,6 +50,7 @@ + + #include <openssl/opensslconf.h> + #ifndef OPENSSL_NO_AES ++#include <openssl/crypto.h> + #include <openssl/evp.h> + #include <openssl/err.h> + #include <string.h> +@@ -967,7 +968,7 @@ static int aes_gcm_tls_cipher(EVP_CIPHER_CTX *ctx, + CRYPTO_gcm128_tag(&gctx->gcm, ctx->buf, + EVP_GCM_TLS_TAG_LEN); + /* If tag mismatch wipe buffer */ +- if (memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN)) ++ if (CRYPTO_memcmp(ctx->buf, in + len, EVP_GCM_TLS_TAG_LEN)) + { + OPENSSL_cleanse(out, len); + goto err; +@@ -1351,7 +1352,7 @@ static int aes_ccm_cipher(EVP_CIPHER_CTX *ctx, uns + unsigned char tag[16]; + if (CRYPTO_ccm128_tag(ccm, tag, cctx->M)) + { +- if (!memcmp(tag, ctx->buf, cctx->M)) ++ if (!CRYPTO_memcmp(tag, ctx->buf, cctx->M)) + rv = len; + } + } +Index: crypto/openssl/crypto/evp/e_rc4_hmac_md5.c +=================================================================== +--- crypto/openssl/crypto/evp/e_rc4_hmac_md5.c (revision 284286) ++++ crypto/openssl/crypto/evp/e_rc4_hmac_md5.c (working copy) +@@ -54,6 +54,7 @@ + + #if !defined(OPENSSL_NO_RC4) && !defined(OPENSSL_NO_MD5) + ++#include <openssl/crypto.h> + #include <openssl/evp.h> + #include <openssl/objects.h> + #include <openssl/rc4.h> +@@ -205,7 +206,7 @@ static int rc4_hmac_md5_cipher(EVP_CIPHER_CTX *ctx + MD5_Update(&key->md,mac,MD5_DIGEST_LENGTH); + MD5_Final(mac,&key->md); + +- if (memcmp(out+plen,mac,MD5_DIGEST_LENGTH)) ++ if (CRYPTO_memcmp(out + plen, mac, MD5_DIGEST_LENGTH)) + return 0; + } else { + MD5_Update(&key->md,out+md5_off,len-md5_off); +Index: crypto/openssl/crypto/evp/evp.h +=================================================================== +--- crypto/openssl/crypto/evp/evp.h (revision 284286) ++++ crypto/openssl/crypto/evp/evp.h (working copy) +@@ -103,7 +103,6 @@ + #define EVP_PKS_RSA 0x0100 + #define EVP_PKS_DSA 0x0200 + #define EVP_PKS_EC 0x0400 +-#define EVP_PKT_EXP 0x1000 /* <= 512 bit key */ + + #define EVP_PKEY_NONE NID_undef + #define EVP_PKEY_RSA NID_rsaEncryption +Index: crypto/openssl/crypto/hmac/hmac.c +=================================================================== +--- crypto/openssl/crypto/hmac/hmac.c (revision 284286) ++++ crypto/openssl/crypto/hmac/hmac.c (working copy) +@@ -240,6 +240,7 @@ unsigned char *HMAC(const EVP_MD *evp_md, const vo + HMAC_CTX_cleanup(&c); + return md; + err: ++ HMAC_CTX_cleanup(&c); + return NULL; + } + +Index: crypto/openssl/crypto/modes/gcm128.c +=================================================================== +--- crypto/openssl/crypto/modes/gcm128.c (revision 284286) ++++ crypto/openssl/crypto/modes/gcm128.c (working copy) +@@ -1525,7 +1525,7 @@ int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx,const + ctx->Xi.u[1] ^= ctx->EK0.u[1]; + + if (tag && len<=sizeof(ctx->Xi)) +- return memcmp(ctx->Xi.c,tag,len); ++ return CRYPTO_memcmp(ctx->Xi.c, tag, len); + else + return -1; + } +Index: crypto/openssl/crypto/objects/obj_dat.c +=================================================================== +--- crypto/openssl/crypto/objects/obj_dat.c (revision 284286) ++++ crypto/openssl/crypto/objects/obj_dat.c (working copy) +@@ -405,6 +405,9 @@ int OBJ_obj2nid(const ASN1_OBJECT *a) + if (a->nid != 0) + return(a->nid); + ++ if (a->length == 0) ++ return NID_undef; ++ + if (added != NULL) + { + ad.type=ADDED_DATA; +Index: crypto/openssl/crypto/pkcs12/p12_mutl.c +=================================================================== +--- crypto/openssl/crypto/pkcs12/p12_mutl.c (revision 284286) ++++ crypto/openssl/crypto/pkcs12/p12_mutl.c (working copy) +@@ -59,6 +59,7 @@ + #ifndef OPENSSL_NO_HMAC + #include <stdio.h> + #include "cryptlib.h" ++#include <openssl/crypto.h> + #include <openssl/hmac.h> + #include <openssl/rand.h> + #include <openssl/pkcs12.h> +@@ -123,7 +124,8 @@ int PKCS12_verify_mac(PKCS12 *p12, const char *pas + return 0; + } + if ((maclen != (unsigned int)p12->mac->dinfo->digest->length) +- || memcmp (mac, p12->mac->dinfo->digest->data, maclen)) return 0; ++ || CRYPTO_memcmp(mac, p12->mac->dinfo->digest->data, maclen)) ++ return 0; + return 1; + } + +Index: crypto/openssl/crypto/pkcs7/pk7_doit.c +=================================================================== +--- crypto/openssl/crypto/pkcs7/pk7_doit.c (revision 284286) ++++ crypto/openssl/crypto/pkcs7/pk7_doit.c (working copy) +@@ -504,6 +504,12 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, B + goto err; + } + ++ /* Detached content must be supplied via in_bio instead. */ ++ if (data_body == NULL && in_bio == NULL) { ++ PKCS7err(PKCS7_F_PKCS7_DATADECODE, PKCS7_R_NO_CONTENT); ++ goto err; ++ } ++ + /* We will be checking the signature */ + if (md_sk != NULL) + { +@@ -660,7 +666,7 @@ BIO *PKCS7_dataDecode(PKCS7 *p7, EVP_PKEY *pkey, B + } + + #if 1 +- if (PKCS7_is_detached(p7) || (in_bio != NULL)) ++ if (in_bio != NULL) + { + bio=in_bio; + } +Index: crypto/openssl/crypto/x509/x509_vfy.c +=================================================================== +--- crypto/openssl/crypto/x509/x509_vfy.c (revision 284286) ++++ crypto/openssl/crypto/x509/x509_vfy.c (working copy) +@@ -1679,83 +1679,121 @@ int X509_cmp_current_time(const ASN1_TIME *ctm) + } + + int X509_cmp_time(const ASN1_TIME *ctm, time_t *cmp_time) +- { ++{ + char *str; + ASN1_TIME atm; + long offset; +- char buff1[24],buff2[24],*p; +- int i,j; ++ char buff1[24], buff2[24], *p; ++ int i, j, remaining; + +- p=buff1; +- i=ctm->length; +- str=(char *)ctm->data; +- if (ctm->type == V_ASN1_UTCTIME) +- { +- if ((i < 11) || (i > 17)) return 0; +- memcpy(p,str,10); +- p+=10; +- str+=10; ++ p = buff1; ++ remaining = ctm->length; ++ str = (char *)ctm->data; ++ /* ++ * Note that the following (historical) code allows much more slack in the ++ * time format than RFC5280. In RFC5280, the representation is fixed: ++ * UTCTime: YYMMDDHHMMSSZ ++ * GeneralizedTime: YYYYMMDDHHMMSSZ ++ */ ++ if (ctm->type == V_ASN1_UTCTIME) { ++ /* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */ ++ int min_length = sizeof("YYMMDDHHMMZ") - 1; ++ int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1; ++ if (remaining < min_length || remaining > max_length) ++ return 0; ++ memcpy(p, str, 10); ++ p += 10; ++ str += 10; ++ remaining -= 10; ++ } else { ++ /* YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm */ ++ int min_length = sizeof("YYYYMMDDHHMMZ") - 1; ++ int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1; ++ if (remaining < min_length || remaining > max_length) ++ return 0; ++ memcpy(p, str, 12); ++ p += 12; ++ str += 12; ++ remaining -= 12; + } +- else +- { +- if (i < 13) return 0; +- memcpy(p,str,12); +- p+=12; +- str+=12; +- } + +- if ((*str == 'Z') || (*str == '-') || (*str == '+')) +- { *(p++)='0'; *(p++)='0'; } +- else +- { +- *(p++)= *(str++); +- *(p++)= *(str++); +- /* Skip any fractional seconds... */ +- if (*str == '.') +- { ++ if ((*str == 'Z') || (*str == '-') || (*str == '+')) { ++ *(p++) = '0'; ++ *(p++) = '0'; ++ } else { ++ /* SS (seconds) */ ++ if (remaining < 2) ++ return 0; ++ *(p++) = *(str++); ++ *(p++) = *(str++); ++ remaining -= 2; ++ /* ++ * Skip any (up to three) fractional seconds... ++ * TODO(emilia): in RFC5280, fractional seconds are forbidden. ++ * Can we just kill them altogether? ++ */ ++ if (remaining && *str == '.') { + str++; +- while ((*str >= '0') && (*str <= '9')) str++; ++ remaining--; ++ for (i = 0; i < 3 && remaining; i++, str++, remaining--) { ++ if (*str < '0' || *str > '9') ++ break; + } +- + } +- *(p++)='Z'; +- *(p++)='\0'; + +- if (*str == 'Z') +- offset=0; +- else +- { ++ } ++ *(p++) = 'Z'; ++ *(p++) = '\0'; ++ ++ /* We now need either a terminating 'Z' or an offset. */ ++ if (!remaining) ++ return 0; ++ if (*str == 'Z') { ++ if (remaining != 1) ++ return 0; ++ offset = 0; ++ } else { ++ /* (+-)HHMM */ + if ((*str != '+') && (*str != '-')) + return 0; +- offset=((str[1]-'0')*10+(str[2]-'0'))*60; +- offset+=(str[3]-'0')*10+(str[4]-'0'); ++ /* Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280. */ ++ if (remaining != 5) ++ return 0; ++ if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' || ++ str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9') ++ return 0; ++ offset = ((str[1] - '0') * 10 + (str[2] - '0')) * 60; ++ offset += (str[3] - '0') * 10 + (str[4] - '0'); + if (*str == '-') +- offset= -offset; ++ offset = -offset; + } +- atm.type=ctm->type; ++ atm.type = ctm->type; + atm.flags = 0; +- atm.length=sizeof(buff2); +- atm.data=(unsigned char *)buff2; ++ atm.length = sizeof(buff2); ++ atm.data = (unsigned char *)buff2; + +- if (X509_time_adj(&atm, offset*60, cmp_time) == NULL) ++ if (X509_time_adj(&atm, offset * 60, cmp_time) == NULL) + return 0; + +- if (ctm->type == V_ASN1_UTCTIME) +- { +- i=(buff1[0]-'0')*10+(buff1[1]-'0'); +- if (i < 50) i+=100; /* cf. RFC 2459 */ +- j=(buff2[0]-'0')*10+(buff2[1]-'0'); +- if (j < 50) j+=100; ++ if (ctm->type == V_ASN1_UTCTIME) { ++ i = (buff1[0] - '0') * 10 + (buff1[1] - '0'); ++ if (i < 50) ++ i += 100; /* cf. RFC 2459 */ ++ j = (buff2[0] - '0') * 10 + (buff2[1] - '0'); ++ if (j < 50) ++ j += 100; + +- if (i < j) return -1; +- if (i > j) return 1; ++ if (i < j) ++ return -1; ++ if (i > j) *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201506120733.t5C7XuXj018873>