mailing list of musl libc
 help / color / Atom feed
* [musl] No such process return value in pthread_getcpuclockid
@ 2020-02-10 19:29 Alexander Scherbatiy
  2020-02-10 19:34 ` Rich Felker
  0 siblings, 1 reply; 6+ messages in thread
From: Alexander Scherbatiy @ 2020-02-10 19:29 UTC (permalink / raw)
  To: musl

Hello,

It seems that pthread_getcpuclockid does not properly handle non valid 
thread id argument.

Below is a sample which calls pthread_getcpuclockid with NULL thread id. 
The expected result is ESRCH (No thread with the ID thread could be 
found). It crashes in my docker with Alpine Linux 3.11.3 (musl libc 
x86_64 1.1.24). It returns ESRCH on my Ubuntu system.

---  pthread_getcpuclockid_sample.c ---

#include <time.h>
#include <stdio.h>
#include <pthread.h>
#include <errno.h>


int main()
{
     clockid_t cid;
     int s;

     s = pthread_getcpuclockid((pthread_t) NULL, &cid);

     if (s == ESRCH) {
         printf("result: ESRCH\n");
     } else {
         printf("result: %d\n", s);
     }

     return 0;
}
--------------------------------------

 > gcc -pthread -o pthread_getcpuclockid_sample 
pthread_getcpuclockid_sample.c

 > ./pthread_getcpuclockid_sample

Segmentation fault (core dumped)


Thanks,

Alexander.




^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [musl] No such process return value in pthread_getcpuclockid
  2020-02-10 19:29 [musl] No such process return value in pthread_getcpuclockid Alexander Scherbatiy
@ 2020-02-10 19:34 ` Rich Felker
  2020-02-10 19:57   ` Alexander Scherbatiy
  0 siblings, 1 reply; 6+ messages in thread
From: Rich Felker @ 2020-02-10 19:34 UTC (permalink / raw)
  To: musl

On Mon, Feb 10, 2020 at 10:29:02PM +0300, Alexander Scherbatiy wrote:
> Hello,
> 
> It seems that pthread_getcpuclockid does not properly handle non
> valid thread id argument.
> 
> Below is a sample which calls pthread_getcpuclockid with NULL thread
> id. The expected result is ESRCH (No thread with the ID thread could
> be found). It crashes in my docker with Alpine Linux 3.11.3 (musl
> libc x86_64 1.1.24). It returns ESRCH on my Ubuntu system.

There's no such thing as a "null thread id". A pthread_t value is
either the id of a thread which is still valid (still running or
joinable and not yet joined), or *any* use of it produces undefined
behavior. There is no value reserved for a sentinel. If you need an
optional thread id variable/field, you need a separate validity flag
alongside it.

None of this is unique to musl; it's the way the POSIX threads
interfaces are designed.

Rich

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [musl] No such process return value in pthread_getcpuclockid
  2020-02-10 19:34 ` Rich Felker
@ 2020-02-10 19:57   ` Alexander Scherbatiy
  2020-02-10 20:14     ` Rich Felker
  2020-02-10 20:23     ` Markus Wichmann
  0 siblings, 2 replies; 6+ messages in thread
From: Alexander Scherbatiy @ 2020-02-10 19:57 UTC (permalink / raw)
  To: musl, Rich Felker

On 10.02.2020 22:34, Rich Felker wrote:

> On Mon, Feb 10, 2020 at 10:29:02PM +0300, Alexander Scherbatiy wrote:
>> Hello,
>>
>> It seems that pthread_getcpuclockid does not properly handle non
>> valid thread id argument.
>>
>> Below is a sample which calls pthread_getcpuclockid with NULL thread
>> id. The expected result is ESRCH (No thread with the ID thread could
>> be found). It crashes in my docker with Alpine Linux 3.11.3 (musl
>> libc x86_64 1.1.24). It returns ESRCH on my Ubuntu system.
> There's no such thing as a "null thread id". A pthread_t value is
> either the id of a thread which is still valid (still running or
> joinable and not yet joined), or *any* use of it produces undefined
> behavior. There is no value reserved for a sentinel. If you need an
> optional thread id variable/field, you need a separate validity flag
> alongside it.
>
> None of this is unique to musl; it's the way the POSIX threads
> interfaces are designed.

I can create a thread, join to it and use the thread id in 
pthread_getcpuclockid function after that.

The Linux Programmer's Manual has the following errors section: "ESRCH  
No thread with the ID thread could be found."

Does pthread_getcpuclockid function from musl follows the similar errors 
handling approach?

Thanks,

Alexandr.

>
> Rich

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [musl] No such process return value in pthread_getcpuclockid
  2020-02-10 19:57   ` Alexander Scherbatiy
@ 2020-02-10 20:14     ` Rich Felker
  2020-02-11  9:16       ` Alexander Scherbatiy
  2020-02-10 20:23     ` Markus Wichmann
  1 sibling, 1 reply; 6+ messages in thread
From: Rich Felker @ 2020-02-10 20:14 UTC (permalink / raw)
  To: musl

On Mon, Feb 10, 2020 at 10:57:22PM +0300, Alexander Scherbatiy wrote:
> On 10.02.2020 22:34, Rich Felker wrote:
> 
> >On Mon, Feb 10, 2020 at 10:29:02PM +0300, Alexander Scherbatiy wrote:
> >>Hello,
> >>
> >>It seems that pthread_getcpuclockid does not properly handle non
> >>valid thread id argument.
> >>
> >>Below is a sample which calls pthread_getcpuclockid with NULL thread
> >>id. The expected result is ESRCH (No thread with the ID thread could
> >>be found). It crashes in my docker with Alpine Linux 3.11.3 (musl
> >>libc x86_64 1.1.24). It returns ESRCH on my Ubuntu system.
> >There's no such thing as a "null thread id". A pthread_t value is
> >either the id of a thread which is still valid (still running or
> >joinable and not yet joined), or *any* use of it produces undefined
> >behavior. There is no value reserved for a sentinel. If you need an
> >optional thread id variable/field, you need a separate validity flag
> >alongside it.
> >
> >None of this is unique to musl; it's the way the POSIX threads
> >interfaces are designed.
> 
> I can create a thread, join to it and use the thread id in
> pthread_getcpuclockid function after that.

That has undefined behavior, and the fact that it does is *inherent* -
reusable resource identifiers can be reused as soon as they're freed
(and nonreusable ones only admit a finite number of resource ever to
exist). Expecting use of pthread_t after its lifetime to give a
meaningful error is analogous to expecting free() or close() to give
you a meaningful error.

If you need a citation, it's XSH 2.9.2 Thread IDs:

    "Although implementations may have thread IDs that are unique in a
    system, applications should only assume that thread IDs are usable
    and unique within a single process. The effect of calling any of
    the functions defined in this volume of POSIX.1-2017 and passing
    as an argument the thread ID of a thread from another process is
    unspecified. The lifetime of a thread ID ends after the thread
    terminates if it was created with the detachstate attribute set to
    PTHREAD_CREATE_DETACHED or if pthread_detach() or pthread_join()
    has been called for that thread. A conforming implementation is
    free to reuse a thread ID after its lifetime has ended. If an
                                                            ^^^^^
    application attempts to use a thread ID whose lifetime has ended,
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    the behavior is undefined."
    ^^^^^^^^^^^^^^^^^^^^^^^^^^

https://pubs.opengroup.org/onlinepubs/9699919799/functions/V2_chap02.html#tag_15_09_02

> The Linux Programmer's Manual has the following errors section:
> "ESRCH  No thread with the ID thread could be found."
> 
> Does pthread_getcpuclockid function from musl follows the similar
> errors handling approach?

The specification of ESRCH for pthread interfaces was a bug, because a
"shall fail" or even "may fail" condition makes no sense with a
behavior that's explicitly undefined (in which case the implementation
is allowed to do anything at all). This was clarified in POSIX 2008 as
a result of Austin Group interpretation 142:

https://collaboration.opengroup.org/austin/interps/documents/14366/AI-142.txt

Unfortunately the Linux man pages have not corrected this.

Rich

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [musl] No such process return value in pthread_getcpuclockid
  2020-02-10 19:57   ` Alexander Scherbatiy
  2020-02-10 20:14     ` Rich Felker
@ 2020-02-10 20:23     ` Markus Wichmann
  1 sibling, 0 replies; 6+ messages in thread
From: Markus Wichmann @ 2020-02-10 20:23 UTC (permalink / raw)
  To: musl

On Mon, Feb 10, 2020 at 10:57:22PM +0300, Alexander Scherbatiy wrote:
> I can create a thread, join to it and use the thread id in
> pthread_getcpuclockid function after that.
>

Nope, that's a use after free. Joining a thread has the effect of
invalidating all outstanding pthread_ts for the joined thread.

> The Linux Programmer's Manual has the following errors section: "ESRCH  No
> thread with the ID thread could be found."
>

And POSIX says "No errors are defined." I'm guessing POSIX wins.
Use-after-free in this case would be dangerous even if it did not crash.
See, once a thread is joined, the pthread_t is invalidated, but it may
be reused. Another thread may immediately create another thread that
coincidentally allocates the pthread_t in exactly the same place as the
old pthread_t was. Not as coincidental as one might think if both
threads have the same stack and guard size.

Once that has happened, pthread_getcpuclockid (or any other pthread_*
function) will access a different thread than you intended. It is a
logic error to do what you want to do, and crashing is one of the best
things that can happen to you if you try. The other possibility is a
really subtle bug that only occurs sometimes. Happy debugging!

> Does pthread_getcpuclockid function from musl follows the similar errors
> handling approach?
>

Musl's pthread_getcpuclockid() cannot fail at this time. It can only
succeed or crash.

Ciao,
Markus

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [musl] No such process return value in pthread_getcpuclockid
  2020-02-10 20:14     ` Rich Felker
@ 2020-02-11  9:16       ` Alexander Scherbatiy
  0 siblings, 0 replies; 6+ messages in thread
From: Alexander Scherbatiy @ 2020-02-11  9:16 UTC (permalink / raw)
  To: musl, Rich Felker

On 10.02.2020 23:14, Rich Felker wrote:

> The specification of ESRCH for pthread interfaces was a bug, because a
> "shall fail" or even "may fail" condition makes no sense with a
> behavior that's explicitly undefined (in which case the implementation
> is allowed to do anything at all). This was clarified in POSIX 2008 as
> a result of Austin Group interpretation 142:
>
> https://collaboration.opengroup.org/austin/interps/documents/14366/AI-142.txt

  Thank you. It sounds right that If an application attempts to use a 
thread ID whose lifetime has ended, the behavior is undefined.


  I see that "POSIX 2008 as a result of Austin Group interpretation 142" 
has strange comment about pthread_getcpuclockid() function:

   "The same argument applies to the ESRCH errors for pthread_detach(),  
pthread_getschedparam(), pthread_setschedparam() and  
pthread_setschedprio().

   (It does not apply to pthread_getcpuclockid() since the function  
could just always return a fixed clock ID without needing to  examine 
the thread ID.)"

   What does it mean that pthread_getcpuclockid() does not need to 
examine the thread ID? As I see from the musl pthread_getcpuclockid() 
implementation it really uses the thread ID:

https://git.musl-libc.org/cgit/musl/tree/src/thread/pthread_getcpuclockid.c


   Thanks,

   Alexander.

>
> Unfortunately the Linux man pages have not corrected this.
>
> Rich

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, back to index

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-10 19:29 [musl] No such process return value in pthread_getcpuclockid Alexander Scherbatiy
2020-02-10 19:34 ` Rich Felker
2020-02-10 19:57   ` Alexander Scherbatiy
2020-02-10 20:14     ` Rich Felker
2020-02-11  9:16       ` Alexander Scherbatiy
2020-02-10 20:23     ` Markus Wichmann

mailing list of musl libc

Archives are clonable: git clone --mirror http://inbox.vuxu.org/musl

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://inbox.vuxu.org/vuxu.archive.musl


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git