diff options
author | Patrick McHardy <kaber@trash.net> | 2007-12-05 04:28:30 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 17:56:18 -0500 |
commit | a3c8e7fd4b36bf6e12fef432cfa8a001dc0b7a26 (patch) | |
tree | 59ce4404b88b5b20bd7a6e344d3b3dc77c81ad9e /net/netfilter | |
parent | e48b9b2fb383879a5d758d526b5eb8de4509f467 (diff) |
[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')
-rw-r--r-- | net/netfilter/nfnetlink_queue.c | 31 |
1 files changed, 12 insertions, 19 deletions
diff --git a/net/netfilter/nfnetlink_queue.c b/net/netfilter/nfnetlink_queue.c index bd18de72e3c..4abf62a6c05 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, | |||
781 | QDEBUG("entering for msg %u\n", NFNL_MSG_TYPE(nlh->nlmsg_type)); | 781 | QDEBUG("entering for msg %u\n", NFNL_MSG_TYPE(nlh->nlmsg_type)); |
782 | 782 | ||
783 | queue = instance_lookup_get(queue_num); | 783 | queue = instance_lookup_get(queue_num); |
784 | if (queue && queue->peer_pid != NETLINK_CB(skb).pid) { | ||
785 | ret = -EPERM; | ||
786 | goto out_put; | ||
787 | } | ||
788 | |||
784 | if (nfqa[NFQA_CFG_CMD]) { | 789 | if (nfqa[NFQA_CFG_CMD]) { |
785 | struct nfqnl_msg_config_cmd *cmd; | 790 | struct nfqnl_msg_config_cmd *cmd; |
791 | |||
786 | cmd = nla_data(nfqa[NFQA_CFG_CMD]); | 792 | cmd = nla_data(nfqa[NFQA_CFG_CMD]); |
787 | QDEBUG("found CFG_CMD\n"); | 793 | QDEBUG("found CFG_CMD\n"); |
788 | 794 | ||
@@ -798,12 +804,6 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb, | |||
798 | case NFQNL_CFG_CMD_UNBIND: | 804 | case NFQNL_CFG_CMD_UNBIND: |
799 | if (!queue) | 805 | if (!queue) |
800 | return -ENODEV; | 806 | return -ENODEV; |
801 | |||
802 | if (queue->peer_pid != NETLINK_CB(skb).pid) { | ||
803 | ret = -EPERM; | ||
804 | goto out_put; | ||
805 | } | ||
806 | |||
807 | instance_destroy(queue); | 807 | instance_destroy(queue); |
808 | break; | 808 | break; |
809 | case NFQNL_CFG_CMD_PF_BIND: | 809 | case NFQNL_CFG_CMD_PF_BIND: |
@@ -820,25 +820,13 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb, | |||
820 | ret = -EINVAL; | 820 | ret = -EINVAL; |
821 | break; | 821 | break; |
822 | } | 822 | } |
823 | } else { | ||
824 | if (!queue) { | ||
825 | QDEBUG("no config command, and no instance ENOENT\n"); | ||
826 | ret = -ENOENT; | ||
827 | goto out_put; | ||
828 | } | ||
829 | |||
830 | if (queue->peer_pid != NETLINK_CB(skb).pid) { | ||
831 | QDEBUG("no config command, and wrong pid\n"); | ||
832 | ret = -EPERM; | ||
833 | goto out_put; | ||
834 | } | ||
835 | } | 823 | } |
836 | 824 | ||
837 | if (nfqa[NFQA_CFG_PARAMS]) { | 825 | if (nfqa[NFQA_CFG_PARAMS]) { |
838 | struct nfqnl_msg_config_params *params; | 826 | struct nfqnl_msg_config_params *params; |
839 | 827 | ||
840 | if (!queue) { | 828 | if (!queue) { |
841 | ret = -ENOENT; | 829 | ret = -ENODEV; |
842 | goto out_put; | 830 | goto out_put; |
843 | } | 831 | } |
844 | params = nla_data(nfqa[NFQA_CFG_PARAMS]); | 832 | params = nla_data(nfqa[NFQA_CFG_PARAMS]); |
@@ -848,6 +836,11 @@ nfqnl_recv_config(struct sock *ctnl, struct sk_buff *skb, | |||
848 | 836 | ||
849 | if (nfqa[NFQA_CFG_QUEUE_MAXLEN]) { | 837 | if (nfqa[NFQA_CFG_QUEUE_MAXLEN]) { |
850 | __be32 *queue_maxlen; | 838 | __be32 *queue_maxlen; |
839 | |||
840 | if (!queue) { | ||
841 | ret = -ENODEV; | ||
842 | goto out_put; | ||
843 | } | ||
851 | queue_maxlen = nla_data(nfqa[NFQA_CFG_QUEUE_MAXLEN]); | 844 | queue_maxlen = nla_data(nfqa[NFQA_CFG_QUEUE_MAXLEN]); |
852 | spin_lock_bh(&queue->lock); | 845 | spin_lock_bh(&queue->lock); |
853 | queue->queue_maxlen = ntohl(*queue_maxlen); | 846 | queue->queue_maxlen = ntohl(*queue_maxlen); |