Created
July 15, 2011 04:07
-
-
Save andrewg-felinemenace/1084042 to your computer and use it in GitHub Desktop.
Per-thread user ids and capabilities
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdlib.h> | |
#include <unistd.h> | |
#include <string.h> | |
#include <sys/types.h> | |
#include <stdio.h> | |
#include <pthread.h> | |
#include <sys/syscall.h> | |
/* | |
* This can be used to demonstrate a grsecurity chroot_findtask bug, recent glibc cross thread | |
* signalling on set*id, and or native per-thread privilege ids if using a non glibc or non | |
* recent glibc. | |
* | |
* use /tmp/repro anything to test via raw syscall() to see how glibc changes things. | |
* | |
* ubuntu 11.04, just for qemu folks :) | |
* | |
* # /tmp/r | |
* dropping via libc setuid/setgid | |
* --> modern glibc will apply to all threads | |
* [main] my [ug]id is 100/100 | |
* [thread] my [ug]id is 100/100 | |
* # /tmp/r proof | |
* dropping via raw syscall setgid/setuid | |
* [main] my [ug]id is 100/100 | |
* [thread] my [ug]id is 0/0 | |
*/ | |
// recent glibc, chroot_findtask = 1 | |
// # /tmp/repro | |
// [main] my [ug]id is 100/100 | |
// [thread] my [ug]id is 0/0 | |
// recent glibc, chroot_findtask = 0 | |
// # /tmp/repro | |
// [main] my [ug]id is 100/100 | |
// [thread] my [ug]id is 100/100 | |
// uclibc, chroot_findtask = 1 | |
// # ./repro | |
// [main] my [ug]id is 100/100 | |
// [thread] my [ug]id is 0/0 | |
// uclibc, chroot_findtask = 0 | |
// # ./repro | |
// [main] my [ug]id is 100/100 | |
// [thread] my [ug]id is 0/0 | |
int run; // trivial spin lock. lazy, I know. | |
int raw_syscall; | |
void *dumpprivs(void *arg) | |
{ | |
while(! run); | |
printf("[thread] my [ug]id is %d/%d\n", getuid(), getgid()); | |
exit(1); | |
} | |
int main(int argc, char **argv) | |
{ | |
int rc; | |
pthread_t id; | |
raw_syscall = argc > 1; | |
pthread_create(&id, NULL, dumpprivs, NULL); | |
chroot("/var/empty"); | |
if(raw_syscall) { | |
printf("dropping via raw syscall setgid/setuid\n"); | |
syscall(SYS_setgid, 100); | |
syscall(SYS_setuid, 100); | |
} else { | |
printf("dropping via libc setuid/setgid\n"); | |
printf("--> modern glibc will apply to all threads\n"); | |
setgid(100); | |
setuid(100); | |
} | |
printf("[main] my [ug]id is %d/%d\n", getuid(), getgid()); | |
run = 1; | |
while(run); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment