[jira] [Commented] (PROTON-992) Proton's use of Cyrus SASL is not thread-safe.

2015-09-22 Thread michael goulish (JIRA)

[ 
https://issues.apache.org/jira/browse/PROTON-992?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=14902731#comment-14902731
 ] 

michael goulish commented on PROTON-992:


oops.  this is a duplicate of PROTON-862

> Proton's use of Cyrus SASL is not thread-safe.
> --
>
> Key: PROTON-992
> URL: https://issues.apache.org/jira/browse/PROTON-992
> Project: Qpid Proton
>  Issue Type: Bug
>  Components: proton-c
>Affects Versions: 0.10
>Reporter: michael goulish
>Assignee: michael goulish
>Priority: Critical
>
> Documentation for the Cyrus SASL library says that the library is believed to 
> be thread-safe only if the code that uses it meets several requirements.
> The requirements are:
> * you supply mutex functions (see sasl_set_mutex())
> * you make no libsasl calls until sasl_client/server_init() completes
> * no libsasl calls are made after sasl_done() is begun
> * when using GSSAPI, you use a thread-safe GSS / Kerberos 5 library.
> It says explicitly that that sasl_set* calls are not thread safe, since they 
> set global state.
> The proton library makes calls to sasl_set* functions in :
>   pni_init_client()
>   pni_init_server(), and
>   pni_process_init()
> Since those are internal functions, there is no way for code that uses Proton 
> to lock around those calls.
> I think proton needs a new API call to let applications call 
> sasl_set_mutex().  Or something.
> We probably also need other protections to meet the other requirements 
> specified in the Cyrus documentation (and quoted above).



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)


[jira] [Commented] (PROTON-992) Proton's use of Cyrus SASL is not thread-safe.

2015-09-18 Thread Andrew Stitcher (JIRA)

[ 
https://issues.apache.org/jira/browse/PROTON-992?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=14875683#comment-14875683
 ] 

Andrew Stitcher commented on PROTON-992:


This is a fair point.

It's worth noting that for Cyrus SASL there is no intrinsically global state, 
which makes this whole issue all the more irritating.

With some work we could actually modify the Cyrus SASL codebase to not have the 
global init/fini. Equally we could change the code to use gnu SASL which does 
this stuff correctly (but would require us to handle the authentication 
database side of things).

Incidentally this bug is a restatement of PROTON-862

> Proton's use of Cyrus SASL is not thread-safe.
> --
>
> Key: PROTON-992
> URL: https://issues.apache.org/jira/browse/PROTON-992
> Project: Qpid Proton
>  Issue Type: Bug
>  Components: proton-c
>Affects Versions: 0.10
>Reporter: michael goulish
>Assignee: michael goulish
>Priority: Critical
>
> Documentation for the Cyrus SASL library says that the library is believed to 
> be thread-safe only if the code that uses it meets several requirements.
> The requirements are:
> * you supply mutex functions (see sasl_set_mutex())
> * you make no libsasl calls until sasl_client/server_init() completes
> * no libsasl calls are made after sasl_done() is begun
> * when using GSSAPI, you use a thread-safe GSS / Kerberos 5 library.
> It says explicitly that that sasl_set* calls are not thread safe, since they 
> set global state.
> The proton library makes calls to sasl_set* functions in :
>   pni_init_client()
>   pni_init_server(), and
>   pni_process_init()
> Since those are internal functions, there is no way for code that uses Proton 
> to lock around those calls.
> I think proton needs a new API call to let applications call 
> sasl_set_mutex().  Or something.
> We probably also need other protections to meet the other requirements 
> specified in the Cyrus documentation (and quoted above).



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)


[jira] [Commented] (PROTON-992) Proton's use of Cyrus SASL is not thread-safe.

2015-09-18 Thread Alan Conway (JIRA)

[ 
https://issues.apache.org/jira/browse/PROTON-992?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=14875651#comment-14875651
 ] 

Alan Conway commented on PROTON-992:


You need more than an atomic counter to implement exactly once - if there are 
concurrent calls to init you must not only ensure that only one of them 
executes, but also that the others *wait till it is complete*. You need a lock 
or the equivalent of pthread_once. In terms of safety, ease of use and avoiding 
API change I agree this is the way to go. However my concern is that it makes 
proton harder to port since we need a portable abstraction for "once" and we 
introduce a dependency on some library for locking. The original design goal of 
proton was to be a very portable, pure C99 codebase, thread *agnostic* 
codebase. Pulling in a dependency on pthreads doesn't seem to be in that 
spirit. E.g. I'm not sure how pthreads will play with the Go binding. That's 
why the SASL allows you to specify locks externally - so it doesn't force a 
thread library on you. That's a horrible solution but I'm not sure I like 
forcing pthreads any better.

The "traditional" C solution to this problem is to have sufficient start-up and 
shut-down functions that must be called in main before and after use or yes, 
you will get leaks. It's C. Everybody does it - SASL, OpenSSL, everybody. 
Trying to be more clever than the language we are coding in seems likely to 
lead to trouble - IMO it already has and this JIRA is it.

> Proton's use of Cyrus SASL is not thread-safe.
> --
>
> Key: PROTON-992
> URL: https://issues.apache.org/jira/browse/PROTON-992
> Project: Qpid Proton
>  Issue Type: Bug
>  Components: proton-c
>Affects Versions: 0.10
>Reporter: michael goulish
>Assignee: michael goulish
>Priority: Critical
>
> Documentation for the Cyrus SASL library says that the library is believed to 
> be thread-safe only if the code that uses it meets several requirements.
> The requirements are:
> * you supply mutex functions (see sasl_set_mutex())
> * you make no libsasl calls until sasl_client/server_init() completes
> * no libsasl calls are made after sasl_done() is begun
> * when using GSSAPI, you use a thread-safe GSS / Kerberos 5 library.
> It says explicitly that that sasl_set* calls are not thread safe, since they 
> set global state.
> The proton library makes calls to sasl_set* functions in :
>   pni_init_client()
>   pni_init_server(), and
>   pni_process_init()
> Since those are internal functions, there is no way for code that uses Proton 
> to lock around those calls.
> I think proton needs a new API call to let applications call 
> sasl_set_mutex().  Or something.
> We probably also need other protections to meet the other requirements 
> specified in the Cyrus documentation (and quoted above).



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)


Re: [jira] [Commented] (PROTON-992) Proton's use of Cyrus SASL is not thread-safe.

2015-09-17 Thread Michael Goulish
Thanks!

I wondered about that (briefly) but thought there was nothing to be done.
If you have a sketch, I would be happy to see it!




- Original Message -

[ 
https://issues.apache.org/jira/browse/PROTON-992?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=14802937#comment-14802937
 ] 

Andrew Stitcher commented on PROTON-992:


Upon a few days reflection I've realised that you cannot fix this problem with 
a global init for proton:

This is because there are a couple of parameters of the Cyrus library that 
*must* be set before calling either sasl_server_init() or sasl_client_init(). 
These are the configuration file directory and the server name. Currently if 
you want to customise these you must set them before the first usage of SASL 
and this works as SASL is initialised lazily. However in the proposed API there 
is literally no place to set them:

Since the usage pattern has to be documented that you must initialise the 
library before using it the Cyrus Sasl ibrary will be initialised before you 
are allowed to use the APIs that set the path or name.

So I think the only workable solution is to have an atomic count of use of the 
library and initialise on the going from 0->1 then finalise on going from 1->0. 
Obviously also keeping track of how many uses the library has as well so that 
we can finalise in the correct place. An important point here is to make the 
count atomic so that we can be sure to avoid any re-entrance into the 
initialisation or finalisation code (this is doable using gcc/clang builtins - 
we don't really support Cyrus on Win32 so Visual Studio isn't too important, 
but it has atomic primitives too)

I would note that really we should alos be using atomic counts like this in the 
OpenSSL code too,.

> Proton's use of Cyrus SASL is not thread-safe.
> --
>
> Key: PROTON-992
> URL: https://issues.apache.org/jira/browse/PROTON-992
> Project: Qpid Proton
>  Issue Type: Bug
>  Components: proton-c
>Affects Versions: 0.10
>Reporter: michael goulish
>Assignee: michael goulish
>Priority: Critical
>
> Documentation for the Cyrus SASL library says that the library is believed to 
> be thread-safe only if the code that uses it meets several requirements.
> The requirements are:
> * you supply mutex functions (see sasl_set_mutex())
> * you make no libsasl calls until sasl_client/server_init() completes
> * no libsasl calls are made after sasl_done() is begun
> * when using GSSAPI, you use a thread-safe GSS / Kerberos 5 library.
> It says explicitly that that sasl_set* calls are not thread safe, since they 
> set global state.
> The proton library makes calls to sasl_set* functions in :
>   pni_init_client()
>   pni_init_server(), and
>   pni_process_init()
> Since those are internal functions, there is no way for code that uses Proton 
> to lock around those calls.
> I think proton needs a new API call to let applications call 
> sasl_set_mutex().  Or something.
> We probably also need other protections to meet the other requirements 
> specified in the Cyrus documentation (and quoted above).



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)


[jira] [Commented] (PROTON-992) Proton's use of Cyrus SASL is not thread-safe.

2015-09-17 Thread Andrew Stitcher (JIRA)

[ 
https://issues.apache.org/jira/browse/PROTON-992?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=14802937#comment-14802937
 ] 

Andrew Stitcher commented on PROTON-992:


Upon a few days reflection I've realised that you cannot fix this problem with 
a global init for proton:

This is because there are a couple of parameters of the Cyrus library that 
*must* be set before calling either sasl_server_init() or sasl_client_init(). 
These are the configuration file directory and the server name. Currently if 
you want to customise these you must set them before the first usage of SASL 
and this works as SASL is initialised lazily. However in the proposed API there 
is literally no place to set them:

Since the usage pattern has to be documented that you must initialise the 
library before using it the Cyrus Sasl ibrary will be initialised before you 
are allowed to use the APIs that set the path or name.

So I think the only workable solution is to have an atomic count of use of the 
library and initialise on the going from 0->1 then finalise on going from 1->0. 
Obviously also keeping track of how many uses the library has as well so that 
we can finalise in the correct place. An important point here is to make the 
count atomic so that we can be sure to avoid any re-entrance into the 
initialisation or finalisation code (this is doable using gcc/clang builtins - 
we don't really support Cyrus on Win32 so Visual Studio isn't too important, 
but it has atomic primitives too)

I would note that really we should alos be using atomic counts like this in the 
OpenSSL code too,.

> Proton's use of Cyrus SASL is not thread-safe.
> --
>
> Key: PROTON-992
> URL: https://issues.apache.org/jira/browse/PROTON-992
> Project: Qpid Proton
>  Issue Type: Bug
>  Components: proton-c
>Affects Versions: 0.10
>Reporter: michael goulish
>Assignee: michael goulish
>Priority: Critical
>
> Documentation for the Cyrus SASL library says that the library is believed to 
> be thread-safe only if the code that uses it meets several requirements.
> The requirements are:
> * you supply mutex functions (see sasl_set_mutex())
> * you make no libsasl calls until sasl_client/server_init() completes
> * no libsasl calls are made after sasl_done() is begun
> * when using GSSAPI, you use a thread-safe GSS / Kerberos 5 library.
> It says explicitly that that sasl_set* calls are not thread safe, since they 
> set global state.
> The proton library makes calls to sasl_set* functions in :
>   pni_init_client()
>   pni_init_server(), and
>   pni_process_init()
> Since those are internal functions, there is no way for code that uses Proton 
> to lock around those calls.
> I think proton needs a new API call to let applications call 
> sasl_set_mutex().  Or something.
> We probably also need other protections to meet the other requirements 
> specified in the Cyrus documentation (and quoted above).



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)


[jira] [Commented] (PROTON-992) Proton's use of Cyrus SASL is not thread-safe.

2015-09-11 Thread Alan Conway (JIRA)

[ 
https://issues.apache.org/jira/browse/PROTON-992?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=14740985#comment-14740985
 ] 

Alan Conway commented on PROTON-992:


Yep, was looking at an older version of the code. My bad, re-reading.


> Proton's use of Cyrus SASL is not thread-safe.
> --
>
> Key: PROTON-992
> URL: https://issues.apache.org/jira/browse/PROTON-992
> Project: Qpid Proton
>  Issue Type: Bug
>  Components: proton-c
>Affects Versions: 0.10
>Reporter: michael goulish
>Assignee: michael goulish
>Priority: Critical
>
> Documentation for the Cyrus SASL library says that the library is believed to 
> be thread-safe only if the code that uses it meets several requirements.
> The requirements are:
> * you supply mutex functions (see sasl_set_mutex())
> * you make no libsasl calls until sasl_client/server_init() completes
> * no libsasl calls are made after sasl_done() is begun
> * when using GSSAPI, you use a thread-safe GSS / Kerberos 5 library.
> It says explicitly that that sasl_set* calls are not thread safe, since they 
> set global state.
> The proton library makes calls to sasl_set* functions in :
>   pni_init_client()
>   pni_init_server(), and
>   pni_process_init()
> Since those are internal functions, there is no way for code that uses Proton 
> to lock around those calls.
> I think proton needs a new API call to let applications call 
> sasl_set_mutex().  Or something.
> We probably also need other protections to meet the other requirements 
> specified in the Cyrus documentation (and quoted above).



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)


[jira] [Commented] (PROTON-992) Proton's use of Cyrus SASL is not thread-safe.

2015-09-10 Thread Alan Conway (JIRA)

[ 
https://issues.apache.org/jira/browse/PROTON-992?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel=14739069#comment-14739069
 ] 

Alan Conway commented on PROTON-992:


The general proton philosophy on thread safety is to be "thread agnosic". Calls 
involving values associated with a single engine or reactor *cannot* be made 
concurrently, but objects belonging to different engines or reactors are 
independent and can be used concurrently simply because there are no shared 
variables. Locking or serialization is left to higher layers, which is as it 
should be. We need to preserve that philosophy.

The main problem is that proton tries to hide the sasl_client_init() and 
sasl_client_done() calls in calls that can be made per-connection. Looking at 
the cyrus code, these calls they are clearly not intended to be safe to call 
multiple times or concurrently as they over-write global state. Many C 
libraries have init/done functions that must be called exactly once per process 
(from main() in C, from static ctor/dtor in C++ etc.) It is a hateful 
requirement and proton has done well to avoid it but if we depend on external 
libraries I fear we can avoid it no more. We need global init/done functions at 
least for the sasl stuff. In a single threaded reactor we could call them as a 
convenience in default handlers for reactor start/stop events but code using 
multiple reactors in multiple thread contexts needs to be able to override such 
behavior, and real C programmers will prefer to know that all the global 
init/done functions are called in order under their control in main().

Practical experience with qpid C++ broker suggests that this is enough and 
after that per-connection serialization is sufficient, qpidd does not set the 
SASL mutex functions. However the SASL docs say it is *not* sufficient, and 
maybe qpidd is just lucky or a future version of SASL will break it. We should 
dig deeper before deciding what further serialization horrors need to be 
inflicted on the per-connection part of the  SASL negotiation.

> Proton's use of Cyrus SASL is not thread-safe.
> --
>
> Key: PROTON-992
> URL: https://issues.apache.org/jira/browse/PROTON-992
> Project: Qpid Proton
>  Issue Type: Bug
>  Components: proton-c
>Affects Versions: 0.10
>Reporter: michael goulish
>Priority: Critical
>
> Documentation for the Cyrus SASL library says that the library is believed to 
> be thread-safe only if the code that uses it meets several requirements.
> The requirements are:
> * you supply mutex functions (see sasl_set_mutex())
> * you make no libsasl calls until sasl_client/server_init() completes
> * no libsasl calls are made after sasl_done() is begun
> * when using GSSAPI, you use a thread-safe GSS / Kerberos 5 library.
> It says explicitly that that sasl_set* calls are not thread safe, since they 
> set global state.
> The proton library makes calls to sasl_set* functions in :
>   pni_init_client()
>   pni_init_server(), and
>   pni_process_init()
> Since those are internal functions, there is no way for code that uses Proton 
> to lock around those calls.
> I think proton needs a new API call to let applications call 
> sasl_set_mutex().  Or something.
> We probably also need other protections to meet the other requirements 
> specified in the Cyrus documentation (and quoted above).



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)