> The answer is that if you're compiled single-threaded, it's perfectly
legal.
> If you're multi-threaded, it's not.

err, nobody codes like this

find me an example in real-life code that is being used.
better yet, find me an example in OpenSSL.

Your other points I agree with however.

> > Let's assume for a moment that openssl is not "compiled for multi
> > thread", whatever you mean with that exactly.  Even when the application
> > is using threads, when openssl tries to use errno it will get the one
for
> > the current thread.

Err? No.

Between the time that errno is set, and errno is read by the application,
ANOTHER thread could have changed errrno!! The very definition
of a race condition.

Furthermore, you might be reading 'errno', but the library call in
libpthread
that replaced the library call you thought you were using was actually
setting (*__the_errno()). So you MUST link with -lpthread when you define
_REENTRANT and visa versa to ensure the standard library and the app
are talking about the same errno!

My (possibly insane) usage of OpenSSL plugs in all my own OS routines,
just to avoid this problem.

-paul


On Jan 29, 2008 5:54 PM, David Schwartz <[EMAIL PROTECTED]> wrote:

>
> > There is no "global" variable named errno, it only exist in the TLS.
>  You
> > could say that because there is only 1 TLS, that it's global, and it
> > acts that way.  But it's not really the same as a normal global
> > variable.  You can't access the variables in the same manner you access
> > other global variables.
>
> Is the following code legal:
>
> void foo(void)
> {
>  static int *my_errno=NULL;
>  if(my_errno==NULL) my_errno=errno;
>  // code that uses 'my_errno' as if it were 'errno'
> }
>
> The answer is that if you're compiled single-threaded, it's perfectly
> legal.
> If you're multi-threaded, it's not.
>
> This might be a perfectly sensible optimization to condition on
> '_REENTRANT'
> not being defined. In principle, the compiler might do such a thing
> automatically if the overhead of TLS were higher than the overhead of the
> test.
>
> > In case of errno on a glibc system with NPTL there is no difference in
> the
> > compiled code.  You always get the same function call.
>
> Exactly. The precise same code can have a very different semantic meaning
> depending upon whether it is used in a multi-threaded or a single-threaded
> process. That's why you *must* specify appropriate compilation flags. The
> code may need to change so that it can produce *different* code to get the
> *same* semantic meaning.
>
> > Let's assume for a moment that openssl is not "compiled for multi
> > thread", whatever you mean with that exactly.  Even when the application
> > is using threads, when openssl tries to use errno it will get the one
> for
> > the current thread.
>
> Really? Even if it's coded like my 'foo' above? It will magically always
> get
> the right 'errno'? How?!
>
> > > That these two different semantics are implemented by the same
> > > code doesn't
> > > change the fact that the semantics are different. In fact, it makes
> the
> > > important point that the semantics of code can be changed by whether
> the
> > > process is single-threaded or multi-threaded.
>
> > I'm not at all saying that the semantics are the same.  All I'm saying
> > is that in case of errno on a recent glibc there is no difference in the
> > compiled code depending on wether your application or library is
> > multi-threaded or not.
>
> There is a huge difference. In the case of a single-threaded process, it
> will get a process global 'errno' and optimizations such as my 'foo'
> function above are perfectly legal. In the case of a multi-threaded
> process,
> they're not.
>
> > > On many Linux distributions, it is perfectly acceptable to do
> > the following:
> > >
> > > #ifdef _REENTRANT
> > > // inefficient thread-safe code
> > > #else
> > > // more efficient code that assumes 'errno' is process-global
> > > #endif
>
> > On many Linux distributions it's required that if such code is in a
> > library that it's compiled using -D_REENTRANT for the packages
> > they ship.  With other words, if the library can be compiled
> > reentrant, that's what we want.
>
> Right, and the OP is saying he doesn't have to compile with -D_REENTRANT
> (or
> whatever else is specified on his platform as required for multi-threaded
> code) and he can still use the library in a multi-threaded process.
>
> I'm saying he can't do this even if he thinks the code will be the same
> because the "same code" can mean something different. Different code may
> be
> needed to get the same *effect*.
>
> Compiling code without the compilation flags your platform documents as
> required to get thread-safety guarantees and then using that compiled code
> in a multi-threaded process is simply off the map. Anything can happen.
> Here
> be dragons. This is so even in the case of Linux, where all the flags do
> (at
> least, on most Linux platforms, AFAICT) is add a single define to the
> compilation and a library to the linking.
>
> And it's a bad idea even if you know it's safe on a particular platform. 9
> times out of 10, code winds up running on platforms you never expected. If
> these assumptions are no longer true on that platform, you may get code
> that
> appears to work but has subtle bugs that cause it to do the wrong thing
> under load. This is precisely the type of issue that can cause information
> intended for one client to go to another. Not a good think in an
> encryption/security context.
>
> DS
>
>
> ______________________________________________________________________
> OpenSSL Project                                 http://www.openssl.org
> Development Mailing List                       openssl-dev@openssl.org
> Automated List Manager                           [EMAIL PROTECTED]
>

Reply via email to