bug-glibc
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

linuxthread problem


From: 潘庆峰
Subject: linuxthread problem
Date: Sun, 29 Jul 2001 17:03:30 +0800

Hi, all
        I found a problem in my program, here is the demo:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/signal.h>
#include <signal.h>
#include <sys/wait.h>
#include <pwd.h>
#include <pthread.h>

pthread_mutex_t g_lock;
pthread_cond_t g_cond;

struct TestArg
{
        pthread_mutex_t* plock;
        pthread_cond_t* pcond;
};

inline int CREATE_THREAD(pthread_t *thread,void *(*start_routine)(void*),void *arg)
{
        pthread_attr_t attr;
        pthread_attr_init(&attr); /* initialize attr with default attributes */
        pthread_attr_setstacksize (&attr,1024*1024);
        int res = pthread_create(thread,&attr,start_routine,arg);
        pthread_attr_destroy(&attr);
        return res;
}

void* Dummy(void* arg)
{
        sleep(100); // i do nothing
}

void* TheSon(void* arg)
{
        struct TestArg* pArg;
       
        printf("begin of TheSon()\n");
       
        pArg = (struct TestArg*)arg;

        printf("TheSon: uid:%d, euid:%d\n", getuid(), geteuid());
      
        printf("TheSon(): begin to lock\n");
        pthread_mutex_lock(pArg->plock);
        printf("TheSon(): end lock\n");

        printf("TheSon(): begin to signal\n");
        pthread_cond_signal(pArg->pcond);
        printf("TheSon(): end signal\n");

        printf("TheSon(): begin to unlock\n");
        pthread_mutex_unlock(pArg->plock);
        printf("TheSon(): end unlock\n");
        return NULL;
}

int main(int argc, char** argv)
{
        pthread_t tid;
        pthread_mutex_init(&g_lock,NULL);
        pthread_cond_init(&g_cond,NULL);

        CREATE_THREAD(&tid, Dummy, NULL);

        struct TestArg Arg;
        Arg.pcond = &g_cond;
        Arg.plock = &g_lock;

        if( setuid(505)!=0 || seteuid(505)!=0)
        {
                printf("You should specify a real uid in your system and run as root!\n");
                return 0;
        }

        printf("uid:%d, euid:%d\n", getuid(), geteuid());

        printf("begin to lock in main\n");
        pthread_mutex_lock(&g_lock);
        printf("end of lock in main\n");

        if( CREATE_THREAD(&tid, TheSon, &Arg) )
        {
                printf("Can't create thread\n");
                return 0;
        }
        else
        {
                sleep(1); /* If this thread go too fast, the problem MAY not appear */
                printf("begin to wait\n");
                pthread_cond_wait(&g_cond, &g_lock);
                printf("end wait\n");

                printf("begin to unlock in main\n");
                pthread_mutex_unlock(&g_lock);
                printf("end unlock in main\n");
        }
        return 0;
}



        if you run it as root, then i will have a dead lock.
        These program will dead lock if you run it as root. The source of the problem is that:  
        1. After CREATE_THREAD(&tid, Dummy, NULL);  linuxthread create a manager thread, this manager run as root
        2. after that, main thread setuid() to 505
        3. main thread create "TheSon", "TheSon" clone() by manager thread, so it's root's uid
        4. main thread call pthread_cond_wait(), but it can't kill() a signal to "TheSon", because its uid is 505(linuxthread use signal to communate each other), so the program dead lock.

        It's seems the kernel's problem, linuxthread can help nothing, but i have to say that linuxthread should not assume system call kill() will never fail, as i know, linuxthread just call kill() but not care it's return code? I think if linuxthread should do that test and rutun an error, then pthread_mutex_unlock() will return error but not dead lock .


Yours
Qingfeng Pan
2001.7.29


reply via email to

[Prev in Thread] Current Thread [Next in Thread]