|
@@ -518,13 +518,11 @@ static struct tag_ref *get_tag_ref(tag_t full_tag,
|
|
|
|
|
|
|
|
DR_DEBUG("qtaguid: get_tag_ref(0x%llx)\n",
|
|
DR_DEBUG("qtaguid: get_tag_ref(0x%llx)\n",
|
|
|
full_tag);
|
|
full_tag);
|
|
|
- spin_lock_bh(&uid_tag_data_tree_lock);
|
|
|
|
|
tr_entry = lookup_tag_ref(full_tag, &utd_entry);
|
|
tr_entry = lookup_tag_ref(full_tag, &utd_entry);
|
|
|
BUG_ON(IS_ERR_OR_NULL(utd_entry));
|
|
BUG_ON(IS_ERR_OR_NULL(utd_entry));
|
|
|
if (!tr_entry)
|
|
if (!tr_entry)
|
|
|
tr_entry = new_tag_ref(full_tag, utd_entry);
|
|
tr_entry = new_tag_ref(full_tag, utd_entry);
|
|
|
|
|
|
|
|
- spin_unlock_bh(&uid_tag_data_tree_lock);
|
|
|
|
|
if (utd_res)
|
|
if (utd_res)
|
|
|
*utd_res = utd_entry;
|
|
*utd_res = utd_entry;
|
|
|
DR_DEBUG("qtaguid: get_tag_ref(0x%llx) utd=%p tr=%p\n",
|
|
DR_DEBUG("qtaguid: get_tag_ref(0x%llx) utd=%p tr=%p\n",
|
|
@@ -2036,6 +2034,7 @@ static int ctrl_cmd_delete(const char *input)
|
|
|
|
|
|
|
|
/* Delete socket tags */
|
|
/* Delete socket tags */
|
|
|
spin_lock_bh(&sock_tag_list_lock);
|
|
spin_lock_bh(&sock_tag_list_lock);
|
|
|
|
|
+ spin_lock_bh(&uid_tag_data_tree_lock);
|
|
|
node = rb_first(&sock_tag_tree);
|
|
node = rb_first(&sock_tag_tree);
|
|
|
while (node) {
|
|
while (node) {
|
|
|
st_entry = rb_entry(node, struct sock_tag, sock_node);
|
|
st_entry = rb_entry(node, struct sock_tag, sock_node);
|
|
@@ -2065,6 +2064,7 @@ static int ctrl_cmd_delete(const char *input)
|
|
|
list_del(&st_entry->list);
|
|
list_del(&st_entry->list);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+ spin_unlock_bh(&uid_tag_data_tree_lock);
|
|
|
spin_unlock_bh(&sock_tag_list_lock);
|
|
spin_unlock_bh(&sock_tag_list_lock);
|
|
|
|
|
|
|
|
sock_tag_tree_erase(&st_to_free_tree);
|
|
sock_tag_tree_erase(&st_to_free_tree);
|
|
@@ -2274,10 +2274,12 @@ static int ctrl_cmd_tag(const char *input)
|
|
|
full_tag = combine_atag_with_uid(acct_tag, uid_int);
|
|
full_tag = combine_atag_with_uid(acct_tag, uid_int);
|
|
|
|
|
|
|
|
spin_lock_bh(&sock_tag_list_lock);
|
|
spin_lock_bh(&sock_tag_list_lock);
|
|
|
|
|
+ spin_lock_bh(&uid_tag_data_tree_lock);
|
|
|
sock_tag_entry = get_sock_stat_nl(el_socket->sk);
|
|
sock_tag_entry = get_sock_stat_nl(el_socket->sk);
|
|
|
tag_ref_entry = get_tag_ref(full_tag, &uid_tag_data_entry);
|
|
tag_ref_entry = get_tag_ref(full_tag, &uid_tag_data_entry);
|
|
|
if (IS_ERR(tag_ref_entry)) {
|
|
if (IS_ERR(tag_ref_entry)) {
|
|
|
res = PTR_ERR(tag_ref_entry);
|
|
res = PTR_ERR(tag_ref_entry);
|
|
|
|
|
+ spin_unlock_bh(&uid_tag_data_tree_lock);
|
|
|
spin_unlock_bh(&sock_tag_list_lock);
|
|
spin_unlock_bh(&sock_tag_list_lock);
|
|
|
goto err_put;
|
|
goto err_put;
|
|
|
}
|
|
}
|
|
@@ -2311,15 +2313,19 @@ static int ctrl_cmd_tag(const char *input)
|
|
|
pr_err("qtaguid: ctrl_tag(%s): "
|
|
pr_err("qtaguid: ctrl_tag(%s): "
|
|
|
"socket tag alloc failed\n",
|
|
"socket tag alloc failed\n",
|
|
|
input);
|
|
input);
|
|
|
|
|
+ BUG_ON(tag_ref_entry->num_sock_tags <= 0);
|
|
|
|
|
+ tag_ref_entry->num_sock_tags--;
|
|
|
|
|
+ free_tag_ref_from_utd_entry(tag_ref_entry,
|
|
|
|
|
+ uid_tag_data_entry);
|
|
|
|
|
+ spin_unlock_bh(&uid_tag_data_tree_lock);
|
|
|
spin_unlock_bh(&sock_tag_list_lock);
|
|
spin_unlock_bh(&sock_tag_list_lock);
|
|
|
res = -ENOMEM;
|
|
res = -ENOMEM;
|
|
|
- goto err_tag_unref_put;
|
|
|
|
|
|
|
+ goto err_put;
|
|
|
}
|
|
}
|
|
|
sock_tag_entry->sk = el_socket->sk;
|
|
sock_tag_entry->sk = el_socket->sk;
|
|
|
sock_tag_entry->socket = el_socket;
|
|
sock_tag_entry->socket = el_socket;
|
|
|
sock_tag_entry->pid = current->tgid;
|
|
sock_tag_entry->pid = current->tgid;
|
|
|
sock_tag_entry->tag = combine_atag_with_uid(acct_tag, uid_int);
|
|
sock_tag_entry->tag = combine_atag_with_uid(acct_tag, uid_int);
|
|
|
- spin_lock_bh(&uid_tag_data_tree_lock);
|
|
|
|
|
pqd_entry = proc_qtu_data_tree_search(
|
|
pqd_entry = proc_qtu_data_tree_search(
|
|
|
&proc_qtu_data_tree, current->tgid);
|
|
&proc_qtu_data_tree, current->tgid);
|
|
|
/*
|
|
/*
|
|
@@ -2337,11 +2343,11 @@ static int ctrl_cmd_tag(const char *input)
|
|
|
else
|
|
else
|
|
|
list_add(&sock_tag_entry->list,
|
|
list_add(&sock_tag_entry->list,
|
|
|
&pqd_entry->sock_tag_list);
|
|
&pqd_entry->sock_tag_list);
|
|
|
- spin_unlock_bh(&uid_tag_data_tree_lock);
|
|
|
|
|
|
|
|
|
|
sock_tag_tree_insert(sock_tag_entry, &sock_tag_tree);
|
|
sock_tag_tree_insert(sock_tag_entry, &sock_tag_tree);
|
|
|
atomic64_inc(&qtu_events.sockets_tagged);
|
|
atomic64_inc(&qtu_events.sockets_tagged);
|
|
|
}
|
|
}
|
|
|
|
|
+ spin_unlock_bh(&uid_tag_data_tree_lock);
|
|
|
spin_unlock_bh(&sock_tag_list_lock);
|
|
spin_unlock_bh(&sock_tag_list_lock);
|
|
|
/* We keep the ref to the socket (file) until it is untagged */
|
|
/* We keep the ref to the socket (file) until it is untagged */
|
|
|
CT_DEBUG("qtaguid: ctrl_tag(%s): done st@%p ...->f_count=%ld\n",
|
|
CT_DEBUG("qtaguid: ctrl_tag(%s): done st@%p ...->f_count=%ld\n",
|
|
@@ -2349,10 +2355,6 @@ static int ctrl_cmd_tag(const char *input)
|
|
|
atomic_long_read(&el_socket->file->f_count));
|
|
atomic_long_read(&el_socket->file->f_count));
|
|
|
return 0;
|
|
return 0;
|
|
|
|
|
|
|
|
-err_tag_unref_put:
|
|
|
|
|
- BUG_ON(tag_ref_entry->num_sock_tags <= 0);
|
|
|
|
|
- tag_ref_entry->num_sock_tags--;
|
|
|
|
|
- free_tag_ref_from_utd_entry(tag_ref_entry, uid_tag_data_entry);
|
|
|
|
|
err_put:
|
|
err_put:
|
|
|
CT_DEBUG("qtaguid: ctrl_tag(%s): done. ...->f_count=%ld\n",
|
|
CT_DEBUG("qtaguid: ctrl_tag(%s): done. ...->f_count=%ld\n",
|
|
|
input, atomic_long_read(&el_socket->file->f_count) - 1);
|
|
input, atomic_long_read(&el_socket->file->f_count) - 1);
|
|
@@ -2547,7 +2549,7 @@ static int pp_stats_line(struct seq_file *m, struct tag_stat *ts_entry,
|
|
|
uid_t stat_uid = get_uid_from_tag(tag);
|
|
uid_t stat_uid = get_uid_from_tag(tag);
|
|
|
struct proc_print_info *ppi = m->private;
|
|
struct proc_print_info *ppi = m->private;
|
|
|
/* Detailed tags are not available to everybody */
|
|
/* Detailed tags are not available to everybody */
|
|
|
- if (!can_read_other_uid_stats(make_kuid(&init_user_ns,stat_uid))) {
|
|
|
|
|
|
|
+ if (!can_read_other_uid_stats(make_kuid(&init_user_ns, stat_uid))) {
|
|
|
CT_DEBUG("qtaguid: stats line: "
|
|
CT_DEBUG("qtaguid: stats line: "
|
|
|
"%s 0x%llx %u: insufficient priv "
|
|
"%s 0x%llx %u: insufficient priv "
|
|
|
"from pid=%u tgid=%u uid=%u stats.gid=%u\n",
|
|
"from pid=%u tgid=%u uid=%u stats.gid=%u\n",
|