Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f96eb74d authored by Subash Abhinov Kasiviswanathan's avatar Subash Abhinov Kasiviswanathan Committed by Sean Tranchetti
Browse files

nf: IDLETIMER: Fix possible use before initialization in idletimer_resume



idletimer_resume() assumes that the PM_SUSPEND_PREPARE notifier is sent
before PM_POST_SUSPEND so that timer->last_suspend_time is initialized.
However, it is possible for PM_POST_SUSPEND 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.

CRs-Fixed: 2333588
Change-Id: I95328b0ac85dba819ff9cef751c3d07300c232f1
Signed-off-by: default avatarSubash Abhinov Kasiviswanathan <subashab@codeaurora.org>
parent df485206
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -76,6 +76,7 @@ struct idletimer_tg {
	bool send_nl_msg;
	bool active;
	uid_t uid;
	bool suspend_time_valid;
};

static LIST_HEAD(idletimer_tg_list);
@@ -245,8 +246,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(&timestamp_lock);
		if (!timer->active) {
			spin_unlock_bh(&timestamp_lock);
@@ -281,7 +287,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;