diff options
| author | liping.zhang <liping.zhang@spreadtrum.com> | 2016-01-11 13:31:01 +0800 |
|---|---|---|
| committer | Mister Oyster <oysterized@gmail.com> | 2017-04-17 19:03:51 +0200 |
| commit | 3859f9754e1e41010e744dec959f5f5bec2e7054 (patch) | |
| tree | 181061db6a126a9424ba45f711070342ab14bab0 /net | |
| parent | d62b0ebbfa1cdb69fefb126430d76b21a717222b (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.c | 7 |
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, |
