Commit baab2ce7 authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller

[NETFILTER]: nfnetlink_{queue,log}: return proper error codes in instance_create

Currently we return EINVAL for "instance exists", "allocation failed" and
"module unloaded below us", which is completely inapproriate.
Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1792bab4
...@@ -128,19 +128,23 @@ static struct nfulnl_instance * ...@@ -128,19 +128,23 @@ static struct nfulnl_instance *
instance_create(u_int16_t group_num, int pid) instance_create(u_int16_t group_num, int pid)
{ {
struct nfulnl_instance *inst; struct nfulnl_instance *inst;
int err;
write_lock_bh(&instances_lock); write_lock_bh(&instances_lock);
if (__instance_lookup(group_num)) { if (__instance_lookup(group_num)) {
inst = NULL; err = -EEXIST;
goto out_unlock; goto out_unlock;
} }
inst = kzalloc(sizeof(*inst), GFP_ATOMIC); inst = kzalloc(sizeof(*inst), GFP_ATOMIC);
if (!inst) if (!inst) {
err = -ENOMEM;
goto out_unlock; goto out_unlock;
}
if (!try_module_get(THIS_MODULE)) { if (!try_module_get(THIS_MODULE)) {
kfree(inst); kfree(inst);
err = -EAGAIN;
goto out_unlock; goto out_unlock;
} }
...@@ -169,7 +173,7 @@ instance_create(u_int16_t group_num, int pid) ...@@ -169,7 +173,7 @@ instance_create(u_int16_t group_num, int pid)
out_unlock: out_unlock:
write_unlock_bh(&instances_lock); write_unlock_bh(&instances_lock);
return NULL; return ERR_PTR(err);
} }
static void __nfulnl_flush(struct nfulnl_instance *inst); static void __nfulnl_flush(struct nfulnl_instance *inst);
...@@ -731,8 +735,8 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, ...@@ -731,8 +735,8 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
inst = instance_create(group_num, inst = instance_create(group_num,
NETLINK_CB(skb).pid); NETLINK_CB(skb).pid);
if (!inst) { if (IS_ERR(inst)) {
ret = -EINVAL; ret = PTR_ERR(inst);
goto out; goto out;
} }
break; break;
......
...@@ -89,16 +89,21 @@ instance_lookup(u_int16_t queue_num) ...@@ -89,16 +89,21 @@ instance_lookup(u_int16_t queue_num)
static struct nfqnl_instance * static struct nfqnl_instance *
instance_create(u_int16_t queue_num, int pid) instance_create(u_int16_t queue_num, int pid)
{ {
struct nfqnl_instance *inst = NULL; struct nfqnl_instance *inst;
unsigned int h; unsigned int h;
int err;
spin_lock(&instances_lock); spin_lock(&instances_lock);
if (instance_lookup(queue_num)) if (instance_lookup(queue_num)) {
err = -EEXIST;
goto out_unlock; goto out_unlock;
}
inst = kzalloc(sizeof(*inst), GFP_ATOMIC); inst = kzalloc(sizeof(*inst), GFP_ATOMIC);
if (!inst) if (!inst) {
err = -ENOMEM;
goto out_unlock; goto out_unlock;
}
inst->queue_num = queue_num; inst->queue_num = queue_num;
inst->peer_pid = pid; inst->peer_pid = pid;
...@@ -109,8 +114,10 @@ instance_create(u_int16_t queue_num, int pid) ...@@ -109,8 +114,10 @@ instance_create(u_int16_t queue_num, int pid)
INIT_LIST_HEAD(&inst->queue_list); INIT_LIST_HEAD(&inst->queue_list);
INIT_RCU_HEAD(&inst->rcu); INIT_RCU_HEAD(&inst->rcu);
if (!try_module_get(THIS_MODULE)) if (!try_module_get(THIS_MODULE)) {
err = -EAGAIN;
goto out_free; goto out_free;
}
h = instance_hashfn(queue_num); h = instance_hashfn(queue_num);
hlist_add_head_rcu(&inst->hlist, &instance_table[h]); hlist_add_head_rcu(&inst->hlist, &instance_table[h]);
...@@ -123,7 +130,7 @@ out_free: ...@@ -123,7 +130,7 @@ out_free:
kfree(inst); kfree(inst);
out_unlock: out_unlock:
spin_unlock(&instances_lock); spin_unlock(&instances_lock);
return NULL; return ERR_PTR(err);
} }
static void nfqnl_flush(struct nfqnl_instance *queue, nfqnl_cmpfn cmpfn, static void nfqnl_flush(struct nfqnl_instance *queue, nfqnl_cmpfn cmpfn,
...@@ -724,8 +731,8 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb, ...@@ -724,8 +731,8 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
goto err_out_unlock; goto err_out_unlock;
} }
queue = instance_create(queue_num, NETLINK_CB(skb).pid); queue = instance_create(queue_num, NETLINK_CB(skb).pid);
if (!queue) { if (IS_ERR(queue)) {
ret = -EINVAL; ret = PTR_ERR(queue);
goto err_out_unlock; goto err_out_unlock;
} }
break; break;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment