From 82a467b7233af339fba66c7bd84b4aa0b55e87bf Mon Sep 17 00:00:00 2001 From: JP Abgrall Date: Wed, 6 Jul 2011 20:09:38 -0700 Subject: [PATCH] netfitler: xt_qtaguid: add another missing spin_unlock. This time the symptom is caused by tagging the same socket twice without untagging it in between. This would cause it to not unlock, and return. Signed-off-by: JP Abgrall --- net/netfilter/xt_qtaguid.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c index 3cacec0..49ed432 100644 --- a/net/netfilter/xt_qtaguid.c +++ b/net/netfilter/xt_qtaguid.c @@ -997,11 +997,13 @@ static int qtaguid_ctrl_parse(const char *input, int count) sock_tag_entry = get_sock_stat_nl(el_socket->sk); if (!sock_tag_entry) spin_unlock_irqrestore(&sock_tag_list_lock, flags); + /* HERE: The lock is held if there was a matching sock tag entry */ break; default: res = -EINVAL; goto err; } + /* HERE: The lock is held if there was a matching sock tag entry */ /* Process commands */ switch (cmd) { @@ -1009,17 +1011,23 @@ static int qtaguid_ctrl_parse(const char *input, int count) case 't': if (argc < 2) { res = -EINVAL; + /* HERE: The lock is held if there was a matching sock + * tag entry */ goto err_unlock; } if (argc < 3) { acct_tag = 0; } else if (!valid_atag(acct_tag)) { res = -EINVAL; + /* HERE: The lock is held if there was a matching sock + * tag entry */ goto err_unlock; } if (argc < 4) uid = current_fsuid(); if (!sock_tag_entry) { + /* HERE: There is no lock held because there was no + * sock tag entry */ sock_tag_entry = kmalloc(sizeof(*sock_tag_entry), GFP_KERNEL); if (!sock_tag_entry) { @@ -1034,13 +1042,15 @@ static int qtaguid_ctrl_parse(const char *input, int count) uid); spin_lock_irqsave(&sock_tag_list_lock, flags); sock_tag_tree_insert(sock_tag_entry, &sock_tag_tree); - spin_unlock_irqrestore(&sock_tag_list_lock, flags); } else { + /* HERE: The lock is held because there is a matching + * sock tag entry */ /* Just update the acct_tag portion. */ uid_t orig_uid = get_uid_from_tag(sock_tag_entry->tag); sock_tag_entry->tag = combine_atag_with_uid(acct_tag, orig_uid); } + spin_unlock_irqrestore(&sock_tag_list_lock, flags); pr_debug("xt_qtaguid: tag: sock_tag_entry->sk=%p " "...->tag=0x%llx (uid=%u)\n", sock_tag_entry->sk, sock_tag_entry->tag, -- 2.7.4