summaryrefslogtreecommitdiffstats
path: root/net/netfilter/nfnetlink_queue.c
diff options
context:
space:
mode:
authorPatrick McHardy2007-12-05 10:28:30 +0100
committerDavid S. Miller2008-01-28 23:56:18 +0100
commita3c8e7fd4b36bf6e12fef432cfa8a001dc0b7a26 (patch)
tree59ce4404b88b5b20bd7a6e344d3b3dc77c81ad9e /net/netfilter/nfnetlink_queue.c
parent[NETFILTER]: nfnetlink_queue: avoid unnecessary atomic operation (diff)
downloadkernel-qcow2-linux-a3c8e7fd4b36bf6e12fef432cfa8a001dc0b7a26.tar.gz
kernel-qcow2-linux-a3c8e7fd4b36bf6e12fef432cfa8a001dc0b7a26.tar.xz
kernel-qcow2-linux-a3c8e7fd4b36bf6e12fef432cfa8a001dc0b7a26.zip
[NETFILTER]: nfnetlink_queue: fix checks in nfqnl_recv_config
The peer_pid must be checked in all cases when a queue exists, currently it is not checked if for NFQA_CFG_QUEUE_MAXLEN when a NFQA_CFG_CMD attribute exists in some cases. Same for the queue existance check, which can cause a NULL pointer dereference. Also consistently return -ENODEV for "queue not found". -ENOENT would be better, but that is already used to indicate a queued skb id doesn't exist. Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netfilter/nfnetlink_queue.c')
-rw-r--r--net/netfilter/nfnetlink_queue.c31
1 files changed, 12 insertions, 19 deletions
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c
index bd18de72e3c5..4abf62a6c057 100644
--- a/net/netfilter/nfnetlink_queue.c
+++ b/net/netfilter/nfnetlink_queue.c
@@ -781,8 +781,14 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
QDEBUG("entering for msg %u\n", NFNL_MSG_TYPE(nlh->nlmsg_type));
queue = instance_lookup_get(queue_num);
+ if (queue && queue->peer_pid != NETLINK_CB(skb).pid) {
+ ret = -EPERM;
+ goto out_put;
+ }
+
if (nfqa[NFQA_CFG_CMD]) {
struct nfqnl_msg_config_cmd *cmd;
+
cmd = nla_data(nfqa[NFQA_CFG_CMD]);
QDEBUG("found CFG_CMD\n");
@@ -798,12 +804,6 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
case NFQNL_CFG_CMD_UNBIND:
if (!queue)
return -ENODEV;
-
- if (queue->peer_pid != NETLINK_CB(skb).pid) {
- ret = -EPERM;
- goto out_put;
- }
-
instance_destroy(queue);
break;
case NFQNL_CFG_CMD_PF_BIND:
@@ -820,25 +820,13 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
ret = -EINVAL;
break;
}
- } else {
- if (!queue) {
- QDEBUG("no config command, and no instance ENOENT\n");
- ret = -ENOENT;
- goto out_put;
- }
-
- if (queue->peer_pid != NETLINK_CB(skb).pid) {
- QDEBUG("no config command, and wrong pid\n");
- ret = -EPERM;
- goto out_put;
- }
}
if (nfqa[NFQA_CFG_PARAMS]) {
struct nfqnl_msg_config_params *params;
if (!queue) {
- ret = -ENOENT;
+ ret = -ENODEV;
goto out_put;
}
params = nla_data(nfqa[NFQA_CFG_PARAMS]);
@@ -848,6 +836,11 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
if (nfqa[NFQA_CFG_QUEUE_MAXLEN]) {
__be32 *queue_maxlen;
+
+ if (!queue) {
+ ret = -ENODEV;
+ goto out_put;
+ }
queue_maxlen = nla_data(nfqa[NFQA_CFG_QUEUE_MAXLEN]);
spin_lock_bh(&queue->lock);
queue->queue_maxlen = ntohl(*queue_maxlen);