summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJP Abgrall <jpa@google.com>2011-07-06 20:09:38 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:38:47 -0800
commitd950bc8b0857b6c77950abf646294592445f67f7 (patch)
tree516e8a067a00992e34bcbd9c09acdad01eff3e52
parent9881dd84794835f80622e90575778f2eaf9a7b99 (diff)
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 <jpa@google.com>
-rw-r--r--net/netfilter/xt_qtaguid.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/net/netfilter/xt_qtaguid.c b/net/netfilter/xt_qtaguid.c
index 3cacec07fbf7..49ed432d793c 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,