Bug 2745 - mutex with ERRORCHECK attribute fails to unlock on child after fork
Summary: mutex with ERRORCHECK attribute fails to unlock on child after fork
Status: RESOLVED INVALID
Alias: None
Product: glibc
Classification: Unclassified
Component: nptl (show other bugs)
Version: 2.3.6
: P2 normal
Target Milestone: ---
Assignee: Ulrich Drepper
URL:
Keywords:
: 2746 (view as bug list)
Depends on:
Blocks:
 
Reported: 2006-06-09 19:18 UTC by Rafal Dabrowa
Modified: 2014-07-04 22:12 UTC (History)
1 user (show)

See Also:
Host: i686-pc-linux-gnu
Target: i686-pc-linux-gnu
Build: i686-pc-linux-gnu
Last reconfirmed:
fweimer: security-


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Rafal Dabrowa 2006-06-09 19:18:20 UTC
pthread_mutex_unlock function unexpectedly fails when called in child process 
on a mutex, which:
 * has PTHREAD_MUTEX_ERRORCHECK or PTHREAD_MUTEX_RECURSIVE attribute
 * has been locked in parent process

Possibility of unlocking of a mutex locked in parent process is typically used 
in handlers installed by pthread_atfork routine and is supposed to work.

Code example:

#include <pthread.h>
#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    pthread_mutex_t mutex;
    pthread_mutexattr_t attr;
    pid_t pid;
    int err;

    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
    pthread_mutex_init(&mutex, &attr);
    pthread_mutex_lock(&mutex);
    pid = fork();
    err = pthread_mutex_unlock(&mutex);
    printf("pid=%d, err=%d\n", pid, err);
    return 0;
}

---------------------------------------------------
Output:
    pid=0, err=1
    pid=5817, err=0
err should be 0 both on child and on parent.
Comment 1 Ulrich Drepper 2006-06-10 07:01:54 UTC
After fork only async-safe functions can be called.  Therefore the code is
completely bogus.  Don't file bugs if you have no clue what you're talking about.
Comment 2 Ulrich Drepper 2006-06-10 07:02:45 UTC
*** Bug 2746 has been marked as a duplicate of this bug. ***
Comment 3 Rafal Dabrowa 2006-06-10 08:21:13 UTC
I have a clue: see "RATIONALE" section of "pthread_atfork" specification in:

   http://www.opengroup.org/onlinepubs/009695399/functions/pthread_atfork.html

We can read there:
    "The expected usage is that the prepare handler acquires all mutex locks and
the other two fork handlers release them."

But this does not work with glibc, because unlocking mutex from "child" handler
fails.
Comment 4 Jakub Jelinek 2006-06-10 08:58:02 UTC
What from "Consequently, to avoid errors, the child process may only execute
async-signal-safe operations until such time as one of the exec functions is
called." you don't understand?
In the child you of course are never supposed to unlock the lock, but instead
pthread_mutex_init it.
Comment 5 Jakub Jelinek 2006-06-10 09:03:45 UTC
Also, the child doesn't own the mutex, it is owned by the thread that called
fork (), so for error checking mutex returning EPERM is certainly valid behavior.
Comment 6 Rafal Dabrowa 2006-06-10 18:44:44 UTC
"If a multi-threaded process calls fork(), the new process shall contain a 
replica of the calling thread and its entire address space, possibly including 
the states of mutexes and other resources. Consequently, to avoid errors, the 
child process may only execute async-signal-safe operations until such time as 
one of the exec functions is called"

This is about multi-threaded processes only. Process in my example program is 
single-threaded. So async-safety does not apply.

Also, do you understand "replica of the calling thread and its entire address 
space, possibly including the states of mutexes and other resources" ? If the 
thread owns mutex in parent process, it should own the mutex in child, too.

 I think this may not apply to mutexes with PTHREAD_PROCESS_SHARED attribute, 
although the standard does not say about this.
Comment 7 Ulrich Drepper 2006-06-10 19:45:51 UTC
Dammit, leave this closed.  You are wrong on all counts, from not async-safe
applying to using pthread_mutex_unlock in the first place.  If you reopen this
again or file another stupid bug like this I have no choice but to make sure you
cannot do it again in future.
Comment 8 Rafal Dabrowa 2006-06-13 07:33:10 UTC
OK, sorry. I have suggested with pthreads implementation under AIX.