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

[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: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e48b9b2f
...@@ -781,8 +781,14 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb, ...@@ -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)); QDEBUG("entering for msg %u\n", NFNL_MSG_TYPE(nlh->nlmsg_type));
queue = instance_lookup_get(queue_num); 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]) { if (nfqa[NFQA_CFG_CMD]) {
struct nfqnl_msg_config_cmd *cmd; struct nfqnl_msg_config_cmd *cmd;
cmd = nla_data(nfqa[NFQA_CFG_CMD]); cmd = nla_data(nfqa[NFQA_CFG_CMD]);
QDEBUG("found CFG_CMD\n"); QDEBUG("found CFG_CMD\n");
...@@ -798,12 +804,6 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb, ...@@ -798,12 +804,6 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
case NFQNL_CFG_CMD_UNBIND: case NFQNL_CFG_CMD_UNBIND:
if (!queue) if (!queue)
return -ENODEV; return -ENODEV;
if (queue->peer_pid != NETLINK_CB(skb).pid) {
ret = -EPERM;
goto out_put;
}
instance_destroy(queue); instance_destroy(queue);
break; break;
case NFQNL_CFG_CMD_PF_BIND: case NFQNL_CFG_CMD_PF_BIND:
...@@ -820,25 +820,13 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb, ...@@ -820,25 +820,13 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
ret = -EINVAL; ret = -EINVAL;
break; 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]) { if (nfqa[NFQA_CFG_PARAMS]) {
struct nfqnl_msg_config_params *params; struct nfqnl_msg_config_params *params;
if (!queue) { if (!queue) {
ret = -ENOENT; ret = -ENODEV;
goto out_put; goto out_put;
} }
params = nla_data(nfqa[NFQA_CFG_PARAMS]); params = nla_data(nfqa[NFQA_CFG_PARAMS]);
...@@ -848,6 +836,11 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb, ...@@ -848,6 +836,11 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
if (nfqa[NFQA_CFG_QUEUE_MAXLEN]) { if (nfqa[NFQA_CFG_QUEUE_MAXLEN]) {
__be32 *queue_maxlen; __be32 *queue_maxlen;
if (!queue) {
ret = -ENODEV;
goto out_put;
}
queue_maxlen = nla_data(nfqa[NFQA_CFG_QUEUE_MAXLEN]); queue_maxlen = nla_data(nfqa[NFQA_CFG_QUEUE_MAXLEN]);
spin_lock_bh(&queue->lock); spin_lock_bh(&queue->lock);
queue->queue_maxlen = ntohl(*queue_maxlen); queue->queue_maxlen = ntohl(*queue_maxlen);
......
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