[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]
Bug with fcntl(n, F_SETOWN, getpid) with NPTL 0.34
- From: David Holmes <dholmes dltech com au>
- To: phil-list redhat com
- Subject: Bug with fcntl(n, F_SETOWN, getpid) with NPTL 0.34
- Date: Fri, 17 Oct 2003 13:10:29 +1000 (EST)
I searched to see if this was a known issue but found nothing.
Using RH9 out-of-the-box with the NPTL 0.34 update applied.
The test program (attached) tries to do fcntl(fd, F_SETOWN, getpid()) on a
socket descriptor. If it does this in the main thread then it works fine.
If it does this in a separate pthread then it fails with EPERM.
Looking into the bowels of sock.c sock_no_fcntl does this:
case F_SETOWN:
if (current->pgrp != -arg &&
current->pid != arg &&
!capable(CAP_KILL)) return(-EPERM);
Running as root provides the CAP_KILL capability and the test passes. So
it seems that there is a discrepancy between the value returned by
getpid() and the value used internally (current->pid).
This only fails with NPTL. If I use LD_ASSUME_KERNEL the test passes
threaded and non-threaded.
Thanks.
David Holmes
#include <sys/types.h>
#include <sys/socket.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <pthread.h>
#define CHECK(func, msg) \
if ((func) != 0) { \
fprintf(stderr, "Error: %s - %s\n", msg, strerror(errno)); \
exit(1); \
}
#define CHECKP(func) \
do { \
int rc = (func); \
if (rc!= 0) { \
fprintf(stderr, "Error: " #func " - %s\n", strerror(rc)); \
exit(1); \
} \
} while(0)
int fds[] = { -1, -1 };
static int fcntlSetFlag(int fd,int flag) {
int flags=fcntl(fd,F_GETFL,0);
if (flags<0) {
return -1;
}
return fcntl(fd,F_SETFL,flags|flag);
}
static void test() {
int fd;
CHECK(socketpair(AF_UNIX, SOCK_STREAM, 0, fds), "socketpair");
fd = fds[0];
if (fcntlSetFlag(fd, O_ASYNC)<0) {
fprintf(stderr, "error setting O_ASYNC flag on %d: %s\n",
fd, strerror(errno));
exit(1);
}
if (fcntl(fd, F_SETOWN, getpid())<0) {
fprintf(stderr, "error fcntl(%d, F_SETOWN, %d): %s\n",fd, getpid(), strerror(errno));
exit(1);
}
printf("Managed to set up socket %d ok\n", fd);
close(fds[0]);
close(fds[1]);
}
static void* threadRun(void* arg) {
test();
pthread_detach(pthread_self()); /* ensure detached to release resources */
pthread_exit(NULL);
}
static void threadedTest() {
pthread_t thread;
pthread_attr_t attr;
/* we take default status:
- joinable
- default contention scope ??
- default stack attributes
*/
CHECKP(pthread_attr_init(&attr));
/* always set this so that the thread uses the attr object we pass in */
CHECKP(pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED));
CHECKP(pthread_create(&thread, &attr, threadRun, 0));
}
int main(int argc, char* argv[]) {
if (argc > 1) {
printf("Doing threaded test\n");
threadedTest();
pthread_exit(0);
}
else {
printf("Doing normal test\n");
test();
}
return 0;
}
[Date Prev][Date Next] [Thread Prev][Thread Next]
[Thread Index]
[Date Index]
[Author Index]