aboutsummaryrefslogtreecommitdiff
path: root/net/netfilter
diff options
context:
space:
mode:
authorPatrick Daly <pdaly@codeaurora.org>2014-10-23 18:01:33 -0700
committerPatrick Daly <pdaly@codeaurora.org>2014-10-23 18:54:12 -0700
commite72454e809861616f7c20f5f09b1d05cf3a2361c (patch)
treee94c124823de80ba7f918ac304e0950f12e45e0c /net/netfilter
parent299a62628520a3aa821ee0c542181d3c716ee553 (diff)
downloadqcom-msm-v3.10-e72454e809861616f7c20f5f09b1d05cf3a2361c.tar.gz
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>
Diffstat (limited to 'net/netfilter')
-rw-r--r--net/netfilter/xt_IDLETIMER.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/net/netfilter/xt_IDLETIMER.c b/net/netfilter/xt_IDLETIMER.c
index f6562ba97a9..b21fbd63da6 100644
--- a/net/netfilter/xt_IDLETIMER.c
+++ b/net/netfilter/xt_IDLETIMER.c
@@ -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(&timestamp_lock);
if (!timer->active) {
spin_unlock_bh(&timestamp_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;