X-Original-To: alpine-aports@lists.alpinelinux.org Received: from mail-lf0-f65.google.com (mail-lf0-f65.google.com [209.85.215.65]) by lists.alpinelinux.org (Postfix) with ESMTP id 27F675C2D14 for ; Mon, 12 Dec 2016 14:04:03 +0000 (GMT) Received: by mail-lf0-f65.google.com with SMTP id p100so3595596lfg.2 for ; Mon, 12 Dec 2016 06:04:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=hprdVypBktksq4mXnOpF6Kv/i6u1YNgYQ3bobS42ZuM=; b=pR1ZpGZD0U/LO4iN2T8uMIp/l/eQ5rsKOtEZ4s2bemf03xBPqCOH0G335u0bJDzhWH 4btoBnEebJ8caLMXIugWKiZpayxnHpcColwba+YPa0xC5dxEhzGGUoR4t+5FvNGHhhV7 AXzQ8hADkEAjixYYfYKYBVsIqpLo9Ffni4sWpVo9Wq4iJ6XWBXyrWfMkji0wXvUE0ROX YpT2xhhDXYulYnzmGhGE48sPB5/ltY/24gW4hQTLJza/vyYjRmTtQAbH+GYyqCTMpGoM olKc8FS8VkXPnhIka+XuG8sGbqfBvn7+rD0UcKEXE3rbuqq70RvULiqk9H3iy42iceb0 L6kA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=hprdVypBktksq4mXnOpF6Kv/i6u1YNgYQ3bobS42ZuM=; b=nC4LPZtUWPTJSY+uaV8d+rhJHi6dX7CVin2P7Xx8uesMdZsrDSTDaIWzvLESTM+Lrf RKNKg7Wgfgksjf2EidKdcYaejSIOe50LIfYr0zD7d0UsK43bPJVTK3G+rmISnzUbh9ej kpEz7JfcDpP/J/O7uirwouj4XtC0S0NdhfHGFtgIfhvwR8U82uZpeHB4yHru0Px47fJ4 WQVP3slNmrvLzBDIN/HRY+TdqIdibq5jit0AdCqZ/q/MV7u4KGfBkQlKB17ZkGTujWNQ D/pKCc/DoussATIV7OuTlgj2dJlNbEG1IcJOhKRcOeVO8JqpzvGejwhMyzSV9V1bCiq/ vleA== X-Gm-Message-State: AKaTC03iRkZYz22Tri5pRmFc//ah7WvBViShB5F7A7dgIPXu98qVovnVZggd/FQ0DC5LGw== X-Received: by 10.25.74.85 with SMTP id x82mr26925505lfa.154.1481551442464; Mon, 12 Dec 2016 06:04:02 -0800 (PST) Received: from v3-1.util.wtbts.net ([83.145.235.199]) by smtp.gmail.com with ESMTPSA id v72sm9174294lfa.11.2016.12.12.06.04.01 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 12 Dec 2016 06:04:01 -0800 (PST) From: Sergey Lukin To: alpine-aports@lists.alpinelinux.org Cc: Sergey Lukin Subject: [alpine-aports] [PATCH v3.1] main/zeromq: security upgrade - fixes #4295 Date: Mon, 12 Dec 2016 14:03:55 +0000 Message-Id: <1481551435-9026-1-git-send-email-sergej.lukin@gmail.com> X-Mailer: git-send-email 2.2.1 X-Mailinglist: alpine-aports Precedence: list List-Id: Alpine Development List-Unsubscribe: List-Post: List-Help: List-Subscribe: CVE-2014-9721 --- main/zeromq/APKBUILD | 24 ++- main/zeromq/CVE-2014-9721.patch | 416 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 431 insertions(+), 9 deletions(-) create mode 100644 main/zeromq/CVE-2014-9721.patch diff --git a/main/zeromq/APKBUILD b/main/zeromq/APKBUILD index 6373f45..f43e99a 100644 --- a/main/zeromq/APKBUILD +++ b/main/zeromq/APKBUILD @@ -1,8 +1,9 @@ # Contributor: Natanael Copa +# Contributor: Sergey Lukin # Maintainer: Natanael Copa pkgname=zeromq pkgver=4.0.5 -pkgrel=0 +pkgrel=1 pkgdesc="The ZeroMQ messaging library and tools" url="http://www.zeromq.org/" arch="all" @@ -11,11 +12,13 @@ depends= makedepends="util-linux-dev openpgm-dev perl python autoconf automake" install= subpackages="$pkgname-dev $pkgname-doc libzmq" -source="http://download.zeromq.org/zeromq-$pkgver.tar.gz" +source="http://download.zeromq.org/zeromq-$pkgver.tar.gz + CVE-2014-9721.patch + " -_builddir="$srcdir"/$pkgname-$pkgver +builddir="$srcdir"/$pkgname-$pkgver prepare() { - cd "$_builddir" + cd "$builddir" for i in $source; do case $i in *.patch) msg $i; patch -p1 -i "$srcdir"/$i || return 1;; @@ -25,7 +28,7 @@ prepare() { } build() { - cd "$_builddir" + cd "$builddir" ./configure \ --build=$CBUILD \ --host=$CHOST \ @@ -39,7 +42,7 @@ build() { } package() { - cd "$_builddir" + cd "$builddir" make DESTDIR="$pkgdir" install rm -f "$pkgdir"/usr/lib/*.la } @@ -50,6 +53,9 @@ libzmq() { mv "$pkgdir"/usr/lib/libzmq.so.* "$subpkgdir"/usr/lib/ } -md5sums="73c39f5eb01b9d7eaf74a5d899f1d03d zeromq-4.0.5.tar.gz" -sha256sums="3bc93c5f67370341428364ce007d448f4bb58a0eaabd0a60697d8086bc43342b zeromq-4.0.5.tar.gz" -sha512sums="0d928ed688ed940d460fa8f8d574a9819dccc4e030d735a8c7db71b59287ee50fa741a08249e356c78356b03c2174f2f2699f05aa7dc3d380ed47d8d7bab5408 zeromq-4.0.5.tar.gz" +md5sums="73c39f5eb01b9d7eaf74a5d899f1d03d zeromq-4.0.5.tar.gz +320491e2ef2ab0f3e980a30e25fc2563 CVE-2014-9721.patch" +sha256sums="3bc93c5f67370341428364ce007d448f4bb58a0eaabd0a60697d8086bc43342b zeromq-4.0.5.tar.gz +5cf92b204709e97043ddf9b5ae7ed36bda835c5f9831de02209451589f054427 CVE-2014-9721.patch" +sha512sums="0d928ed688ed940d460fa8f8d574a9819dccc4e030d735a8c7db71b59287ee50fa741a08249e356c78356b03c2174f2f2699f05aa7dc3d380ed47d8d7bab5408 zeromq-4.0.5.tar.gz +eefc48fa851059092c09e4e22125e9a25f6da1506624dd4b1417c974f630e798bcd54257214c9fc4de6d2f92fb4a8b78607b6400e8d09c64284b566e3bfc0d98 CVE-2014-9721.patch" diff --git a/main/zeromq/CVE-2014-9721.patch b/main/zeromq/CVE-2014-9721.patch new file mode 100644 index 0000000..788ddc7 --- /dev/null +++ b/main/zeromq/CVE-2014-9721.patch @@ -0,0 +1,416 @@ +https://bugs.alpinelinux.org/issues/4295 +https://github.com/zeromq/zeromq4-x/commit/b6e3e0f601e2c1ec1f3aac880ed6a3fe63043e51 +http://www.openwall.com/lists/oss-security/2015/05/07/8 + + +--- a/src/session_base.cpp +--- b/src/session_base.cpp +@@ -323,6 +323,14 @@ int zmq::session_base_t::zap_connect () + return 0; + } + ++bool zmq::session_base_t::zap_enabled () ++{ ++ return ( ++ options.mechanism != ZMQ_NULL || ++ (options.mechanism == ZMQ_NULL && options.zap_domain.length() > 0) ++ ); ++} ++ + void zmq::session_base_t::process_attach (i_engine *engine_) + { + zmq_assert (engine_ != NULL); + + +--- a/src/session_base.hpp +--- b/src/session_base.hpp +@@ -68,7 +68,8 @@ namespace zmq + int push_msg (msg_t *msg_); + + int zap_connect (); +- ++ bool zap_enabled (); ++ + // Fetches a message. Returns 0 if successful; -1 otherwise. + // The caller is responsible for freeing the message when no + // longer used. + + +--- a/src/stream_engine.cpp +--- b/src/stream_engine.cpp +@@ -464,6 +464,11 @@ bool zmq::stream_engine_t::handshake () + // Is the peer using ZMTP/1.0 with no revision number? + // If so, we send and receive rest of identity message + if (greeting_recv [0] != 0xff || !(greeting_recv [9] & 0x01)) { ++ if (session->zap_enabled ()) { ++ // Reject ZMTP 1.0 connections if ZAP is enabled ++ error (); ++ return false; ++ } + encoder = new (std::nothrow) v1_encoder_t (out_batch_size); + alloc_assert (encoder); + +@@ -505,6 +510,11 @@ bool zmq::stream_engine_t::handshake () + } + else + if (greeting_recv [revision_pos] == ZMTP_1_0) { ++ if (session->zap_enabled ()) { ++ // Reject ZMTP 1.0 connections if ZAP is enabled ++ error (); ++ return false; ++ } + encoder = new (std::nothrow) v1_encoder_t ( + out_batch_size); + alloc_assert (encoder); +@@ -515,6 +525,11 @@ bool zmq::stream_engine_t::handshake () + } + else + if (greeting_recv [revision_pos] == ZMTP_2_0) { ++ if (session->zap_enabled ()) { ++ // Reject ZMTP 1.0 connections if ZAP is enabled ++ error (); ++ return false; ++ } + encoder = new (std::nothrow) v2_encoder_t (out_batch_size); + alloc_assert (encoder); + + + +--- a/tests/test_security_curve.cpp +--- b/tests/test_security_curve.cpp +@@ -18,12 +18,23 @@ + */ + + #include "testutil.hpp" ++#if defined (ZMQ_HAVE_WINDOWS) ++# include ++# include ++# include ++# define close closesocket ++#else ++# include ++# include ++# include ++# include ++#endif + + // We'll generate random test keys at startup +-static char client_public [40]; +-static char client_secret [40]; +-static char server_public [40]; +-static char server_secret [40]; ++static char client_public [41]; ++static char client_secret [41]; ++static char server_public [41]; ++static char server_secret [41]; + + // -------------------------------------------------------------------------- + // This methods receives and validates ZAP requestes (allowing or denying + @@ -46,7 +57,7 @@ static void zap_handler (void *handler) + int size = zmq_recv (handler, client_key, 32, 0); + assert (size == 32); + +- char client_key_text [40]; ++ char client_key_text [41]; + zmq_z85_encode (client_key_text, client_key, 32); + + assert (streq (version, "1.0")); +@@ -181,8 +192,8 @@ int main (void) + + // Check CURVE security with bogus client credentials + // This must be caught by the ZAP handler +- char bogus_public [40]; +- char bogus_secret [40]; ++ char bogus_public [41]; ++ char bogus_secret [41]; + zmq_curve_keypair (bogus_public, bogus_secret); + + client = zmq_socket (ctx, ZMQ_DEALER); +@@ -217,7 +228,46 @@ int main (void) + assert (rc == 0); + expect_bounce_fail (server, client); + close_zero_linger (client); +- ++ ++ // Unauthenticated messages from a vanilla socket shouldn't be received ++ struct sockaddr_in ip4addr; ++ int s; ++ ++ ip4addr.sin_family = AF_INET; ++ ip4addr.sin_port = htons (9998); ++ inet_pton (AF_INET, "127.0.0.1", &ip4addr.sin_addr); ++ ++ s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); ++ rc = connect (s, (struct sockaddr*) &ip4addr, sizeof (ip4addr)); ++ assert (rc > -1); ++ // send anonymous ZMTP/1.0 greeting ++ send (s, "\x01\x00", 2, 0); ++ // send sneaky message that shouldn't be received ++ send (s, "\x08\x00sneaky\0", 9, 0); ++ int timeout = 150; ++ zmq_setsockopt (server, ZMQ_RCVTIMEO, &timeout, sizeof (timeout)); ++ char *buf = s_recv (server); ++ if (buf != NULL) { ++ printf ("Received unauthenticated message: %s\n", buf); ++ assert (buf == NULL); ++ } ++ close (s); ++ ++ // Check return codes for invalid buffer sizes ++ client = zmq_socket (ctx, ZMQ_DEALER); ++ assert (client); ++ errno = 0; ++ rc = zmq_setsockopt (client, ZMQ_CURVE_SERVERKEY, server_public, 123); ++ assert (rc == -1 && errno == EINVAL); ++ errno = 0; ++ rc = zmq_setsockopt (client, ZMQ_CURVE_PUBLICKEY, client_public, 123); ++ assert (rc == -1 && errno == EINVAL); ++ errno = 0; ++ rc = zmq_setsockopt (client, ZMQ_CURVE_SECRETKEY, client_secret, 123); ++ assert (rc == -1 && errno == EINVAL); ++ rc = zmq_close (client); ++ assert (rc == 0); ++ + // Shutdown + rc = zmq_close (server); + assert (rc == 0); + + +--- a/tests/test_security_null.cpp +--- b/tests/test_security_null.cpp +@@ -1,5 +1,5 @@ + /* +- Copyright (c) 2007-2013 Contributors as noted in the AUTHORS file ++ Copyright (c) 2007-2014 Contributors as noted in the AUTHORS file + + This file is part of 0MQ. + +@@ -18,6 +18,17 @@ + */ + + #include "testutil.hpp" ++#if defined (ZMQ_HAVE_WINDOWS) ++# include ++# include ++# include ++# define close closesocket ++#else ++# include ++# include ++# include ++# include ++#endif + + static void + zap_handler (void *handler) +@@ -27,6 +38,7 @@ zap_handler (void *handler) + char *version = s_recv (handler); + if (!version) + break; // Terminating ++ + char *sequence = s_recv (handler); + char *domain = s_recv (handler); + char *address = s_recv (handler); +@@ -57,7 +69,7 @@ zap_handler (void *handler) + free (identity); + free (mechanism); + } +- zmq_close (handler); ++ close_zero_linger (handler); + } + + int main (void) +@@ -76,72 +88,89 @@ int main (void) + void *zap_thread = zmq_threadstart (&zap_handler, handler); + + // We bounce between a binding server and a connecting client ++ ++ // We first test client/server with no ZAP domain ++ // Libzmq does not call our ZAP handler, the connect must succeed + void *server = zmq_socket (ctx, ZMQ_DEALER); + assert (server); + void *client = zmq_socket (ctx, ZMQ_DEALER); + assert (client); +- +- // We first test client/server with no ZAP domain +- // Libzmq does not call our ZAP handler, the connect must succeed + rc = zmq_bind (server, "tcp://127.0.0.1:9000"); + assert (rc == 0); +- rc = zmq_connect (client, "tcp://localhost:9000"); ++ rc = zmq_connect (client, "tcp://127.0.0.1:9000"); + assert (rc == 0); + bounce (server, client); +- zmq_unbind (server, "tcp://127.0.0.1:9000"); +- zmq_disconnect (client, "tcp://localhost:9000"); +- ++ close_zero_linger (client); ++ close_zero_linger (server); ++ + // Now define a ZAP domain for the server; this enables + // authentication. We're using the wrong domain so this test + // must fail. +- // ************************************************************** +- // PH: the following causes libzmq to get confused, so that the +- // next step fails. To reproduce, uncomment this block. Note that +- // even creating a new client/server socket pair, the behaviour +- // does not change. +- // ************************************************************** +- // Destroying the old sockets and creating new ones isn't needed, +- // but it shows that the problem isn't related to specific sockets. +- //close_zero_linger (client); +- //close_zero_linger (server); +- //server = zmq_socket (ctx, ZMQ_DEALER); +- //assert (server); +- //client = zmq_socket (ctx, ZMQ_DEALER); +- //assert (client); +- //// The above code should not be required +- //rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "WRONG", 5); +- //assert (rc == 0); +- //rc = zmq_bind (server, "tcp://127.0.0.1:9001"); +- //assert (rc == 0); +- //rc = zmq_connect (client, "tcp://localhost:9001"); +- //assert (rc == 0); +- //expect_bounce_fail (server, client); +- //zmq_unbind (server, "tcp://127.0.0.1:9001"); +- //zmq_disconnect (client, "tcp://localhost:9001"); +- ++ server = zmq_socket (ctx, ZMQ_DEALER); ++ assert (server); ++ client = zmq_socket (ctx, ZMQ_DEALER); ++ assert (client); ++ rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "WRONG", 5); ++ assert (rc == 0); ++ rc = zmq_bind (server, "tcp://127.0.0.1:9001"); ++ assert (rc == 0); ++ rc = zmq_connect (client, "tcp://127.0.0.1:9001"); ++ assert (rc == 0); ++ expect_bounce_fail (server, client); ++ close_zero_linger (client); ++ close_zero_linger (server); ++ + // Now use the right domain, the test must pass ++ server = zmq_socket (ctx, ZMQ_DEALER); ++ assert (server); ++ client = zmq_socket (ctx, ZMQ_DEALER); ++ assert (client); + rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "TEST", 4); + assert (rc == 0); + rc = zmq_bind (server, "tcp://127.0.0.1:9002"); + assert (rc == 0); +- rc = zmq_connect (client, "tcp://localhost:9002"); ++ rc = zmq_connect (client, "tcp://127.0.0.1:9002"); + assert (rc == 0); +- // ************************************************************** +- // PH: it fails here; though the ZAP reply is 200 OK, and +- // null_mechanism.cpp correctly parses that, the connection +- // never succeeds and the test hangs. +- // ************************************************************** + bounce (server, client); +- zmq_unbind (server, "tcp://127.0.0.1:9002"); +- zmq_disconnect (client, "tcp://localhost:9002"); +- +- // Shutdown + close_zero_linger (client); + close_zero_linger (server); +- rc = zmq_ctx_term (ctx); ++ ++ // Unauthenticated messages from a vanilla socket shouldn't be received ++ server = zmq_socket (ctx, ZMQ_DEALER); ++ assert (server); ++ rc = zmq_setsockopt (server, ZMQ_ZAP_DOMAIN, "WRONG", 5); + assert (rc == 0); ++ rc = zmq_bind (server, "tcp://127.0.0.1:9003"); ++ assert (rc == 0); ++ ++ struct sockaddr_in ip4addr; ++ int s; ++ ++ ip4addr.sin_family = AF_INET; ++ ip4addr.sin_port = htons(9003); ++ inet_pton(AF_INET, "127.0.0.1", &ip4addr.sin_addr); + +- // Wait until ZAP handler terminates. ++ s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); ++ rc = connect (s, (struct sockaddr*) &ip4addr, sizeof ip4addr); ++ assert (rc > -1); ++ // send anonymous ZMTP/1.0 greeting ++ send (s, "\x01\x00", 2, 0); ++ // send sneaky message that shouldn't be received ++ send (s, "\x08\x00sneaky\0", 9, 0); ++ int timeout = 150; ++ zmq_setsockopt (server, ZMQ_RCVTIMEO, &timeout, sizeof (timeout)); ++ char *buf = s_recv (server); ++ if (buf != NULL) { ++ printf ("Received unauthenticated message: %s\n", buf); ++ assert (buf == NULL); ++ } ++ close (s); ++ close_zero_linger (server); ++ ++ // Shutdown ++ rc = zmq_ctx_term (ctx); ++ assert (rc == 0); ++ // Wait until ZAP handler terminates + zmq_threadclose (zap_thread); + + return 0; + + +--- a/tests/test_security_plain.cpp +--- b/tests/test_security_plain.cpp +@@ -1,5 +1,5 @@ + /* +- Copyright (c) 2007-2013 Contributors as noted in the AUTHORS file ++ Copyright (c) 2007-2014 Contributors as noted in the AUTHORS file + + This file is part of 0MQ. + +@@ -18,6 +18,17 @@ + */ + + #include "testutil.hpp" ++#if defined (ZMQ_HAVE_WINDOWS) ++# include ++# include ++# include ++# define close closesocket ++#else ++# include ++# include ++# include ++# include ++#endif + + static void + zap_handler (void *ctx) +@@ -137,6 +148,30 @@ int main (void) + expect_bounce_fail (server, client); + close_zero_linger (client); + ++ // Unauthenticated messages from a vanilla socket shouldn't be received ++ struct sockaddr_in ip4addr; ++ int s; ++ ++ ip4addr.sin_family = AF_INET; ++ ip4addr.sin_port = htons (9998); ++ inet_pton (AF_INET, "127.0.0.1", &ip4addr.sin_addr); ++ ++ s = socket (AF_INET, SOCK_STREAM, IPPROTO_TCP); ++ rc = connect (s, (struct sockaddr*) &ip4addr, sizeof (ip4addr)); ++ assert (rc > -1); ++ // send anonymous ZMTP/1.0 greeting ++ send (s, "\x01\x00", 2, 0); ++ // send sneaky message that shouldn't be received ++ send (s, "\x08\x00sneaky\0", 9, 0); ++ int timeout = 150; ++ zmq_setsockopt (server, ZMQ_RCVTIMEO, &timeout, sizeof (timeout)); ++ char *buf = s_recv (server); ++ if (buf != NULL) { ++ printf ("Received unauthenticated message: %s\n", buf); ++ assert (buf == NULL); ++ } ++ close (s); ++ + // Shutdown + rc = zmq_close (server); + assert (rc == 0); -- 2.2.1 --- Unsubscribe: alpine-aports+unsubscribe@lists.alpinelinux.org Help: alpine-aports+help@lists.alpinelinux.org ---