aboutsummaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorliping.zhang <liping.zhang@spreadtrum.com>2016-01-11 13:31:01 +0800
committerMister Oyster <oysterized@gmail.com>2017-04-17 19:03:51 +0200
commit3859f9754e1e41010e744dec959f5f5bec2e7054 (patch)
tree181061db6a126a9424ba45f711070342ab14bab0 /net
parentd62b0ebbfa1cdb69fefb126430d76b21a717222b (diff)
xt_qtaguid: fix a race condition in if_tag_stat_update
Miss a lock protection in if_tag_stat_update while doing get_iface_entry. So if one CPU is doing iface_stat_create while another CPU is doing if_tag_stat_update, race will happened. Change-Id: Ib8d98e542f4e385685499f5b7bb7354f08654a75 Signed-off-by: Liping Zhang <liping.zhang@spreadtrum.com>
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/xt_qtaguid.c7
1 files changed, 4 insertions, 3 deletions
diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c
index 9d515b3b9..e93a416b3 100644
--- a/net/netfilter/xt_qtaguid.c
+++ b/net/netfilter/xt_qtaguid.c
@@ -1299,11 +1299,12 @@ static void if_tag_stat_update(const char *ifname, uid_t uid,
"uid=%u sk=%p dir=%d proto=%d bytes=%d)\n",
ifname, uid, sk, direction, proto, bytes);
-
+ spin_lock_bh(&iface_stat_list_lock);
iface_entry = get_iface_entry(ifname);
if (!iface_entry) {
pr_err_ratelimited("qtaguid: tag_stat: stat_update() "
"%s not found\n", ifname);
+ spin_unlock_bh(&iface_stat_list_lock);
return;
}
/* It is ok to process data when an iface_entry is inactive */
@@ -1339,8 +1340,7 @@ static void if_tag_stat_update(const char *ifname, uid_t uid,
* {0, uid_tag} will also get updated.
*/
tag_stat_update(tag_stat_entry, direction, proto, bytes);
- spin_unlock_bh(&iface_entry->tag_stat_list_lock);
- return;
+ goto unlock;
}
/* Loop over tag list under this interface for {0,uid_tag} */
@@ -1380,6 +1380,7 @@ static void if_tag_stat_update(const char *ifname, uid_t uid,
tag_stat_update(new_tag_stat, direction, proto, bytes);
unlock:
spin_unlock_bh(&iface_entry->tag_stat_list_lock);
+ spin_unlock_bh(&iface_stat_list_lock);
}
static int iface_netdev_event_handler(struct notifier_block *nb,