From 94fbf434c719985d68c2a8bc6ceeaade79232adf265324e77b2f04a937f5a314 Mon Sep 17 00:00:00 2001 From: Stephan Kulow Date: Fri, 9 May 2014 04:57:35 +0000 Subject: [PATCH] Accepting request 232889 from Base:System - 0005-libssl-Hide-library-private-symbols.patch Update to hide more symbols that are not part of the public API - openssl-gcc-attributes.patch BUF_memdup also needs attribute alloc_size as it returns memory of size of the second parameter. - openssl-ocloexec.patch Update, accept() also needs O_CLOEXEC. - 0009-Fix-double-frees.patch, 0017-Double-free-in-i2o_ECPublicKey.patch fix various double frees (from upstream) - 012-Fix-eckey_priv_encode.patch eckey_priv_encode should return an error inmediately on failure of i2d_ECPrivateKey (from upstream) - 0001-Axe-builtin-printf-implementation-use-glibc-instead.patch From libressl, modified to work on linux systems that do not have funopen() but fopencookie() instead. Once upon a time, OS didn't have snprintf, which caused openssl to bundle a *printf implementation. We know better nowadays, the glibc implementation has buffer overflow checking, has sane failure modes deal properly with threads, signals..etc.. - build with -fno-common as well. (forwarded request 232752 from elvigia) OBS-URL: https://build.opensuse.org/request/show/232889 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/openssl?expand=0&rev=116 --- ...ntf-implementation-use-glibc-instead.patch | 835 ++++++++++++++++++ ...-libssl-Hide-library-private-symbols.patch | 108 ++- 0009-Fix-double-frees.patch | 51 ++ 0012-Fix-eckey_priv_encode.patch | 26 + 0017-Double-free-in-i2o_ECPublicKey.patch | 31 + openssl-gcc-attributes.patch | 11 + openssl-ocloexec.patch | 21 +- openssl.changes | 30 + openssl.spec | 10 +- 9 files changed, 1098 insertions(+), 25 deletions(-) create mode 100644 0001-Axe-builtin-printf-implementation-use-glibc-instead.patch create mode 100644 0009-Fix-double-frees.patch create mode 100644 0012-Fix-eckey_priv_encode.patch create mode 100644 0017-Double-free-in-i2o_ECPublicKey.patch diff --git a/0001-Axe-builtin-printf-implementation-use-glibc-instead.patch b/0001-Axe-builtin-printf-implementation-use-glibc-instead.patch new file mode 100644 index 0000000..32ea436 --- /dev/null +++ b/0001-Axe-builtin-printf-implementation-use-glibc-instead.patch @@ -0,0 +1,835 @@ +From fd708c2242408187cff392e8b0850275ac99376f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Cristian=20Rodr=C3=ADguez?= +Date: Sun, 4 May 2014 23:36:54 -0400 +Subject: [PATCH] Axe builtin printf implementation, use glibc instead + + +diff --git a/crypto/bio/b_print.c b/crypto/bio/b_print.c +index 143a7cf..657beb7 100644 +--- a/crypto/bio/b_print.c ++++ b/crypto/bio/b_print.c +@@ -56,17 +56,9 @@ + * [including the GNU Public Licence.] + */ + +-/* disable assert() unless BIO_DEBUG has been defined */ +-#ifndef BIO_DEBUG +-# ifndef NDEBUG +-# define NDEBUG +-# endif ++#ifndef _GNU_SOURCE ++#define _GNU_SOURCE + #endif +- +-/* +- * Stolen from tjh's ssl/ssl_trc.c stuff. +- */ +- + #include + #include + #include +@@ -79,690 +71,6 @@ + #include /* To get BN_LLONG properly defined */ + #include + +-#if defined(BN_LLONG) || defined(SIXTY_FOUR_BIT) +-# ifndef HAVE_LONG_LONG +-# define HAVE_LONG_LONG 1 +-# endif +-#endif +- +-/***************************************************************************/ +- +-/* +- * Copyright Patrick Powell 1995 +- * This code is based on code written by Patrick Powell +- * It may be used for any purpose as long as this notice remains intact +- * on all source code distributions. +- */ +- +-/* +- * This code contains numerious changes and enhancements which were +- * made by lots of contributors over the last years to Patrick Powell's +- * original code: +- * +- * o Patrick Powell (1995) +- * o Brandon Long (1996, for Mutt) +- * o Thomas Roessler (1998, for Mutt) +- * o Michael Elkins (1998, for Mutt) +- * o Andrew Tridgell (1998, for Samba) +- * o Luke Mewburn (1999, for LukemFTP) +- * o Ralf S. Engelschall (1999, for Pth) +- * o ... (for OpenSSL) +- */ +- +-#ifdef HAVE_LONG_DOUBLE +-#define LDOUBLE long double +-#else +-#define LDOUBLE double +-#endif +- +-#ifdef HAVE_LONG_LONG +-# if defined(_WIN32) && !defined(__GNUC__) +-# define LLONG __int64 +-# else +-# define LLONG long long +-# endif +-#else +-#define LLONG long +-#endif +- +-static void fmtstr (char **, char **, size_t *, size_t *, +- const char *, int, int, int); +-static void fmtint (char **, char **, size_t *, size_t *, +- LLONG, int, int, int, int); +-static void fmtfp (char **, char **, size_t *, size_t *, +- LDOUBLE, int, int, int); +-static void doapr_outch (char **, char **, size_t *, size_t *, int); +-static void _dopr(char **sbuffer, char **buffer, +- size_t *maxlen, size_t *retlen, int *truncated, +- const char *format, va_list args); +- +-/* format read states */ +-#define DP_S_DEFAULT 0 +-#define DP_S_FLAGS 1 +-#define DP_S_MIN 2 +-#define DP_S_DOT 3 +-#define DP_S_MAX 4 +-#define DP_S_MOD 5 +-#define DP_S_CONV 6 +-#define DP_S_DONE 7 +- +-/* format flags - Bits */ +-#define DP_F_MINUS (1 << 0) +-#define DP_F_PLUS (1 << 1) +-#define DP_F_SPACE (1 << 2) +-#define DP_F_NUM (1 << 3) +-#define DP_F_ZERO (1 << 4) +-#define DP_F_UP (1 << 5) +-#define DP_F_UNSIGNED (1 << 6) +- +-/* conversion flags */ +-#define DP_C_SHORT 1 +-#define DP_C_LONG 2 +-#define DP_C_LDOUBLE 3 +-#define DP_C_LLONG 4 +- +-/* some handy macros */ +-#define char_to_int(p) (p - '0') +-#define OSSL_MAX(p,q) ((p >= q) ? p : q) +- +-static void +-_dopr( +- char **sbuffer, +- char **buffer, +- size_t *maxlen, +- size_t *retlen, +- int *truncated, +- const char *format, +- va_list args) +-{ +- char ch; +- LLONG value; +- LDOUBLE fvalue; +- char *strvalue; +- int min; +- int max; +- int state; +- int flags; +- int cflags; +- size_t currlen; +- +- state = DP_S_DEFAULT; +- flags = currlen = cflags = min = 0; +- max = -1; +- ch = *format++; +- +- while (state != DP_S_DONE) { +- if (ch == '\0' || (buffer == NULL && currlen >= *maxlen)) +- state = DP_S_DONE; +- +- switch (state) { +- case DP_S_DEFAULT: +- if (ch == '%') +- state = DP_S_FLAGS; +- else +- doapr_outch(sbuffer,buffer, &currlen, maxlen, ch); +- ch = *format++; +- break; +- case DP_S_FLAGS: +- switch (ch) { +- case '-': +- flags |= DP_F_MINUS; +- ch = *format++; +- break; +- case '+': +- flags |= DP_F_PLUS; +- ch = *format++; +- break; +- case ' ': +- flags |= DP_F_SPACE; +- ch = *format++; +- break; +- case '#': +- flags |= DP_F_NUM; +- ch = *format++; +- break; +- case '0': +- flags |= DP_F_ZERO; +- ch = *format++; +- break; +- default: +- state = DP_S_MIN; +- break; +- } +- break; +- case DP_S_MIN: +- if (isdigit((unsigned char)ch)) { +- min = 10 * min + char_to_int(ch); +- ch = *format++; +- } else if (ch == '*') { +- min = va_arg(args, int); +- ch = *format++; +- state = DP_S_DOT; +- } else +- state = DP_S_DOT; +- break; +- case DP_S_DOT: +- if (ch == '.') { +- state = DP_S_MAX; +- ch = *format++; +- } else +- state = DP_S_MOD; +- break; +- case DP_S_MAX: +- if (isdigit((unsigned char)ch)) { +- if (max < 0) +- max = 0; +- max = 10 * max + char_to_int(ch); +- ch = *format++; +- } else if (ch == '*') { +- max = va_arg(args, int); +- ch = *format++; +- state = DP_S_MOD; +- } else +- state = DP_S_MOD; +- break; +- case DP_S_MOD: +- switch (ch) { +- case 'h': +- cflags = DP_C_SHORT; +- ch = *format++; +- break; +- case 'l': +- if (*format == 'l') { +- cflags = DP_C_LLONG; +- format++; +- } else +- cflags = DP_C_LONG; +- ch = *format++; +- break; +- case 'q': +- cflags = DP_C_LLONG; +- ch = *format++; +- break; +- case 'L': +- cflags = DP_C_LDOUBLE; +- ch = *format++; +- break; +- default: +- break; +- } +- state = DP_S_CONV; +- break; +- case DP_S_CONV: +- switch (ch) { +- case 'd': +- case 'i': +- switch (cflags) { +- case DP_C_SHORT: +- value = (short int)va_arg(args, int); +- break; +- case DP_C_LONG: +- value = va_arg(args, long int); +- break; +- case DP_C_LLONG: +- value = va_arg(args, LLONG); +- break; +- default: +- value = va_arg(args, int); +- break; +- } +- fmtint(sbuffer, buffer, &currlen, maxlen, +- value, 10, min, max, flags); +- break; +- case 'X': +- flags |= DP_F_UP; +- /* FALLTHROUGH */ +- case 'x': +- case 'o': +- case 'u': +- flags |= DP_F_UNSIGNED; +- switch (cflags) { +- case DP_C_SHORT: +- value = (unsigned short int)va_arg(args, unsigned int); +- break; +- case DP_C_LONG: +- value = (LLONG) va_arg(args, +- unsigned long int); +- break; +- case DP_C_LLONG: +- value = va_arg(args, unsigned LLONG); +- break; +- default: +- value = (LLONG) va_arg(args, +- unsigned int); +- break; +- } +- fmtint(sbuffer, buffer, &currlen, maxlen, value, +- ch == 'o' ? 8 : (ch == 'u' ? 10 : 16), +- min, max, flags); +- break; +- case 'f': +- if (cflags == DP_C_LDOUBLE) +- fvalue = va_arg(args, LDOUBLE); +- else +- fvalue = va_arg(args, double); +- fmtfp(sbuffer, buffer, &currlen, maxlen, +- fvalue, min, max, flags); +- break; +- case 'E': +- flags |= DP_F_UP; +- case 'e': +- if (cflags == DP_C_LDOUBLE) +- fvalue = va_arg(args, LDOUBLE); +- else +- fvalue = va_arg(args, double); +- break; +- case 'G': +- flags |= DP_F_UP; +- case 'g': +- if (cflags == DP_C_LDOUBLE) +- fvalue = va_arg(args, LDOUBLE); +- else +- fvalue = va_arg(args, double); +- break; +- case 'c': +- doapr_outch(sbuffer, buffer, &currlen, maxlen, +- va_arg(args, int)); +- break; +- case 's': +- strvalue = va_arg(args, char *); +- if (max < 0) { +- if (buffer) +- max = INT_MAX; +- else +- max = *maxlen; +- } +- fmtstr(sbuffer, buffer, &currlen, maxlen, strvalue, +- flags, min, max); +- break; +- case 'p': +- value = (long)va_arg(args, void *); +- fmtint(sbuffer, buffer, &currlen, maxlen, +- value, 16, min, max, flags|DP_F_NUM); +- break; +- case 'n': /* XXX */ +- if (cflags == DP_C_SHORT) { +- short int *num; +- num = va_arg(args, short int *); +- *num = currlen; +- } else if (cflags == DP_C_LONG) { /* XXX */ +- long int *num; +- num = va_arg(args, long int *); +- *num = (long int) currlen; +- } else if (cflags == DP_C_LLONG) { /* XXX */ +- LLONG *num; +- num = va_arg(args, LLONG *); +- *num = (LLONG) currlen; +- } else { +- int *num; +- num = va_arg(args, int *); +- *num = currlen; +- } +- break; +- case '%': +- doapr_outch(sbuffer, buffer, &currlen, maxlen, ch); +- break; +- case 'w': +- /* not supported yet, treat as next char */ +- ch = *format++; +- break; +- default: +- /* unknown, skip */ +- break; +- } +- ch = *format++; +- state = DP_S_DEFAULT; +- flags = cflags = min = 0; +- max = -1; +- break; +- case DP_S_DONE: +- break; +- default: +- break; +- } +- } +- *truncated = (currlen > *maxlen - 1); +- if (*truncated) +- currlen = *maxlen - 1; +- doapr_outch(sbuffer, buffer, &currlen, maxlen, '\0'); +- *retlen = currlen - 1; +- return; +-} +- +-static void +-fmtstr( +- char **sbuffer, +- char **buffer, +- size_t *currlen, +- size_t *maxlen, +- const char *value, +- int flags, +- int min, +- int max) +-{ +- int padlen, strln; +- int cnt = 0; +- +- if (value == 0) +- value = ""; +- for (strln = 0; value[strln]; ++strln) +- ; +- padlen = min - strln; +- if (padlen < 0) +- padlen = 0; +- if (flags & DP_F_MINUS) +- padlen = -padlen; +- +- while ((padlen > 0) && (cnt < max)) { +- doapr_outch(sbuffer, buffer, currlen, maxlen, ' '); +- --padlen; +- ++cnt; +- } +- while (*value && (cnt < max)) { +- doapr_outch(sbuffer, buffer, currlen, maxlen, *value++); +- ++cnt; +- } +- while ((padlen < 0) && (cnt < max)) { +- doapr_outch(sbuffer, buffer, currlen, maxlen, ' '); +- ++padlen; +- ++cnt; +- } +-} +- +-static void +-fmtint( +- char **sbuffer, +- char **buffer, +- size_t *currlen, +- size_t *maxlen, +- LLONG value, +- int base, +- int min, +- int max, +- int flags) +-{ +- int signvalue = 0; +- const char *prefix = ""; +- unsigned LLONG uvalue; +- char convert[DECIMAL_SIZE(value)+3]; +- int place = 0; +- int spadlen = 0; +- int zpadlen = 0; +- int caps = 0; +- +- if (max < 0) +- max = 0; +- uvalue = value; +- if (!(flags & DP_F_UNSIGNED)) { +- if (value < 0) { +- signvalue = '-'; +- uvalue = -value; +- } else if (flags & DP_F_PLUS) +- signvalue = '+'; +- else if (flags & DP_F_SPACE) +- signvalue = ' '; +- } +- if (flags & DP_F_NUM) { +- if (base == 8) prefix = "0"; +- if (base == 16) prefix = "0x"; +- } +- if (flags & DP_F_UP) +- caps = 1; +- do { +- convert[place++] = +- (caps ? "0123456789ABCDEF" : "0123456789abcdef") +- [uvalue % (unsigned) base]; +- uvalue = (uvalue / (unsigned) base); +- } while (uvalue && (place < (int)sizeof(convert))); +- if (place == sizeof(convert)) +- place--; +- convert[place] = 0; +- +- zpadlen = max - place; +- spadlen = min - OSSL_MAX(max, place) - (signvalue ? 1 : 0) - strlen(prefix); +- if (zpadlen < 0) +- zpadlen = 0; +- if (spadlen < 0) +- spadlen = 0; +- if (flags & DP_F_ZERO) { +- zpadlen = OSSL_MAX(zpadlen, spadlen); +- spadlen = 0; +- } +- if (flags & DP_F_MINUS) +- spadlen = -spadlen; +- +- /* spaces */ +- while (spadlen > 0) { +- doapr_outch(sbuffer, buffer, currlen, maxlen, ' '); +- --spadlen; +- } +- +- /* sign */ +- if (signvalue) +- doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue); +- +- /* prefix */ +- while (*prefix) { +- doapr_outch(sbuffer, buffer, currlen, maxlen, *prefix); +- prefix++; +- } +- +- /* zeros */ +- if (zpadlen > 0) { +- while (zpadlen > 0) { +- doapr_outch(sbuffer, buffer, currlen, maxlen, '0'); +- --zpadlen; +- } +- } +- /* digits */ +- while (place > 0) +- doapr_outch(sbuffer, buffer, currlen, maxlen, convert[--place]); +- +- /* left justified spaces */ +- while (spadlen < 0) { +- doapr_outch(sbuffer, buffer, currlen, maxlen, ' '); +- ++spadlen; +- } +- return; +-} +- +-static LDOUBLE +-abs_val(LDOUBLE value) +-{ +- LDOUBLE result = value; +- if (value < 0) +- result = -value; +- return result; +-} +- +-static LDOUBLE +-pow_10(int in_exp) +-{ +- LDOUBLE result = 1; +- while (in_exp) { +- result *= 10; +- in_exp--; +- } +- return result; +-} +- +-static long +-roundv(LDOUBLE value) +-{ +- long intpart; +- intpart = (long) value; +- value = value - intpart; +- if (value >= 0.5) +- intpart++; +- return intpart; +-} +- +-static void +-fmtfp( +- char **sbuffer, +- char **buffer, +- size_t *currlen, +- size_t *maxlen, +- LDOUBLE fvalue, +- int min, +- int max, +- int flags) +-{ +- int signvalue = 0; +- LDOUBLE ufvalue; +- char iconvert[20]; +- char fconvert[20]; +- int iplace = 0; +- int fplace = 0; +- int padlen = 0; +- int zpadlen = 0; +- int caps = 0; +- long intpart; +- long fracpart; +- long max10; +- +- if (max < 0) +- max = 6; +- ufvalue = abs_val(fvalue); +- if (fvalue < 0) +- signvalue = '-'; +- else if (flags & DP_F_PLUS) +- signvalue = '+'; +- else if (flags & DP_F_SPACE) +- signvalue = ' '; +- +- intpart = (long)ufvalue; +- +- /* sorry, we only support 9 digits past the decimal because of our +- conversion method */ +- if (max > 9) +- max = 9; +- +- /* we "cheat" by converting the fractional part to integer by +- multiplying by a factor of 10 */ +- max10 = roundv(pow_10(max)); +- fracpart = roundv(pow_10(max) * (ufvalue - intpart)); +- +- if (fracpart >= max10) { +- intpart++; +- fracpart -= max10; +- } +- +- /* convert integer part */ +- do { +- iconvert[iplace++] = +- (caps ? "0123456789ABCDEF" +- : "0123456789abcdef")[intpart % 10]; +- intpart = (intpart / 10); +- } while (intpart && (iplace < (int)sizeof(iconvert))); +- if (iplace == sizeof iconvert) +- iplace--; +- iconvert[iplace] = 0; +- +- /* convert fractional part */ +- do { +- fconvert[fplace++] = +- (caps ? "0123456789ABCDEF" +- : "0123456789abcdef")[fracpart % 10]; +- fracpart = (fracpart / 10); +- } while (fplace < max); +- if (fplace == sizeof fconvert) +- fplace--; +- fconvert[fplace] = 0; +- +- /* -1 for decimal point, another -1 if we are printing a sign */ +- padlen = min - iplace - max - 1 - ((signvalue) ? 1 : 0); +- zpadlen = max - fplace; +- if (zpadlen < 0) +- zpadlen = 0; +- if (padlen < 0) +- padlen = 0; +- if (flags & DP_F_MINUS) +- padlen = -padlen; +- +- if ((flags & DP_F_ZERO) && (padlen > 0)) { +- if (signvalue) { +- doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue); +- --padlen; +- signvalue = 0; +- } +- while (padlen > 0) { +- doapr_outch(sbuffer, buffer, currlen, maxlen, '0'); +- --padlen; +- } +- } +- while (padlen > 0) { +- doapr_outch(sbuffer, buffer, currlen, maxlen, ' '); +- --padlen; +- } +- if (signvalue) +- doapr_outch(sbuffer, buffer, currlen, maxlen, signvalue); +- +- while (iplace > 0) +- doapr_outch(sbuffer, buffer, currlen, maxlen, iconvert[--iplace]); +- +- /* +- * Decimal point. This should probably use locale to find the correct +- * char to print out. +- */ +- if (max > 0 || (flags & DP_F_NUM)) { +- doapr_outch(sbuffer, buffer, currlen, maxlen, '.'); +- +- while (fplace > 0) +- doapr_outch(sbuffer, buffer, currlen, maxlen, fconvert[--fplace]); +- } +- while (zpadlen > 0) { +- doapr_outch(sbuffer, buffer, currlen, maxlen, '0'); +- --zpadlen; +- } +- +- while (padlen < 0) { +- doapr_outch(sbuffer, buffer, currlen, maxlen, ' '); +- ++padlen; +- } +-} +- +-static void +-doapr_outch( +- char **sbuffer, +- char **buffer, +- size_t *currlen, +- size_t *maxlen, +- int c) +-{ +- /* If we haven't at least one buffer, someone has doe a big booboo */ +- assert(*sbuffer != NULL || buffer != NULL); +- +- if (buffer) { +- while (*currlen >= *maxlen) { +- if (*buffer == NULL) { +- if (*maxlen == 0) +- *maxlen = 1024; +- *buffer = OPENSSL_malloc(*maxlen); +- if (*currlen > 0) { +- assert(*sbuffer != NULL); +- memcpy(*buffer, *sbuffer, *currlen); +- } +- *sbuffer = NULL; +- } else { +- *maxlen += 1024; +- *buffer = OPENSSL_realloc(*buffer, *maxlen); +- } +- } +- /* What to do if *buffer is NULL? */ +- assert(*sbuffer != NULL || *buffer != NULL); +- } +- +- if (*currlen < *maxlen) { +- if (*sbuffer) +- (*sbuffer)[(*currlen)++] = (char)c; +- else +- (*buffer)[(*currlen)++] = (char)c; +- } +- +- return; +-} +- + /***************************************************************************/ + + int BIO_printf (BIO *bio, const char *format, ...) +@@ -778,65 +86,70 @@ int BIO_printf (BIO *bio, const char *format, ...) + return(ret); + } + ++static ssize_t cookie_BIO_write(void *cookie, const char *buf, size_t size) ++{ ++ int ret; ++ ret = BIO_write(cookie, buf, size); ++ /* BIO_write may return negative value on error, ++ * but we must return 0 on that case ++ */ ++ return (ret < 0) ? 0 : ret; ++} ++ + int BIO_vprintf (BIO *bio, const char *format, va_list args) +- { ++{ ++ FILE *fp; + int ret; +- size_t retlen; +- char hugebuf[1024*2]; /* Was previously 10k, which is unreasonable +- in small-stack environments, like threads +- or DOS programs. */ +- char *hugebufp = hugebuf; +- size_t hugebufsize = sizeof(hugebuf); +- char *dynbuf = NULL; +- int ignored; ++ ++ cookie_io_functions_t bio_funcs = { ++ .read = NULL, ++ .write = cookie_BIO_write, ++ .seek = NULL, ++ .close = NULL, ++ }; ++ ++ fp = fopencookie(bio, "w", bio_funcs); ++ ++ if (fp == NULL) ++ return -1; ++ ++ ret = vfprintf(fp, format, args); ++ ++ fclose(fp); + +- dynbuf = NULL; +- CRYPTO_push_info("doapr()"); +- _dopr(&hugebufp, &dynbuf, &hugebufsize, +- &retlen, &ignored, format, args); +- if (dynbuf) +- { +- ret=BIO_write(bio, dynbuf, (int)retlen); +- OPENSSL_free(dynbuf); +- } +- else +- { +- ret=BIO_write(bio, hugebuf, (int)retlen); +- } +- CRYPTO_pop_info(); + return(ret); +- } ++} + + /* As snprintf is not available everywhere, we provide our own implementation. + * This function has nothing to do with BIOs, but it's closely related + * to BIO_printf, and we need *some* name prefix ... + * (XXX the function should be renamed, but to what?) */ + int BIO_snprintf(char *buf, size_t n, const char *format, ...) +- { ++{ + va_list args; + int ret; + + va_start(args, format); + +- ret = BIO_vsnprintf(buf, n, format, args); ++ ret = vsnprintf(buf, n, format, args); + + va_end(args); ++ ++ if (ret >= n || ret == -1) return (-1); ++ + return(ret); +- } ++} + + int BIO_vsnprintf(char *buf, size_t n, const char *format, va_list args) +- { +- size_t retlen; +- int truncated; ++{ ++ ++ int ret; ++ ++ ret = vsnprintf(buf, n, format, args); + +- _dopr(&buf, NULL, &n, &retlen, &truncated, format, args); ++ if (ret >= n || ret == -1) ++ return (-1); + +- if (truncated) +- /* In case of truncation, return -1 like traditional snprintf. +- * (Current drafts for ISO/IEC 9899 say snprintf should return +- * the number of characters that would have been written, +- * had the buffer been large enough.) */ +- return -1; +- else +- return (retlen <= INT_MAX) ? (int)retlen : -1; +- } ++ return (ret); ++ ++} +-- +1.8.4.5 + diff --git a/0005-libssl-Hide-library-private-symbols.patch b/0005-libssl-Hide-library-private-symbols.patch index ac7c7e7..c0a0c08 100644 --- a/0005-libssl-Hide-library-private-symbols.patch +++ b/0005-libssl-Hide-library-private-symbols.patch @@ -1,20 +1,42 @@ -From 89d5aecbc62842651cf22e48c405eb435feb0df3 Mon Sep 17 00:00:00 2001 +From f33b5a4cb7da3947d06b74e6f6cd2f264faca170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cristian=20Rodr=C3=ADguez?= -Date: Wed, 24 Jul 2013 23:29:05 -0400 -Subject: [PATCH 5/5] libssl: Hide library private symbols - -This patch only contains the libssl part (the easy one) -patch to libcrypto will follow after it is complete and good enough. +Date: Sun, 20 Apr 2014 19:39:37 -0300 +Subject: [PATCH] libssl: Hide library private symbols It hides all the library symbols that are not part of the public API/ABI when GCC 4 or later is used. --- + ssl/d1_lib.c | 5 ++--- ssl/kssl_lcl.h | 9 +++++++++ + ssl/s23_srvr.c | 4 ++-- + ssl/s2_lib.c | 1 - + ssl/s3_lib.c | 1 - + ssl/ssl_lib.c | 1 - ssl/ssl_locl.h | 8 ++++++++ - 2 files changed, 17 insertions(+) + ssl/t1_lib.c | 6 ++---- + 8 files changed, 23 insertions(+), 12 deletions(-) -Index: openssl-1.0.1g/ssl/kssl_lcl.h -=================================================================== +--- openssl-1.0.1g.orig/ssl/d1_lib.c ++++ openssl-1.0.1g/ssl/d1_lib.c +@@ -67,8 +67,7 @@ + #endif + + static void get_current_time(struct timeval *t); +-const char dtls1_version_str[]="DTLSv1" OPENSSL_VERSION_PTEXT; +-int dtls1_listen(SSL *s, struct sockaddr *client); ++static int dtls1_listen(SSL *s, struct sockaddr *client); + + SSL3_ENC_METHOD DTLSv1_enc_data={ + dtls1_enc, +@@ -468,7 +467,7 @@ static void get_current_time(struct time + #endif + } + +-int dtls1_listen(SSL *s, struct sockaddr *client) ++static int dtls1_listen(SSL *s, struct sockaddr *client) + { + int ret; + --- openssl-1.0.1g.orig/ssl/kssl_lcl.h +++ openssl-1.0.1g/ssl/kssl_lcl.h @@ -61,6 +61,10 @@ @@ -38,8 +60,56 @@ Index: openssl-1.0.1g/ssl/kssl_lcl.h +#endif + #endif /* KSSL_LCL_H */ -Index: openssl-1.0.1g/ssl/ssl_locl.h -=================================================================== +--- openssl-1.0.1g.orig/ssl/s23_srvr.c ++++ openssl-1.0.1g/ssl/s23_srvr.c +@@ -120,7 +120,7 @@ + #endif + + static const SSL_METHOD *ssl23_get_server_method(int ver); +-int ssl23_get_client_hello(SSL *s); ++static int ssl23_get_client_hello(SSL *s); + static const SSL_METHOD *ssl23_get_server_method(int ver) + { + #ifndef OPENSSL_NO_SSL2 +@@ -235,7 +235,7 @@ end: + } + + +-int ssl23_get_client_hello(SSL *s) ++static int ssl23_get_client_hello(SSL *s) + { + char buf_space[11]; /* Request this many bytes in initial read. + * We can detect SSL 3.0/TLS 1.0 Client Hellos +--- openssl-1.0.1g.orig/ssl/s2_lib.c ++++ openssl-1.0.1g/ssl/s2_lib.c +@@ -116,7 +116,6 @@ + #include + #include + +-const char ssl2_version_str[]="SSLv2" OPENSSL_VERSION_PTEXT; + + #define SSL2_NUM_CIPHERS (sizeof(ssl2_ciphers)/sizeof(SSL_CIPHER)) + +--- openssl-1.0.1g.orig/ssl/s3_lib.c ++++ openssl-1.0.1g/ssl/s3_lib.c +@@ -162,7 +162,6 @@ + #include + #endif + +-const char ssl3_version_str[]="SSLv3" OPENSSL_VERSION_PTEXT; + + #define SSL3_NUM_CIPHERS (sizeof(ssl3_ciphers)/sizeof(SSL_CIPHER)) + +--- openssl-1.0.1g.orig/ssl/ssl_lib.c ++++ openssl-1.0.1g/ssl/ssl_lib.c +@@ -160,7 +160,6 @@ + #include + #endif + +-const char *SSL_version_str=OPENSSL_VERSION_TEXT; + + SSL3_ENC_METHOD ssl3_undef_enc_method={ + /* evil casts, but these functions are only called if there's a library bug */ --- openssl-1.0.1g.orig/ssl/ssl_locl.h +++ openssl-1.0.1g/ssl/ssl_locl.h @@ -165,6 +165,10 @@ @@ -53,12 +123,26 @@ Index: openssl-1.0.1g/ssl/ssl_locl.h #ifdef OPENSSL_BUILD_SHLIBSSL # undef OPENSSL_EXTERN # define OPENSSL_EXTERN OPENSSL_EXPORT -@@ -1174,4 +1178,8 @@ void tls_fips_digest_extra( +@@ -1174,4 +1178,12 @@ void tls_fips_digest_extra( const EVP_CIPHER_CTX *cipher_ctx, EVP_MD_CTX *mac_ctx, const unsigned char *data, size_t data_len, size_t orig_len); ++int private_tls1_PRF(long digest_mask, const void *seed1, int seed1_len, const void *seed2, int seed2_len, ++ const void *seed3, int seed3_len, const void *seed4, int seed4_len, const void *seed5, int seed5_len, ++ const unsigned char *sec, int slen, unsigned char *out1, unsigned char *out2, int olen); ++ +#if defined(__GNUC__) && __GNUC__ >= 4 +#pragma GCC visibility pop +#endif + #endif +--- openssl-1.0.1g.orig/ssl/t1_lib.c ++++ openssl-1.0.1g/ssl/t1_lib.c +@@ -117,7 +117,6 @@ + #include + #include "ssl_locl.h" + +-const char tls1_version_str[]="TLSv1" OPENSSL_VERSION_PTEXT; + + #ifndef OPENSSL_NO_TLSEXT + static int tls_decrypt_ticket(SSL *s, const unsigned char *tick, int ticklen, diff --git a/0009-Fix-double-frees.patch b/0009-Fix-double-frees.patch new file mode 100644 index 0000000..ac24d4d --- /dev/null +++ b/0009-Fix-double-frees.patch @@ -0,0 +1,51 @@ +From 9c8dc84ac16a2f21063ae36809d202d0284ecf82 Mon Sep 17 00:00:00 2001 +From: Ben Laurie +Date: Tue, 22 Apr 2014 13:11:56 +0100 +Subject: [PATCH 09/17] Fix double frees. + +--- + CHANGES | 3 ++- + crypto/pkcs7/pk7_doit.c | 1 + + crypto/ts/ts_rsp_verify.c | 1 + + ssl/d1_srvr.c | 1 + + 4 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c +index 77fda3b..4c12a9d 100644 +--- a/crypto/pkcs7/pk7_doit.c ++++ b/crypto/pkcs7/pk7_doit.c +@@ -928,6 +928,7 @@ int PKCS7_SIGNER_INFO_sign(PKCS7_SIGNER_INFO *si) + if (EVP_DigestSignUpdate(&mctx,abuf,alen) <= 0) + goto err; + OPENSSL_free(abuf); ++ abuf = NULL; + if (EVP_DigestSignFinal(&mctx, NULL, &siglen) <= 0) + goto err; + abuf = OPENSSL_malloc(siglen); +diff --git a/crypto/ts/ts_rsp_verify.c b/crypto/ts/ts_rsp_verify.c +index afe16af..b7d170a 100644 +--- a/crypto/ts/ts_rsp_verify.c ++++ b/crypto/ts/ts_rsp_verify.c +@@ -629,6 +629,7 @@ static int TS_compute_imprint(BIO *data, TS_TST_INFO *tst_info, + X509_ALGOR_free(*md_alg); + OPENSSL_free(*imprint); + *imprint_len = 0; ++ *imprint = NULL; + return 0; + } + +diff --git a/ssl/d1_srvr.c b/ssl/d1_srvr.c +index 9975e20..1384ab0 100644 +--- a/ssl/d1_srvr.c ++++ b/ssl/d1_srvr.c +@@ -1356,6 +1356,7 @@ int dtls1_send_server_key_exchange(SSL *s) + (unsigned char *)encodedPoint, + encodedlen); + OPENSSL_free(encodedPoint); ++ encodedPoint = NULL; + p += encodedlen; + } + #endif +-- +1.8.4.5 + diff --git a/0012-Fix-eckey_priv_encode.patch b/0012-Fix-eckey_priv_encode.patch new file mode 100644 index 0000000..7a41324 --- /dev/null +++ b/0012-Fix-eckey_priv_encode.patch @@ -0,0 +1,26 @@ +From f0816174d264b11f6f4ccb41c75883640a2416bb Mon Sep 17 00:00:00 2001 +From: mancha +Date: Thu, 24 Apr 2014 19:06:20 +0000 +Subject: [PATCH 12/17] Fix eckey_priv_encode() + +Fix eckey_priv_encode to return an error on failure of i2d_ECPrivateKey. +--- + CHANGES | 4 ++++ + crypto/ec/ec_ameth.c | 1 + + 2 files changed, 5 insertions(+) + +diff --git a/crypto/ec/ec_ameth.c b/crypto/ec/ec_ameth.c +index 0ce4524..f715a23 100644 +--- a/crypto/ec/ec_ameth.c ++++ b/crypto/ec/ec_ameth.c +@@ -352,6 +352,7 @@ static int eckey_priv_encode(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pkey) + EC_KEY_set_enc_flags(ec_key, old_flags); + OPENSSL_free(ep); + ECerr(EC_F_ECKEY_PRIV_ENCODE, ERR_R_EC_LIB); ++ return 0; + } + /* restore old encoding flags */ + EC_KEY_set_enc_flags(ec_key, old_flags); +-- +1.8.4.5 + diff --git a/0017-Double-free-in-i2o_ECPublicKey.patch b/0017-Double-free-in-i2o_ECPublicKey.patch new file mode 100644 index 0000000..e897722 --- /dev/null +++ b/0017-Double-free-in-i2o_ECPublicKey.patch @@ -0,0 +1,31 @@ +From 8eb094b9460575a328ba04708147c91fc267b394 Mon Sep 17 00:00:00 2001 +From: David Ramos +Date: Sat, 3 May 2014 12:00:27 +0200 +Subject: [PATCH 17/17] Double free in i2o_ECPublicKey + +PR: 3338 +--- + crypto/ec/ec_asn1.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/crypto/ec/ec_asn1.c b/crypto/ec/ec_asn1.c +index 145807b..e94f34e 100644 +--- a/crypto/ec/ec_asn1.c ++++ b/crypto/ec/ec_asn1.c +@@ -1435,8 +1435,11 @@ int i2o_ECPublicKey(EC_KEY *a, unsigned char **out) + *out, buf_len, NULL)) + { + ECerr(EC_F_I2O_ECPUBLICKEY, ERR_R_EC_LIB); +- OPENSSL_free(*out); +- *out = NULL; ++ if (new_buffer) ++ { ++ OPENSSL_free(*out); ++ *out = NULL; ++ } + return 0; + } + if (!new_buffer) +-- +1.8.4.5 + diff --git a/openssl-gcc-attributes.patch b/openssl-gcc-attributes.patch index 2422937..973a7b1 100644 --- a/openssl-gcc-attributes.patch +++ b/openssl-gcc-attributes.patch @@ -32,3 +32,14 @@ void OPENSSL_cleanse(void *ptr, size_t len); +--- openssl-1.0.1g.orig/crypto/buffer/buffer.h ++++ openssl-1.0.1g/crypto/buffer/buffer.h +@@ -87,7 +87,7 @@ int BUF_MEM_grow(BUF_MEM *str, size_t le + int BUF_MEM_grow_clean(BUF_MEM *str, size_t len); + char * BUF_strdup(const char *str); + char * BUF_strndup(const char *str, size_t siz); +-void * BUF_memdup(const void *data, size_t siz); ++void * BUF_memdup(const void *data, size_t siz) __attribute__((alloc_size(2))); + void BUF_reverse(unsigned char *out, const unsigned char *in, size_t siz); + + /* safe string functions */ diff --git a/openssl-ocloexec.patch b/openssl-ocloexec.patch index a5d975f..933b92e 100644 --- a/openssl-ocloexec.patch +++ b/openssl-ocloexec.patch @@ -1,5 +1,3 @@ -Index: crypto/bio/b_sock.c -=================================================================== --- crypto/bio/b_sock.c.orig +++ crypto/bio/b_sock.c @@ -735,7 +735,7 @@ int BIO_get_accept_socket(char *host, in @@ -20,8 +18,15 @@ Index: crypto/bio/b_sock.c if (cs != INVALID_SOCKET) { int ii; -Index: crypto/bio/bss_conn.c -=================================================================== +@@ -866,7 +866,7 @@ int BIO_accept(int sock, char **addr) + sa.len.s=0; + sa.len.i=sizeof(sa.from); + memset(&sa.from,0,sizeof(sa.from)); +- ret=accept(sock,&sa.from.sa,(void *)&sa.len); ++ ret=accept4(sock, &sa.from.sa, (void *)&sa.len, SOCK_CLOEXEC); + if (sizeof(sa.len.i)!=sizeof(sa.len.s) && sa.len.i==0) + { + OPENSSL_assert(sa.len.s<=sizeof(sa.from)); --- crypto/bio/bss_conn.c.orig +++ crypto/bio/bss_conn.c @@ -209,7 +209,7 @@ static int conn_state(BIO *b, BIO_CONNEC @@ -33,8 +38,6 @@ Index: crypto/bio/bss_conn.c if (ret == INVALID_SOCKET) { SYSerr(SYS_F_SOCKET,get_last_socket_error()); -Index: crypto/bio/bss_dgram.c -=================================================================== --- crypto/bio/bss_dgram.c.orig +++ crypto/bio/bss_dgram.c @@ -1032,7 +1032,7 @@ static int dgram_sctp_read(BIO *b, char @@ -91,8 +94,6 @@ Index: crypto/bio/bss_dgram.c if (data->handle_notifications != NULL) data->handle_notifications(b, data->notification_context, (void*) &snp); -Index: crypto/bio/bss_file.c -=================================================================== --- crypto/bio/bss_file.c.orig +++ crypto/bio/bss_file.c @@ -120,6 +120,10 @@ BIO *BIO_new_file(const char *filename, @@ -133,8 +134,6 @@ Index: crypto/bio/bss_file.c fp=fopen(ptr,p); if (fp == NULL) { -Index: crypto/rand/rand_unix.c -=================================================================== --- crypto/rand/rand_unix.c.orig +++ crypto/rand/rand_unix.c @@ -262,7 +262,7 @@ int RAND_poll(void) @@ -146,8 +145,6 @@ Index: crypto/rand/rand_unix.c #ifdef O_NONBLOCK |O_NONBLOCK #endif -Index: crypto/rand/randfile.c -=================================================================== --- crypto/rand/randfile.c.orig +++ crypto/rand/randfile.c @@ -136,7 +136,7 @@ int RAND_load_file(const char *file, lon diff --git a/openssl.changes b/openssl.changes index 7608765..2d81aeb 100644 --- a/openssl.changes +++ b/openssl.changes @@ -1,3 +1,33 @@ +------------------------------------------------------------------- +Mon May 5 16:25:17 UTC 2014 - crrodriguez@opensuse.org + +- 0005-libssl-Hide-library-private-symbols.patch + Update to hide more symbols that are not part of + the public API + +- openssl-gcc-attributes.patch BUF_memdup also + needs attribute alloc_size as it returns memory + of size of the second parameter. + +- openssl-ocloexec.patch Update, accept() + also needs O_CLOEXEC. + +- 0009-Fix-double-frees.patch, 0017-Double-free-in-i2o_ECPublicKey.patch + fix various double frees (from upstream) + +- 012-Fix-eckey_priv_encode.patch eckey_priv_encode should + return an error inmediately on failure of i2d_ECPrivateKey (from upstream) + +- 0001-Axe-builtin-printf-implementation-use-glibc-instead.patch + From libressl, modified to work on linux systems that do not have + funopen() but fopencookie() instead. + Once upon a time, OS didn't have snprintf, which caused openssl to + bundle a *printf implementation. We know better nowadays, the glibc + implementation has buffer overflow checking, has sane failure modes + deal properly with threads, signals..etc.. + +- build with -fno-common as well. + ------------------------------------------------------------------- Mon May 5 06:45:19 UTC 2014 - citypw@gmail.com diff --git a/openssl.spec b/openssl.spec index fbf586d..22cdfc2 100644 --- a/openssl.spec +++ b/openssl.spec @@ -68,6 +68,10 @@ Patch19: openssl-gcc-attributes.patch Patch20: openssl-buffreelistbug-aka-CVE-2010-5298.patch Patch21: openssl-libssl-noweakciphers.patch Patch22: CVE-2014-0198.patch +Patch23: 0009-Fix-double-frees.patch +Patch24: 0012-Fix-eckey_priv_encode.patch +Patch25: 0017-Double-free-in-i2o_ECPublicKey.patch +Patch26: 0001-Axe-builtin-printf-implementation-use-glibc-instead.patch BuildRoot: %{_tmppath}/%{name}-%{version}-build %description @@ -177,6 +181,10 @@ this package's base documentation. %patch20 -p1 %patch21 -p1 %patch22 -p1 +%patch23 -p1 +%patch24 -p1 +%patch25 -p1 +%patch26 -p1 cp -p %{S:10} . cp -p %{S:11} . echo "adding/overwriting some entries in the 'table' hash in Configure" @@ -240,7 +248,7 @@ no-ec2m \ $RPM_OPT_FLAGS -O3 -std=gnu99 \ -Wa,--noexecstack \ -Wl,-z,relro,-z,now \ --fomit-frame-pointer \ +-fno-common \ -DTERMIO \ -DPURIFY \ -DSSL_FORBID_ENULL \