Bug 810

Summary: pthread_create() doesn't fail with EPERM
Product: glibc Reporter: Nikolay Zhuravlev <nikolay.zhuravlev>
Component: nptlAssignee: GOTO Masanori <gotom>
Status: RESOLVED FIXED    
Severity: normal CC: glibc-bugs
Priority: P2 Flags: fweimer: security-
Version: 2.3.2   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:
Attachments: pthread_create_nptl.patch
patch for pthread_create (nptl)

Description Nikolay Zhuravlev 2005-03-30 14:11:50 UTC
pthread_create() doesn't fail with EPERM when
SCHED_FIFO is requested by an unprivileged process.

Tested on the following system:
$ /lib/libc.so.6
GNU C Library stable release version 2.3.2, by Roland McGrath et al.
$ uname -a
Linux  2.4.20-8smp #1 SMP Thu Mar 13 17:45:54 EST 2003 i686 i686 i386
GNU/Linux
The test is built with 'gcc -lpthread -o test test.c'

--------------------------------------------------
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <limits.h>

#define PRIO 17

pthread_t tid;

void *
thread1( void *arg )
{
    pthread_exit(0);
    return 0;
}

int main(int argc, char *argv[])
{

    int err;
    int status;         /* used in pthread_join() */
    struct sched_param  params;
    pthread_attr_t attr;

    if (pthread_attr_init(&attr)) {
        printf("pthread_attr_init FAILED\n");
        exit(1);
    }

    if (pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED)) {
        printf("\npthread_attr_setinheritsched FAILED\n");
        (void) pthread_attr_destroy( &attr );
        exit(1);
    }

    if (pthread_attr_setschedpolicy(&attr, SCHED_FIFO)) {
        printf("\npthread_attr_setschedpolicy FAILED\n");
        (void) pthread_attr_destroy( &attr );
        exit(1);
    }

    params.sched_priority = PRIO;
    if (pthread_attr_setschedparam(&attr, &params)) {
        printf("\npthread_attr_setschedparam FAILED\n");
        (void) pthread_attr_destroy( &attr );
        exit(1);
    }

    if ((err = pthread_create(&tid, &attr, &thread1, NULL)) != EPERM) {

        printf("TEST FAILED\n");

    } else {

        printf("TEST OK\n");

        if (err == 0 && pthread_join(tid, (void **)&status)) {
            printf("pthread_join FAILED\n");
            (void) pthread_cancel(tid);
            exit(1);
        }
    }
    (void) pthread_attr_destroy( &attr );
    return(0);
}

-----------
Also, the test runs fine for the following configurations:

# new machine
glibc 2.3.3,
kernel 2.6.9-1.6_FC2smp

# old machine
glibc 2.2.93
kernel 2.4.18-14
Comment 1 Nikolay Zhuravlev 2005-03-30 14:24:38 UTC
The corrected test case follows...


#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <limits.h>

#define PRIO 17

pthread_t tid;

void *
thread1( void *arg )
{
    pthread_exit(0);
    return 0;
}

int main(int argc, char *argv[])
{

    int err;
    int status;         /* used in pthread_join() */
    struct sched_param  params;
    pthread_attr_t attr;

    if (pthread_attr_init(&attr)) {
        printf("pthread_attr_init FAILED\n");
        exit(1);
    }

    if (pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED)) {
        printf("\npthread_attr_setinheritsched FAILED\n");
        (void) pthread_attr_destroy( &attr );
        exit(1);
    }

    if (pthread_attr_setschedpolicy(&attr, SCHED_FIFO)) {
        printf("\npthread_attr_setschedpolicy FAILED\n");
        (void) pthread_attr_destroy( &attr );
        exit(1);
    }

    params.sched_priority = PRIO;
    if (pthread_attr_setschedparam(&attr, &params)) {
        printf("\npthread_attr_setschedparam FAILED\n");
        (void) pthread_attr_destroy( &attr );
        exit(1);
    }

    if ((err = pthread_create(&tid, &attr, &thread1, NULL)) != EPERM) {

        printf("TEST FAILED\n");

        if (err == 0 && pthread_join(tid, (void **)&status)) {
            printf("pthread_join FAILED\n");
            (void) pthread_cancel(tid);
        }
    } else {

        printf("TEST OK\n");

    }
    (void) pthread_attr_destroy( &attr );
    return(0);
}
Comment 2 Uttam Pawar 2005-04-14 21:35:03 UTC
Created attachment 456 [details]
pthread_create_nptl.patch
Comment 3 Uttam Pawar 2005-04-14 21:36:24 UTC
(In reply to comment #2)
> Created an attachment (id=456)
> pthread_create_nptl.patch
> 

This bug appears to be in nptl too. The proposed patch fixes bug only in nptl.
Comment 4 Nikolay Zhuravlev 2005-04-15 10:01:32 UTC
Assuming we are talking about rev 1.31 here, I have a better idea for the 
patch. Still not as good as the current version, though.
Comment 5 Nikolay Zhuravlev 2005-04-15 10:03:31 UTC
Created attachment 457 [details]
patch for pthread_create (nptl)
Comment 6 Uttam Pawar 2005-06-16 20:20:16 UTC
Is there any status change of this bug?
Comment 7 Ulrich Drepper 2005-09-16 14:53:06 UTC
LinuxThreads support is gone.  Every remaining problem is a feature.
Comment 8 Jatin Nansi 2005-09-27 14:14:06 UTC
Reopening this bug since it was wrongly assigned to the linuxthreads component.
It applies to nptl.
Comment 9 Nikolay Zhuravlev 2005-09-27 16:58:04 UTC
Yes, my mistake. LinuxThreads (even though now irrelevant) does work:

LD_ASSUME_KERNEL=2.4.0 ./test
TEST OK

More modern nptl implementation (FC3) also works:
./test
TEST OK
$ uname -a
Linux dendy 2.6.9-1.667 #1 Tue Nov 2 14:41:25 EST 2004 i686 i686 i386 GNU/Linux
$ /lib/tls/libc.so.6 
GNU C Library stable release version 2.3.3, by Roland McGrath et al.
Comment 10 Ulrich Drepper 2005-10-16 08:21:37 UTC
There have been numerous changes in that area.  And the test does not fail for
me.  Closing the bug now.