Message ID | 20210704225433.32029-6-digetx@gmail.com |
---|---|
State | Superseded |
Headers | show |
Series | Add OTG mode support to Tegra USB PHY, SMB347 and Nexus 7 | expand |
On 21-07-05 01:54:26, Dmitry Osipenko wrote: > The HNP work can be re-scheduled while it's still in-fly. This results in > re-initialization of the busy work, resetting the hrtimer's list node of > the work and crashing kernel with null dereference within kernel/timer > once work's timer is expired. It's very easy to trigger this problem by > re-plugging USB cable quickly. Initialize HNP work only once to fix this > trouble. > > Cc: stable@vger.kernel.org > Signed-off-by: Dmitry Osipenko <digetx@gmail.com> Acked-by: Peter Chen <peter.chen@kernel.org> It is better to append kernel dump if you have v4 patchset. Peter > --- > drivers/usb/common/usb-otg-fsm.c | 6 +++++- > include/linux/usb/otg-fsm.h | 1 + > 2 files changed, 6 insertions(+), 1 deletion(-) > > diff --git a/drivers/usb/common/usb-otg-fsm.c b/drivers/usb/common/usb-otg-fsm.c > index 3740cf95560e..0697fde51d00 100644 > --- a/drivers/usb/common/usb-otg-fsm.c > +++ b/drivers/usb/common/usb-otg-fsm.c > @@ -193,7 +193,11 @@ static void otg_start_hnp_polling(struct otg_fsm *fsm) > if (!fsm->host_req_flag) > return; > > - INIT_DELAYED_WORK(&fsm->hnp_polling_work, otg_hnp_polling_work); > + if (!fsm->hnp_work_inited) { > + INIT_DELAYED_WORK(&fsm->hnp_polling_work, otg_hnp_polling_work); > + fsm->hnp_work_inited = true; > + } > + > schedule_delayed_work(&fsm->hnp_polling_work, > msecs_to_jiffies(T_HOST_REQ_POLL)); > } > diff --git a/include/linux/usb/otg-fsm.h b/include/linux/usb/otg-fsm.h > index 3aee78dda16d..784659d4dc99 100644 > --- a/include/linux/usb/otg-fsm.h > +++ b/include/linux/usb/otg-fsm.h > @@ -196,6 +196,7 @@ struct otg_fsm { > struct mutex lock; > u8 *host_req_flag; > struct delayed_work hnp_polling_work; > + bool hnp_work_inited; > bool state_changed; > }; > > -- > 2.32.0 >
diff --git a/drivers/usb/common/usb-otg-fsm.c b/drivers/usb/common/usb-otg-fsm.c index 3740cf95560e..0697fde51d00 100644 --- a/drivers/usb/common/usb-otg-fsm.c +++ b/drivers/usb/common/usb-otg-fsm.c @@ -193,7 +193,11 @@ static void otg_start_hnp_polling(struct otg_fsm *fsm) if (!fsm->host_req_flag) return; - INIT_DELAYED_WORK(&fsm->hnp_polling_work, otg_hnp_polling_work); + if (!fsm->hnp_work_inited) { + INIT_DELAYED_WORK(&fsm->hnp_polling_work, otg_hnp_polling_work); + fsm->hnp_work_inited = true; + } + schedule_delayed_work(&fsm->hnp_polling_work, msecs_to_jiffies(T_HOST_REQ_POLL)); } diff --git a/include/linux/usb/otg-fsm.h b/include/linux/usb/otg-fsm.h index 3aee78dda16d..784659d4dc99 100644 --- a/include/linux/usb/otg-fsm.h +++ b/include/linux/usb/otg-fsm.h @@ -196,6 +196,7 @@ struct otg_fsm { struct mutex lock; u8 *host_req_flag; struct delayed_work hnp_polling_work; + bool hnp_work_inited; bool state_changed; };
The HNP work can be re-scheduled while it's still in-fly. This results in re-initialization of the busy work, resetting the hrtimer's list node of the work and crashing kernel with null dereference within kernel/timer once work's timer is expired. It's very easy to trigger this problem by re-plugging USB cable quickly. Initialize HNP work only once to fix this trouble. Cc: stable@vger.kernel.org Signed-off-by: Dmitry Osipenko <digetx@gmail.com> --- drivers/usb/common/usb-otg-fsm.c | 6 +++++- include/linux/usb/otg-fsm.h | 1 + 2 files changed, 6 insertions(+), 1 deletion(-)