Hello community,
here is the log from the commit of package libgit2 for openSUSE:Factory checked in at 2017-01-19 10:41:25
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libgit2 (Old)
and /work/SRC/openSUSE:Factory/.libgit2.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "libgit2"
Changes:
--------
--- /work/SRC/openSUSE:Factory/libgit2/libgit2.changes 2016-12-04 15:05:46.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.libgit2.new/libgit2.changes 2017-01-19 10:41:26.377483176 +0100
@@ -1,0 +2,13 @@
+Wed Jan 11 09:27:33 UTC 2017 - astieger@suse.com
+
+- libgit2 0.24.6, including the following security fixes:
+ * bsc#1019036: edge cases in the Git Smart Protocol can lead to
+ attempting to parse outside of the buffer
+ CVE-2016-10128,CVE-2016-10129
+ * bsc#1019037: MITM possible due to lack of parameter for
+ certificate parameter
+ CVE-2016-10130,CVE-2017-5338,CVE-2017-5339
+- includes changes from 0.24.5:
+ * add support for OpenSSL 1.1.0 for BIO filter
+
+-------------------------------------------------------------------
Old:
----
libgit2-0.24.3.tar.gz
New:
----
libgit2-0.24.6.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ libgit2.spec ++++++
--- /var/tmp/diff_new_pack.Q4K2MQ/_old 2017-01-19 10:41:27.057387269 +0100
+++ /var/tmp/diff_new_pack.Q4K2MQ/_new 2017-01-19 10:41:27.057387269 +0100
@@ -1,7 +1,7 @@
#
# spec file for package libgit2
#
-# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
# Copyright (c) 2011, Sascha Peilicke
#
# All modifications and additions to the file contributed by third parties
@@ -18,7 +18,7 @@
Name: libgit2
-Version: 0.24.3
+Version: 0.24.6
Release: 0
Summary: C git library
License: GPL-2.0 WITH GCC-exception-2.0
++++++ libgit2-0.24.3.tar.gz -> libgit2-0.24.6.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgit2-0.24.3/include/git2/version.h new/libgit2-0.24.6/include/git2/version.h
--- old/libgit2-0.24.3/include/git2/version.h 2016-11-03 11:53:23.000000000 +0100
+++ new/libgit2-0.24.6/include/git2/version.h 2017-01-09 21:26:28.000000000 +0100
@@ -7,10 +7,10 @@
#ifndef INCLUDE_git_version_h__
#define INCLUDE_git_version_h__
-#define LIBGIT2_VERSION "0.24.3"
+#define LIBGIT2_VERSION "0.24.6"
#define LIBGIT2_VER_MAJOR 0
#define LIBGIT2_VER_MINOR 24
-#define LIBGIT2_VER_REVISION 3
+#define LIBGIT2_VER_REVISION 6
#define LIBGIT2_VER_PATCH 0
#define LIBGIT2_SOVERSION 24
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgit2-0.24.3/src/openssl_stream.c new/libgit2-0.24.6/src/openssl_stream.c
--- old/libgit2-0.24.3/src/openssl_stream.c 2016-11-03 11:53:23.000000000 +0100
+++ new/libgit2-0.24.6/src/openssl_stream.c 2017-01-09 21:26:28.000000000 +0100
@@ -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 @@
#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 @@
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,10 +172,8 @@
static int bio_create(BIO *b)
{
- b->init = 1;
- b->num = 0;
- b->ptr = NULL;
- b->flags = 0;
+ BIO_set_init(b, 1);
+ BIO_set_data(b, NULL);
return 1;
}
@@ -169,23 +183,22 @@
if (!b)
return 0;
- b->init = 0;
- b->num = 0;
- b->ptr = NULL;
- b->flags = 0;
+ BIO_set_data(b, NULL);
return 1;
}
static int bio_read(BIO *b, char *buf, int len)
{
- git_stream *io = (git_stream *) b->ptr;
+ git_stream *io = (git_stream *) BIO_get_data(b);
+
return (int) git_stream_read(io, buf, len);
}
static int bio_write(BIO *b, const char *buf, int len)
{
- git_stream *io = (git_stream *) b->ptr;
+ git_stream *io = (git_stream *) BIO_get_data(b);
+
return (int) git_stream_write(io, buf, len, 0);
}
@@ -214,17 +227,22 @@
return bio_write(b, str, strlen(str));
}
-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
-};
+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)
{
@@ -339,7 +357,7 @@
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 */
@@ -394,7 +412,7 @@
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;
@@ -445,11 +463,12 @@
st->connected = true;
- bio = BIO_new(&git_stream_bio_method);
+ bio = BIO_new(git_stream_bio_method);
GITERR_CHECK_ALLOC(bio);
- bio->ptr = st->io;
+ 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 -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgit2-0.24.3/src/openssl_stream.h new/libgit2-0.24.6/src/openssl_stream.h
--- old/libgit2-0.24.3/src/openssl_stream.h 2016-11-03 11:53:23.000000000 +0100
+++ new/libgit2-0.24.6/src/openssl_stream.h 2017-01-09 21:26:28.000000000 +0100
@@ -13,4 +13,110 @@
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.
+ */
+#ifdef GIT_OPENSSL
+# include
+# include
+# include
+# include
+
+
+
+# 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;
+}
+
+GIT_INLINE(const unsigned char *) ASN1_STRING_get0_data(const ASN1_STRING *x)
+{
+ return ASN1_STRING_data((ASN1_STRING *)x);
+}
+
+# endif // OpenSSL < 1.1
+#endif // GIT_OPENSSL
+
#endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgit2-0.24.3/src/transports/http.c new/libgit2-0.24.6/src/transports/http.c
--- old/libgit2-0.24.3/src/transports/http.c 2016-11-03 11:53:23.000000000 +0100
+++ new/libgit2-0.24.6/src/transports/http.c 2017-01-09 21:26:28.000000000 +0100
@@ -602,13 +602,12 @@
if ((!error || error == GIT_ECERTIFICATE) && t->owner->certificate_check_cb != NULL &&
git_stream_is_encrypted(t->io)) {
git_cert *cert;
- int is_valid;
+ int is_valid = (error == GIT_OK);
if ((error = git_stream_certificate(&cert, t->io)) < 0)
return error;
giterr_clear();
- is_valid = error != GIT_ECERTIFICATE;
error = t->owner->certificate_check_cb(cert, is_valid, t->connection_data.host, t->owner->message_cb_payload);
if (error < 0) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgit2-0.24.3/src/transports/smart_pkt.c new/libgit2-0.24.6/src/transports/smart_pkt.c
--- old/libgit2-0.24.3/src/transports/smart_pkt.c 2016-11-03 11:53:23.000000000 +0100
+++ new/libgit2-0.24.6/src/transports/smart_pkt.c 2017-01-09 21:26:28.000000000 +0100
@@ -427,15 +427,23 @@
if (bufflen > 0 && bufflen < (size_t)len)
return GIT_EBUFS;
+ /*
+ * The length has to be exactly 0 in case of a flush
+ * packet or greater than PKT_LEN_SIZE, as the decoded
+ * length includes its own encoded length of four bytes.
+ */
+ if (len != 0 && len < PKT_LEN_SIZE)
+ return GIT_ERROR;
+
line += PKT_LEN_SIZE;
/*
- * TODO: How do we deal with empty lines? Try again? with the next
- * line?
+ * The Git protocol does not specify empty lines as part
+ * of the protocol. Not knowing what to do with an empty
+ * line, we should return an error upon hitting one.
*/
if (len == PKT_LEN_SIZE) {
- *head = NULL;
- *out = line;
- return 0;
+ giterr_set_str(GITERR_NET, "Invalid empty packet");
+ return GIT_ERROR;
}
if (len == 0) { /* Flush pkt */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgit2-0.24.3/src/transports/smart_protocol.c new/libgit2-0.24.6/src/transports/smart_protocol.c
--- old/libgit2-0.24.3/src/transports/smart_protocol.c 2016-11-03 11:53:23.000000000 +0100
+++ new/libgit2-0.24.6/src/transports/smart_protocol.c 2017-01-09 21:26:28.000000000 +0100
@@ -759,14 +759,6 @@
line_len -= (line_end - line);
line = line_end;
- /* When a valid packet with no content has been
- * read, git_pkt_parse_line does not report an
- * error, but the pkt pointer has not been set.
- * Handle this by skipping over empty packets.
- */
- if (pkt == NULL)
- continue;
-
error = add_push_report_pkt(push, pkt);
git_pkt_free(pkt);
@@ -821,9 +813,6 @@
error = 0;
- if (pkt == NULL)
- continue;
-
switch (pkt->type) {
case GIT_PKT_DATA:
/* This is a sideband packet which contains other packets */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/libgit2-0.24.3/tests/online/badssl.c new/libgit2-0.24.6/tests/online/badssl.c
--- old/libgit2-0.24.3/tests/online/badssl.c 2016-11-03 11:53:23.000000000 +0100
+++ new/libgit2-0.24.6/tests/online/badssl.c 2017-01-09 21:26:28.000000000 +0100
@@ -10,37 +10,71 @@
static bool g_has_ssl = false;
#endif
+static int cert_check_assert_invalid(git_cert *cert, int valid, const char* host, void *payload)
+{
+ GIT_UNUSED(cert); GIT_UNUSED(host); GIT_UNUSED(payload);
+
+ cl_assert_equal_i(0, valid);
+
+ return GIT_ECERTIFICATE;
+}
+
void test_online_badssl__expired(void)
{
+ git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
+ opts.fetch_opts.callbacks.certificate_check = cert_check_assert_invalid;
+
if (!g_has_ssl)
cl_skip();
cl_git_fail_with(GIT_ECERTIFICATE,
git_clone(&g_repo, "https://expired.badssl.com/fake.git", "./fake", NULL));
+
+ cl_git_fail_with(GIT_ECERTIFICATE,
+ git_clone(&g_repo, "https://expired.badssl.com/fake.git", "./fake", &opts));
}
void test_online_badssl__wrong_host(void)
{
+ git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
+ opts.fetch_opts.callbacks.certificate_check = cert_check_assert_invalid;
+
if (!g_has_ssl)
cl_skip();
cl_git_fail_with(GIT_ECERTIFICATE,
git_clone(&g_repo, "https://wrong.host.badssl.com/fake.git", "./fake", NULL));
+ cl_git_fail_with(GIT_ECERTIFICATE,
+ git_clone(&g_repo, "https://wrong.host.badssl.com/fake.git", "./fake", &opts));
}
void test_online_badssl__self_signed(void)
{
+ git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
+ opts.fetch_opts.callbacks.certificate_check = cert_check_assert_invalid;
+
if (!g_has_ssl)
cl_skip();
cl_git_fail_with(GIT_ECERTIFICATE,
git_clone(&g_repo, "https://self-signed.badssl.com/fake.git", "./fake", NULL));
+ cl_git_fail_with(GIT_ECERTIFICATE,
+ git_clone(&g_repo, "https://self-signed.badssl.com/fake.git", "./fake", &opts));
}
void test_online_badssl__old_cipher(void)
{
+ git_clone_options opts = GIT_CLONE_OPTIONS_INIT;
+ opts.fetch_opts.callbacks.certificate_check = cert_check_assert_invalid;
+
+ /* FIXME: we don't actually reject RC4 anywhere, figure out what to tweak */
+ cl_skip();
+
if (!g_has_ssl)
cl_skip();
- cl_git_fail(git_clone(&g_repo, "https://rc4.badssl.com/fake.git", "./fake", NULL));
+ cl_git_fail_with(GIT_ECERTIFICATE,
+ git_clone(&g_repo, "https://rc4.badssl.com/fake.git", "./fake", NULL));
+ cl_git_fail_with(GIT_ECERTIFICATE,
+ git_clone(&g_repo, "https://rc4.badssl.com/fake.git", "./fake", &opts));
}