Hi, Martin,
I am submitting a patch against a bug in ehci/kdb part of code.
Why this patch? I was using 2.6.32 kernel with kdb patch applied, it
looks like EHCI keyboard is supported in kdb, but I ran into an oops
when I attempted to drop into kdb via an EHCI keyboard, the issue can
always be repeated whenever I drop into kdb via a break key on a EHCI
keyboard. The error message indicates qh_completions_kdb+0x1c/0x420
leads to a NULL pointer dereference, so I disassembled the function,
[2]kdb> id qh_completions_kdb
0xffffffff81376d70 qh_completions_kdb: push %rbp
0xffffffff81376d71 qh_completions_kdb+0x1: mov %rsp,%rbp
0xffffffff81376d74 qh_completions_kdb+0x4: push %r15
0xffffffff81376d76 qh_completions_kdb+0x6: push %r14
0xffffffff81376d78 qh_completions_kdb+0x8: mov %rsi,%r14
0xffffffff81376d7b qh_completions_kdb+0xb: push %r13
0xffffffff81376d7d qh_completions_kdb+0xd: push %r12
0xffffffff81376d7f qh_completions_kdb+0xf: push %rbx
0xffffffff81376d80 qh_completions_kdb+0x10: sub $0x48,%rsp
0xffffffff81376d84 qh_completions_kdb+0x14: mov
%rdi,0xffffffffffffff98(%rbp)
0xffffffff81376d88 qh_completions_kdb+0x18: mov
%rdx,0xffffffffffffff90(%rbp)
0xffffffff81376d8c qh_completions_kdb+0x1c: mov 0x28(%rsi),%rax
0xffffffff81376d90 qh_completions_kdb+0x20: test %rsi,%rsi
0xffffffff81376d93 qh_completions_kdb+0x23: mov
%rax,0xffffffffffffffa8(%rbp)
0xffffffff81376d97 qh_completions_kdb+0x27: mov (%rsi),%rdx
0xffffffff81376d9a qh_completions_kdb+0x2a: mov
%rdx,0xffffffffffffffc0(%rbp)
0xffffffff81376d9e qh_completions_kdb+0x2e: je
0xffffffff81376f30 qh_completions_kdb+0x1c0
0xffffffff81376da4 qh_completions_kdb+0x34: cmpq
$0x0,0xffffffffffffff90(%rbp)
0xffffffff81376da9 qh_completions_kdb+0x39: je
0xffffffff81376f30 qh_completions_kdb+0x1c0
0xffffffff81376daf qh_completions_kdb+0x3f: lea 0x18(%rsi),%rax
0xffffffff81376db3 qh_completions_kdb+0x43: mov
%rax,0xffffffffffffffa0(%rbp)
0xffffffff81376db7 qh_completions_kdb+0x47: cmp 0x18(%rsi),%rax
qh_completions_kdb+0x1c/0x420 equals to mov 0x28(%rsi),%rax,
actually this instruction corresponds to line 589 of function
qh_completions_kdb().
The situation here is, before we invoke qh_completions_kdb(), we
should ensure every parameters are valid. Although line 599~line601
are intending to do the verify work, it might be too late, the truth
is, line 589 may lead to an oops, because qh->dummy means NULL pointer
dereference assuming qh is NULL.
587 qh_completions_kdb(struct ehci_hcd *ehci, struct ehci_qh *qh,
struct urb *kdburb)
588 {
589 struct ehci_qtd *last = NULL, *end = qh->dummy;
590 struct list_head *entry, *tmp;
591 int last_status = -EINPROGRESS;
592 int stopped;
593 unsigned count = 0;
594 int do_status = 0;
595 u8 state;
596 u32 halt = HALT_BIT(ehci);
597 struct ehci_qh_hw *hw = qh->hw;
598
599 /* verify params are valid */
600 if (!qh || !kdburb)
601 return 0;
So I wrote following patch to fix this issue, namely, do the verify
work before we enter into qh_completions_kdb().
Signed-off-by: Jason Xiao <[email protected]>
---
diff -purN linux-2.6.32.a/drivers/usb/host/ehci-hcd.c
linux-2.6.32/drivers/usb/host/ehci-hcd.c
--- linux-2.6.32.a/drivers/usb/host/ehci-hcd.c 2010-01-23
00:57:30.000000000 +0800
+++ linux-2.6.32/drivers/usb/host/ehci-hcd.c 2010-01-23
01:00:58.000000000 +0800
@@ -1097,7 +1097,7 @@ ehci_kdb_poll_char(struct urb *urb)
struct ehci_hcd *ehci;
/* just to make sure */
- if (!urb || !urb->dev || !urb->dev->bus)
+ if (!urb || !urb->dev || !urb->dev->bus || !urb->hcpriv)
return -1;
ehci = (struct ehci_hcd *) hcd_to_ehci(bus_to_hcd(urb->dev->bus));
_______________________________________________
kdb mailing list
[email protected]
http://oss.sgi.com/mailman/listinfo/kdb