[squid-dev] [PATCH] LockingPointer API update
Amos Jeffries
squid3 at treenet.co.nz
Wed Jun 22 11:29:27 UTC 2016
On 22/06/2016 10:42 p.m., Christos Tsantilas wrote:
> On 06/22/2016 07:32 AM, Amos Jeffries wrote:
>> On 22/06/2016 1:02 p.m., Alex Rousskov wrote:
>>> On 06/21/2016 04:00 AM, Amos Jeffries wrote:
>>
>> The two I saw were:
>>
>> 1) PeekingPeerConnector::handleServerCertificate() doing
>> serverBump->serverCert.reset(serverCert.release())
>>
>> On much closer inspection it appears not a bug. But is doing move
>> semantics without a move operator relying heavily on specific
>> implementation detail of TidyPointer API exposure.
>
> This is not bug. The call
> newServerCertPointer.reset(oldServerCertPointer.release())
> just moves the X509 object with the current locks to the
> newServerCertPointer.
Yeah. Thats move semantics.
LockingPointer has a move assignment operator for doing that in clearer
way now in trunk - and 3.5 when built with C++11 compiler.
>>
>> 2) PeekingPeerConnector::serverCertificateVerified() doing two different
>> reset() vs resetAndLock() depending on the data source.
>>
>> The OpenSSL docs do say the call increments a reference count itself.
>> But I still think this is leaking. Since we explicitly unlock on
>> destruct as well as calling the necessary free API method in OpenSSL.
>
> I do not think that this is leaking here.
> The code is the following:
>
> Security::CertPointer serverCert;
> if (...) {
> // We need to lock here because the destructor of
> // serverCert will call X509_free and will
> // decrease the lock of the
> serverCert.resetAndLock(serverBump->serverCert.get());
> } else {
> // We do not need to lock here, the SSL_get_peer_certificate
> // already increases the clock counter and we have to
> // free with X509_free.
> serverCert.reset(SSL_get_peer_certificate(ssl));
> }
> // serverCert::~serverCert() called on function
> // leave, calling X509_free.
>
>
> For LockingCounter we need both a reset and a resetAndLock method to
> correctly using it with openSSL library. There are cases where an
> openSSL call increases the locking counter for the object it returns and
> other cases where it doesn't.
In the patch I'm working on now its looking very much like we can drop
the reset() method for these instances and just use a temporary local
object. Like so:
The above code becomes:
Security::CertPointer serverCert;
if (...) {
// We need to lock here because the destructor of
// serverCert will call X509_free and decrease the lock
// operator =() copy-assign does the lock stuff
serverCert = serverBump->serverCert;
} else {
// We do not need to lock here, the SSL_get_peer_certificate
// already increases the clock counter and we have to
// free with X509_free.
// CertPointer() constructor builds object without locking it
// assuming SSL_get_peer_certificate() did the lock for it.
// operator =() move-assign or copy-assign does the lock stuff
serverCert = Security::CertPointer(SSL_get_peer_certificate(ssl)));
}
// serverCert::~serverCert() called on function
// leave, calling X509_free.
So long as we only construct LockingPointer from freshly minted OpenSSL
raw-pointers that have an OpenSSL set lock. Then we do not need the
non-locking reset() operation.
We do need the locking reset*() method for the cases where the raw
pointer is not locked by the library.
>
> The LockingPointer is not perfect. But it is a class used and adjusted
> to be used for openSSL related objects. OpenSSL is a C library and it is
> not easy to convert openSSL objects to equivalent C++ objects.
>
> I must also note that the locking pointer is not used only for X509
> objects but for other objects too.
>
> In a point of view the LockingPointer should never moved under the
> Security and should be used only for openSSL related code.
Yes and no.
It got moved to src/security/ so objects of its type could be used by
the src/security/ code in builds where the src/ssl/ path is not compiled.
If this attempt to get TidyPointer able to be used as a seamless
replacement in the generic libsecurity API then LockingPointer can
probably go back there. But not until that is true.
But, the GnuTLS builds will need an equivalent Pointer with a different
lock action to handle session pointers.
Amos
More information about the squid-dev
mailing list