nf: IDLETIMER: Fix possible use before initialization in idletimer_resume
idletimer_resume() assumes that the PM_SUSPEND_PREPARE notifier is sent before PM_POST_PREPARE so that timer->last_suspend_time is initialized. However, it is posible for PM_POST_PREPARE to be sent first if there is an error returned from another driver's PM_SUSPEND_PREPARE notifier. Add a flag indicating whether the current value of timer->last_suspend is valid. Detected with CONFIG_SLUB_DEBUG & CONFIG_DEBUG_SPINLOCK in arm64. The timestamp lock is held for more than a minute while set_normalized_timespec() proceses the poisoned timer->last_suspend_time argument. Change-Id: I95328b0ac85dba819ff9cef751c3d07300c232f1 CRs-fixed: 745178 Signed-off-by: Patrick Daly <pdaly@codeaurora.org>
This commit is contained in:
parent
299a626285
commit
e72454e809
|
@ -73,6 +73,7 @@ struct idletimer_tg {
|
|||
bool work_pending;
|
||||
bool send_nl_msg;
|
||||
bool active;
|
||||
bool suspend_time_valid;
|
||||
};
|
||||
|
||||
static LIST_HEAD(idletimer_tg_list);
|
||||
|
@ -230,8 +231,13 @@ static int idletimer_resume(struct notifier_block *notifier,
|
|||
switch (pm_event) {
|
||||
case PM_SUSPEND_PREPARE:
|
||||
get_monotonic_boottime(&timer->last_suspend_time);
|
||||
timer->suspend_time_valid = true;
|
||||
break;
|
||||
case PM_POST_SUSPEND:
|
||||
if (!timer->suspend_time_valid)
|
||||
break;
|
||||
timer->suspend_time_valid = false;
|
||||
|
||||
spin_lock_bh(×tamp_lock);
|
||||
if (!timer->active) {
|
||||
spin_unlock_bh(×tamp_lock);
|
||||
|
@ -266,7 +272,7 @@ static int idletimer_tg_create(struct idletimer_tg_info *info)
|
|||
{
|
||||
int ret;
|
||||
|
||||
info->timer = kmalloc(sizeof(*info->timer), GFP_KERNEL);
|
||||
info->timer = kzalloc(sizeof(*info->timer), GFP_KERNEL);
|
||||
if (!info->timer) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
|
|
Loading…
Reference in New Issue