#define _GNU_SOURCE #include #include #include #include #include #define NUM_THREADS 1 static pthread_attr_t attr; static volatile int euid = -1, gen, num; void *thr(void *arg) { while (euid == -1) ; int cur_gen = gen; int teuid = syscall(SYS_geteuid); if (teuid != euid) { printf("mismatch: %d != %d\n", teuid, euid); sleep(1000000); } __sync_fetch_and_add(&num, 1); while (cur_gen == gen) ; if (pthread_create(&(pthread_t){0}, &attr, thr, 0)) abort(); return 0; } int main(void) { pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); for (int i = 0; i < NUM_THREADS; i++) if (pthread_create(&(pthread_t){0}, &attr, thr, 0)) abort(); printf("uid = %d euid = %d\n", getuid(), geteuid()); int ruid = getuid(); int cur_euid = 0; for (int it = 0;; it++) { printf("%d\n", it); cur_euid = cur_euid ? 0 : ruid; if (seteuid(cur_euid)) { perror("seteuid"); abort(); } num = 0; euid = cur_euid; while (num < NUM_THREADS) ; euid = -1; gen = 1 - gen; } }