Messages in this thread | | | Date | Mon, 12 Apr 1999 15:11:15 -0400 (EDT) | From | "Richard B. Johnson" <> | Subject | verify_area(...) possible problem. |
| |
If I deliberately pass the kernel a bad pointer for an ioctl(), and the kernel code does a verify_area(), the return value may be zero, but dereferencing that pointer can cause a kernel Oops.
This was uncovered in some exhaustive testing of a driver that works if bad parameters are not passed.
Apr 12 14:52:58 chaos kernel: Calling verify_area(VERIFY_WRITE, 12345678, 4 Apr 12 14:52:58 chaos kernel: Result was 0 Apr 12 14:52:58 chaos kernel: Unable to handle kernel paging request at virtual address 12345678 Apr 12 14:52:58 chaos kernel: current->tss.cr3 = 081a4000, %cr3 = 081a4000 Apr 12 14:52:58 chaos kernel: *pde = 00000000 Apr 12 14:52:58 chaos kernel: Oops: 0002 Apr 12 14:52:58 chaos kernel: CPU: 0 Apr 12 14:52:58 chaos kernel: EIP: 0010:[<d404920b>] Apr 12 14:52:58 chaos kernel: EFLAGS: 00010046 Apr 12 14:52:58 chaos kernel: eax: 00000000 ebx: 00000000 ecx: 00000005 edx: c90aa000 Apr 12 14:52:58 chaos kernel: esi: 12345678 edi: 00000286 ebp: dead0000 esp: c82d9f8c Apr 12 14:52:58 chaos kernel: ds: 0018 es: 0018 ss: 0018 Apr 12 14:52:58 chaos kernel: Process tester (pid: 172, process nr: 30, stackpage=c82d9000) Apr 12 14:52:58 chaos kernel: Stack: ffffffe7 c82d8000 c012ef20 c7e83a90 c91abde0 dead0000 12345678 c82d8000 Apr 12 14:52:58 chaos kernel: 00000002 00000004 bffff7a4 c7e83a90 c82d9fc4 c0107b74 00000004 dead0000 Apr 12 14:52:58 chaos kernel: 12345678 00000002 00000004 bffff7a4 00000036 0000002b 0000002b 00000036 Apr 12 14:52:58 chaos kernel: Call Trace: [sys_ioctl+416/464] [system_call+52/56] Apr 12 14:52:58 chaos kernel: Code: 89 06 e9 bf 00 00 00 89 f6 85 f6 0f 84 b0 00 00 00 b8 00 e0
Snippet of code from a driver:
static int device_ioctl(struct inode *inp, struct file *fp, unsigned int cmd, unsigned long arg) { long flags; int result; spin_lock_irqsave(&device_lock, flags); result = 0;
switch(cmd) { case READ_INTR_COUNT: if(arg) { printk("Calling verify_area(VERIFY_WRITE, %p, %d)\n", (void *)arg, sizeof(int)); result = verify_area(VERIFY_WRITE, (void *)arg, sizeof(int)); printk("Result was %d\n", result); if(result) break; *((int *) arg) = info->intrs; } else result = -EINVAL; break;
Cheers, Dick Johnson ***** FILE SYSTEM WAS MODIFIED ***** Penguin : Linux version 2.2.5 on an i686 machine (400.59 BogoMips). Warning : It's hard to remain at the trailing edge of technology.
- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/
| |