From: liping.zhang Date: Mon, 11 Jan 2016 05:31:01 +0000 (+0800) Subject: xt_qtaguid: fix a race condition in if_tag_stat_update X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=c500a829929382de25899ec279d243b90a90e0ca;p=GitHub%2Fexynos8895%2Fandroid_kernel_samsung_universal8895.git 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 --- diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c index 62ddd6cd1ee8..04bb081adde8 100644 --- a/net/netfilter/xt_qtaguid.c +++ b/net/netfilter/xt_qtaguid.c @@ -1291,11 +1291,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: iface_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 */ @@ -1331,8 +1332,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} */ @@ -1372,6 +1372,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,