Update to 0.24.3; Add support for OpenSSL 1.1.0

Signed-off-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
This commit is contained in:
Igor Gnatenko 2016-11-03 18:53:56 +01:00
parent a1fed87ff1
commit d3dc6b84a1
8 changed files with 541 additions and 50 deletions

1
.gitignore vendored
View File

@ -15,3 +15,4 @@
/libgit2-0.24.0.tar.gz
/libgit2-0.24.1.tar.gz
/libgit2-0.24.2.tar.gz
/libgit2-0.24.3.tar.gz

View File

@ -0,0 +1,115 @@
From eee5cc4e72ee70e0df7bb6c4fc9ba5499d1e0d22 Mon Sep 17 00:00:00 2001
From: Igor Gnatenko <i.gnatenko.brain@gmail.com>
Date: Wed, 12 Oct 2016 12:41:36 +0200
Subject: [PATCH 1/4] add support for OpenSSL 1.1.0 for BIO filter
Closes: https://github.com/libgit2/libgit2/issues/3959
Signed-off-by: Igor Gnatenko <i.gnatenko.brain@gmail.com>
(cherry picked from commit feb330d50d0fc10aceec6309131e912e152a1027)
---
src/openssl_stream.c | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/src/openssl_stream.c b/src/openssl_stream.c
index 9d97bae..fc580cf 100644
--- a/src/openssl_stream.c
+++ b/src/openssl_stream.c
@@ -156,10 +156,14 @@ int git_openssl_set_locking(void)
static int bio_create(BIO *b)
{
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
b->init = 1;
b->num = 0;
b->ptr = NULL;
b->flags = 0;
+#else
+ BIO_set_init(b, 1);
+#endif
return 1;
}
@@ -169,23 +173,36 @@ static int bio_destroy(BIO *b)
if (!b)
return 0;
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
b->init = 0;
b->num = 0;
b->ptr = NULL;
b->flags = 0;
+#else
+ BIO_set_init(b, 0);
+ BIO_set_data(b, NULL);
+#endif
return 1;
}
static int bio_read(BIO *b, char *buf, int len)
{
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
git_stream *io = (git_stream *) b->ptr;
+#else
+ git_stream *io = (git_stream *) BIO_get_data(b);
+#endif
return (int) git_stream_read(io, buf, len);
}
static int bio_write(BIO *b, const char *buf, int len)
{
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
git_stream *io = (git_stream *) b->ptr;
+#else
+ git_stream *io = (git_stream *) BIO_get_data(b);
+#endif
return (int) git_stream_write(io, buf, len, 0);
}
@@ -214,6 +231,7 @@ static int bio_puts(BIO *b, const char *str)
return bio_write(b, str, strlen(str));
}
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
static BIO_METHOD git_stream_bio_method = {
BIO_TYPE_SOURCE_SINK,
"git_stream",
@@ -225,6 +243,9 @@ static BIO_METHOD git_stream_bio_method = {
bio_create,
bio_destroy
};
+#else
+static BIO_METHOD *git_stream_bio_method = NULL;
+#endif
static int ssl_set_error(SSL *ssl, int error)
{
@@ -445,9 +466,25 @@ int openssl_connect(git_stream *stream)
st->connected = true;
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
bio = BIO_new(&git_stream_bio_method);
+#else
+ git_stream_bio_method = BIO_meth_new(BIO_TYPE_SOURCE_SINK | BIO_get_new_index(), "git_stream");
+ BIO_meth_set_write(git_stream_bio_method, bio_write);
+ BIO_meth_set_read(git_stream_bio_method, bio_read);
+ BIO_meth_set_puts(git_stream_bio_method, bio_puts);
+ BIO_meth_set_gets(git_stream_bio_method, bio_gets);
+ BIO_meth_set_ctrl(git_stream_bio_method, bio_ctrl);
+ BIO_meth_set_create(git_stream_bio_method, bio_create);
+ BIO_meth_set_destroy(git_stream_bio_method, bio_destroy);
+ bio = BIO_new(git_stream_bio_method);
+#endif
GITERR_CHECK_ALLOC(bio);
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
bio->ptr = st->io;
+#else
+ BIO_set_data(bio, st->io);
+#endif
SSL_set_bio(st->ssl, bio, bio);
/* specify the host in case SNI is needed */
--
2.10.1

View File

@ -1,43 +0,0 @@
From a719ef5e6d4a1a8ec53469c7914032ed67922772 Mon Sep 17 00:00:00 2001
From: Patrick Steinhardt <ps@pks.im>
Date: Fri, 7 Oct 2016 09:31:41 +0200
Subject: [PATCH] commit: always initialize commit message
When parsing a commit, we will treat all bytes left after parsing
the headers as the commit message. When no bytes are left, we
leave the commit's message uninitialized. While uncommon to have
a commit without message, this is the right behavior as Git
unfortunately allows for empty commit messages.
Given that this scenario is so uncommon, most programs acting on
the commit message will never check if the message is actually
set, which may lead to errors. To work around the error and not
lay the burden of checking for empty commit messages to the
developer, initialize the commit message with an empty string
when no commit message is given.
---
src/commit.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/commit.c b/src/commit.c
index 99a8085..76e6dcb 100644
--- a/src/commit.c
+++ b/src/commit.c
@@ -459,10 +459,11 @@ int git_commit__parse(void *_commit, git_odb_object *odb_obj)
buffer = buffer_start + header_len + 1;
/* extract commit message */
- if (buffer <= buffer_end) {
+ if (buffer <= buffer_end)
commit->raw_message = git__strndup(buffer, buffer_end - buffer);
- GITERR_CHECK_ALLOC(commit->raw_message);
- }
+ else
+ commit->raw_message = git__strdup("");
+ GITERR_CHECK_ALLOC(commit->raw_message);
return 0;
--
2.10.1

View File

@ -0,0 +1,300 @@
From d3a5f68ae759bd5abaa5eb2ffb265210392462e1 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= <cmn@dwim.me>
Date: Wed, 2 Nov 2016 12:28:25 +0100
Subject: [PATCH 2/4] openssl: recreate the OpenSSL 1.1 BIO interface for older
versions
We want to program against the interface, so recreate it when we compile
against pre-1.1 versions.
(cherry picked from commit f15eedb3a390dcbe441cd77231c3449ff941d189)
---
src/openssl_stream.c | 92 ++++++++++++++++++++-----------------------------
src/openssl_stream.h | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 134 insertions(+), 55 deletions(-)
diff --git a/src/openssl_stream.c b/src/openssl_stream.c
index fc580cf..328a131 100644
--- a/src/openssl_stream.c
+++ b/src/openssl_stream.c
@@ -13,6 +13,7 @@
#include "posix.h"
#include "stream.h"
#include "socket_stream.h"
+#include "openssl_stream.h"
#include "netops.h"
#include "git2/transport.h"
#include "git2/sys/openssl.h"
@@ -71,12 +72,20 @@ static void shutdown_ssl_locking(void)
#endif /* GIT_THREADS */
+static BIO_METHOD *git_stream_bio_method;
+static int init_bio_method(void);
+
/**
* This function aims to clean-up the SSL context which
* we allocated.
*/
static void shutdown_ssl(void)
{
+ if (git_stream_bio_method) {
+ BIO_meth_free(git_stream_bio_method);
+ git_stream_bio_method = NULL;
+ }
+
if (git__ssl_ctx) {
SSL_CTX_free(git__ssl_ctx);
git__ssl_ctx = NULL;
@@ -121,6 +130,13 @@ int git_openssl_stream_global_init(void)
git__ssl_ctx = NULL;
return -1;
}
+
+ if (init_bio_method() < 0) {
+ SSL_CTX_free(git__ssl_ctx);
+ git__ssl_ctx = NULL;
+ return -1;
+ }
+
#endif
git__on_shutdown(shutdown_ssl);
@@ -156,14 +172,8 @@ int git_openssl_set_locking(void)
static int bio_create(BIO *b)
{
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
- b->init = 1;
- b->num = 0;
- b->ptr = NULL;
- b->flags = 0;
-#else
BIO_set_init(b, 1);
-#endif
+ BIO_set_data(b, NULL);
return 1;
}
@@ -173,36 +183,22 @@ static int bio_destroy(BIO *b)
if (!b)
return 0;
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
- b->init = 0;
- b->num = 0;
- b->ptr = NULL;
- b->flags = 0;
-#else
- BIO_set_init(b, 0);
BIO_set_data(b, NULL);
-#endif
return 1;
}
static int bio_read(BIO *b, char *buf, int len)
{
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
- git_stream *io = (git_stream *) b->ptr;
-#else
git_stream *io = (git_stream *) BIO_get_data(b);
-#endif
+
return (int) git_stream_read(io, buf, len);
}
static int bio_write(BIO *b, const char *buf, int len)
{
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
- git_stream *io = (git_stream *) b->ptr;
-#else
git_stream *io = (git_stream *) BIO_get_data(b);
-#endif
+
return (int) git_stream_write(io, buf, len, 0);
}
@@ -231,21 +227,22 @@ static int bio_puts(BIO *b, const char *str)
return bio_write(b, str, strlen(str));
}
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
-static BIO_METHOD git_stream_bio_method = {
- BIO_TYPE_SOURCE_SINK,
- "git_stream",
- bio_write,
- bio_read,
- bio_puts,
- bio_gets,
- bio_ctrl,
- bio_create,
- bio_destroy
-};
-#else
-static BIO_METHOD *git_stream_bio_method = NULL;
-#endif
+static int init_bio_method(void)
+{
+ /* Set up the BIO_METHOD we use for wrapping our own stream implementations */
+ git_stream_bio_method = BIO_meth_new(BIO_TYPE_SOURCE_SINK | BIO_get_new_index(), "git_stream");
+ GITERR_CHECK_ALLOC(git_stream_bio_method);
+
+ BIO_meth_set_write(git_stream_bio_method, bio_write);
+ BIO_meth_set_read(git_stream_bio_method, bio_read);
+ BIO_meth_set_puts(git_stream_bio_method, bio_puts);
+ BIO_meth_set_gets(git_stream_bio_method, bio_gets);
+ BIO_meth_set_ctrl(git_stream_bio_method, bio_ctrl);
+ BIO_meth_set_create(git_stream_bio_method, bio_create);
+ BIO_meth_set_destroy(git_stream_bio_method, bio_destroy);
+
+ return 0;
+}
static int ssl_set_error(SSL *ssl, int error)
{
@@ -466,27 +463,12 @@ int openssl_connect(git_stream *stream)
st->connected = true;
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
- bio = BIO_new(&git_stream_bio_method);
-#else
- git_stream_bio_method = BIO_meth_new(BIO_TYPE_SOURCE_SINK | BIO_get_new_index(), "git_stream");
- BIO_meth_set_write(git_stream_bio_method, bio_write);
- BIO_meth_set_read(git_stream_bio_method, bio_read);
- BIO_meth_set_puts(git_stream_bio_method, bio_puts);
- BIO_meth_set_gets(git_stream_bio_method, bio_gets);
- BIO_meth_set_ctrl(git_stream_bio_method, bio_ctrl);
- BIO_meth_set_create(git_stream_bio_method, bio_create);
- BIO_meth_set_destroy(git_stream_bio_method, bio_destroy);
bio = BIO_new(git_stream_bio_method);
-#endif
GITERR_CHECK_ALLOC(bio);
-#if OPENSSL_VERSION_NUMBER < 0x10100000L
- bio->ptr = st->io;
-#else
- BIO_set_data(bio, st->io);
-#endif
+ BIO_set_data(bio, st->io);
SSL_set_bio(st->ssl, bio, bio);
+
/* specify the host in case SNI is needed */
#ifdef SSL_CTRL_SET_TLSEXT_HOSTNAME
SSL_set_tlsext_host_name(st->ssl, st->host);
diff --git a/src/openssl_stream.h b/src/openssl_stream.h
index 82b5110..509e404 100644
--- a/src/openssl_stream.h
+++ b/src/openssl_stream.h
@@ -7,10 +7,107 @@
#ifndef INCLUDE_openssl_stream_h__
#define INCLUDE_openssl_stream_h__
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <openssl/x509v3.h>
+#include <openssl/bio.h>
+
#include "git2/sys/stream.h"
extern int git_openssl_stream_global_init(void);
extern int git_openssl_stream_new(git_stream **out, const char *host, const char *port);
+/*
+ * OpenSSL 1.1 made BIO opaque so we have to use functions to interact with it
+ * which do not exist in previous versions. We define these inline functions so
+ * we can program against the interface instead of littering the implementation
+ * with ifdefs.
+ */
+# if OPENSSL_VERSION_NUMBER < 0x10100000L
+
+GIT_INLINE(BIO_METHOD*) BIO_meth_new(int type, const char *name)
+{
+ BIO_METHOD *meth = git__calloc(1, sizeof(BIO_METHOD));
+ if (!meth) {
+ return NULL;
+ }
+
+ meth->type = type;
+ meth->name = name;
+
+ return meth;
+}
+
+GIT_INLINE(void) BIO_meth_free(BIO_METHOD *biom)
+{
+ git__free(biom);
+}
+
+GIT_INLINE(int) BIO_meth_set_write(BIO_METHOD *biom, int (*write) (BIO *, const char *, int))
+{
+ biom->bwrite = write;
+ return 1;
+}
+
+GIT_INLINE(int) BIO_meth_set_read(BIO_METHOD *biom, int (*read) (BIO *, char *, int))
+{
+ biom->bread = read;
+ return 1;
+}
+
+GIT_INLINE(int) BIO_meth_set_puts(BIO_METHOD *biom, int (*puts) (BIO *, const char *))
+{
+ biom->bputs = puts;
+ return 1;
+}
+
+GIT_INLINE(int) BIO_meth_set_gets(BIO_METHOD *biom, int (*gets) (BIO *, char *, int))
+
+{
+ biom->bgets = gets;
+ return 1;
+}
+
+GIT_INLINE(int) BIO_meth_set_ctrl(BIO_METHOD *biom, long (*ctrl) (BIO *, int, long, void *))
+{
+ biom->ctrl = ctrl;
+ return 1;
+}
+
+GIT_INLINE(int) BIO_meth_set_create(BIO_METHOD *biom, int (*create) (BIO *))
+{
+ biom->create = create;
+ return 1;
+}
+
+GIT_INLINE(int) BIO_meth_set_destroy(BIO_METHOD *biom, int (*destroy) (BIO *))
+{
+ biom->destroy = destroy;
+ return 1;
+}
+
+GIT_INLINE(int) BIO_get_new_index(void)
+{
+ /* This exists as of 1.1 so before we'd just have 0 */
+ return 0;
+}
+
+GIT_INLINE(void) BIO_set_init(BIO *b, int init)
+{
+ b->init = init;
+}
+
+GIT_INLINE(void) BIO_set_data(BIO *a, void *ptr)
+{
+ a->ptr = ptr;
+}
+
+GIT_INLINE(void*) BIO_get_data(BIO *a)
+{
+ return a->ptr;
+}
+
+# endif
+
#endif
--
2.10.1

View File

@ -0,0 +1,55 @@
From c16736c6b5c13350df4c41f76b1815e6bbe6ee0a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= <cmn@dwim.me>
Date: Wed, 2 Nov 2016 12:35:46 +0100
Subject: [PATCH 3/4] openssl: use ASN1_STRING_get0_data when compiling against
1.1
For older versions we can fall back on the deprecated ASN1_STRING_data.
(cherry picked from commit 2f3adf9513b1579ae17489d45d032b962bba885a)
---
src/openssl_stream.c | 4 ++--
src/openssl_stream.h | 5 +++++
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/openssl_stream.c b/src/openssl_stream.c
index 328a131..64187a8 100644
--- a/src/openssl_stream.c
+++ b/src/openssl_stream.c
@@ -357,7 +357,7 @@ static int verify_server_cert(SSL *ssl, const char *host)
num = sk_GENERAL_NAME_num(alts);
for (i = 0; i < num && matched != 1; i++) {
const GENERAL_NAME *gn = sk_GENERAL_NAME_value(alts, i);
- const char *name = (char *) ASN1_STRING_data(gn->d.ia5);
+ const char *name = (char *) ASN1_STRING_get0_data(gn->d.ia5);
size_t namelen = (size_t) ASN1_STRING_length(gn->d.ia5);
/* Skip any names of a type we're not looking for */
@@ -412,7 +412,7 @@ static int verify_server_cert(SSL *ssl, const char *host)
if (size > 0) {
peer_cn = OPENSSL_malloc(size + 1);
GITERR_CHECK_ALLOC(peer_cn);
- memcpy(peer_cn, ASN1_STRING_data(str), size);
+ memcpy(peer_cn, ASN1_STRING_get0_data(str), size);
peer_cn[size] = '\0';
} else {
goto cert_fail_name;
diff --git a/src/openssl_stream.h b/src/openssl_stream.h
index 509e404..e8ce5d9 100644
--- a/src/openssl_stream.h
+++ b/src/openssl_stream.h
@@ -108,6 +108,11 @@ GIT_INLINE(void*) BIO_get_data(BIO *a)
return a->ptr;
}
+GIT_INLINE(const unsigned char *) ASN1_STRING_get0_data(const ASN1_STRING *x)
+{
+ return ASN1_STRING_data((ASN1_STRING *)x);
+}
+
# endif
#endif
--
2.10.1

View File

@ -0,0 +1,58 @@
From 57f32d20013fe0fc975e8fcc11b0a91c56df5d04 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= <cmn@dwim.me>
Date: Wed, 2 Nov 2016 13:11:31 +0100
Subject: [PATCH 4/4] openssl: include OpenSSL headers only when we're buliding
against it
We need to include the initialisation and construction functions in all
backend, so we include this header when building against SecureTransport
and WinHTTP as well.
(cherry picked from commit 3b832a085b8c5dc304dd803979894b9bae05df6d)
---
src/openssl_stream.h | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/src/openssl_stream.h b/src/openssl_stream.h
index e8ce5d9..b769437 100644
--- a/src/openssl_stream.h
+++ b/src/openssl_stream.h
@@ -7,11 +7,6 @@
#ifndef INCLUDE_openssl_stream_h__
#define INCLUDE_openssl_stream_h__
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#include <openssl/x509v3.h>
-#include <openssl/bio.h>
-
#include "git2/sys/stream.h"
extern int git_openssl_stream_global_init(void);
@@ -24,6 +19,14 @@ extern int git_openssl_stream_new(git_stream **out, const char *host, const char
* we can program against the interface instead of littering the implementation
* with ifdefs.
*/
+#ifdef GIT_OPENSSL
+# include <openssl/ssl.h>
+# include <openssl/err.h>
+# include <openssl/x509v3.h>
+# include <openssl/bio.h>
+
+
+
# if OPENSSL_VERSION_NUMBER < 0x10100000L
GIT_INLINE(BIO_METHOD*) BIO_meth_new(int type, const char *name)
@@ -113,6 +116,7 @@ GIT_INLINE(const unsigned char *) ASN1_STRING_get0_data(const ASN1_STRING *x)
return ASN1_STRING_data((ASN1_STRING *)x);
}
-# endif
+# endif // OpenSSL < 1.1
+#endif // GIT_OPENSSL
#endif
--
2.10.1

View File

@ -1,14 +1,15 @@
Name: libgit2
Version: 0.24.2
Release: 2%{?dist}
Version: 0.24.3
Release: 1%{?dist}
Summary: C implementation of the Git core methods as a library with a solid API
License: GPLv2 with exceptions
URL: http://libgit2.github.com/
Source0: https://github.com/libgit2/libgit2/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
# https://bugzilla.redhat.com/show_bug.cgi?id=1383212
# CVE-2016-8568 CVE-2016-8569
# https://github.com/libgit2/libgit2/commit/a719ef5e6d4a1a8ec53469c7914032ed67922772
Patch0001: 0001-commit-always-initialize-commit-message.patch
# OpenSSL 1.1.0 support, cherry-picked from master
Patch0001: 0001-add-support-for-OpenSSL-1.1.0-for-BIO-filter.patch
Patch0002: 0002-openssl-recreate-the-OpenSSL-1.1-BIO-interface-for-o.patch
Patch0003: 0003-openssl-use-ASN1_STRING_get0_data-when-compiling-aga.patch
Patch0004: 0004-openssl-include-OpenSSL-headers-only-when-we-re-buli.patch
BuildRequires: cmake
BuildRequires: http-parser-devel
@ -81,6 +82,10 @@ popd
%{_includedir}/git2/
%changelog
* Thu Nov 03 2016 Igor Gnatenko <i.gnatenko.brain@gmail.com> - 0.24.3-1
- Update to 0.24.3 (RHBZ #1391480)
- Add support for OpenSSL 1.1.0 (RHBZ #1383753)
* Mon Oct 10 2016 Igor Gnatenko <i.gnatenko.brain@gmail.com> - 0.24.2-2
- Backport patch for CVE-2016-8568, CVE-2016-8569

View File

@ -1 +1 @@
735661b5b73e3c120d13e2bae21e49b3 libgit2-0.24.2.tar.gz
df626711b16bd5e7021123cbf1655399 libgit2-0.24.3.tar.gz