Skip site navigation (1)Skip section navigation (2)
Date:      22 May 2013 01:31:28 -0000
From:      Michael Gmelin <freebsd@grem.de>
To:        FreeBSD-gnats-submit@freebsd.org
Cc:        delphij@FreeBSD.org
Subject:   ports/178827: [PATCH] security/cryptopp: Bug in libc++ causes key generation to get stuck in endless loop
Message-ID:  <20130522013128.49298.qmail@mail.grem.de>
Resent-Message-ID: <201305220140.r4M1e0sx063492@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         178827
>Category:       ports
>Synopsis:       [PATCH] security/cryptopp: Bug in libc++ causes key generation to get stuck in endless loop
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-ports-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed May 22 01:40:00 UTC 2013
>Closed-Date:
>Last-Modified:
>Originator:     Michael Gmelin
>Release:        FreeBSD 9.1-RELEASE amd64
>Organization:
Grem Equity GmbH
>Environment:
System: FreeBSD bsd64.grem.de 9.1-RELEASE-p2 FreeBSD 9.1-RELEASE-p2 #4 r249052: Wed Apr  3 18:26:19 UTC
>Description:
Due to a bug in the version of libc++ shipping with FreeBSD 9.1-RELEASE,
RSA key generation - and most likely other operations depending on
class PrimeSieve - gets stuck in an endless loop when compiled using
libc++ (CXXFLAGS+= -std=c++11 -stdlib=libc++).

The problem has been reported last year:

http://sourceforge.net/apps/trac/cryptopp/ticket/17
http://old.nabble.com/keygeneration-on-ios-using-clang(libc%2B%2B)-never-terminates-td34614981.html

It is caused by libc++'s implementation of std::find returning invalid
results when operating on std::vector<bool> (read: bitsets). The
problem has already been fixed in libc++:

http://llvm.org/viewvc/llvm-project?view=revision&revision=156546

which is also part of release 3.2 of the library. Unfortunately this is
not available in any release version of FreeBSD yet.

The attached patch works around this problem by conditionally replacing
the call to std::find with a hand written loop in case clang and an
affected version libc++ are detected. For all other compilers as well
as versions of libc++ the code is not altered at all. The ABI stays
stable, so there won't be any unpleasant surprises when upgrading the
port at a later point in time using an updated version of libc++, e.g.
after upgrading to 9.2-RELEASE.

The maintainer might want to communicate this issue upstream as well,
it's not limited to FreeBSD.

Added file(s):
- files/patch-nbtheory.cpp

Port maintainer (delphij@FreeBSD.org) is cc'd.

Generated with FreeBSD Port Tools 0.99_6 (mode: change, diff: suffix)
>How-To-Repeat:

Requires a clang and libc++ enabled FreeBSD 9.1-RELEASE installation.

cd /usr/ports/security/cryptopp
CXX=clang++ CXXFLAGS="-std=c++11 -stdlib=libc++" \
make WITHOUT=STATIC install clean

cat >/tmp/test.cpp <<EOF
#include <cryptopp/rsa.h>
#include <cryptopp/osrng.h>
#include <cryptopp/base64.h>
#include <cryptopp/files.h>
using namespace CryptoPP;
int main()
{
  AutoSeededRandomPool rng;
  InvertibleRSAFunction privkey;
  privkey.Initialize(rng, 2048, 4);
}
EOF

clang++ -pthread -std=c++11 -stdlib=libc++ -I/usr/local/include \
-L/usr/local/lib -lcryptopp -o /tmp/test /tmp/test.cpp

/tmp/test

This is supposed to return immediately, but is hanging indefinitely
instead.

>Fix:
Apply the patch attached to this PR and update the package:

cd /usr/ports/security/cryptopp
patch -p1 </path/to/cryptopp-5.6.1_3.patch
portmaster cryptopp

--- cryptopp-5.6.1_3.patch begins here ---
diff -ruN --exclude=CVS ../cryptopp.orig/Makefile ./Makefile
--- ../cryptopp.orig/Makefile	2013-05-22 02:18:44.000000000 +0200
+++ ./Makefile	2013-05-22 02:19:32.000000000 +0200
@@ -3,7 +3,7 @@
 
 PORTNAME=		cryptopp
 PORTVERSION=		5.6.1
-PORTREVISION=		2
+PORTREVISION=		3
 CATEGORIES=		security
 MASTER_SITES=		SF \
 			http://www.cryptopp.com/
diff -ruN --exclude=CVS ../cryptopp.orig/files/patch-nbtheory.cpp ./files/patch-nbtheory.cpp
--- ../cryptopp.orig/files/patch-nbtheory.cpp	1970-01-01 01:00:00.000000000 +0100
+++ ./files/patch-nbtheory.cpp	2013-05-22 02:18:29.000000000 +0200
@@ -0,0 +1,21 @@
+--- nbtheory.cpp.orig	2013-05-22 00:16:26.761193859 +0000
++++ nbtheory.cpp	2013-05-22 00:15:29.401256454 +0000
+@@ -307,7 +307,18 @@
+ 
+ bool PrimeSieve::NextCandidate(Integer &c)
+ {
++#if defined(__clang__) && defined(_LIBCPP_VERSION) &&  _LIBCPP_VERSION < 1101
++	// Workaround for a bug in libc++ in std::find on std::vector<bool>
++	std::vector<bool>::iterator pos = m_sieve.begin()+m_next;
++	for (std::vector<bool>::iterator end = m_sieve.end(); pos != end; ++pos)
++	{
++		if (*pos == false)
++			break;
++	}
++	bool safe = SafeConvert(pos - m_sieve.begin(), m_next);
++#else
+ 	bool safe = SafeConvert(std::find(m_sieve.begin()+m_next, m_sieve.end(), false) - m_sieve.begin(), m_next);
++#endif
+ 	assert(safe);
+ 	if (m_next == m_sieve.size())
+ 	{
--- cryptopp-5.6.1_3.patch ends here ---

>Release-Note:
>Audit-Trail:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20130522013128.49298.qmail>