diff options
| author | Patrick McHardy <kaber@trash.net> | 2008-03-10 19:44:13 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2008-03-10 19:44:13 -0400 |
| commit | b7047a1c886386b10a103b4fea26678db8b57832 (patch) | |
| tree | 7bc7d14b5a71470f774f190d7809cca45e8bef8f | |
| parent | 019f692ea719a2da17606511d2648b8cc1762268 (diff) | |
[NETFILTER]: nfnetlink_log: fix EPERM when binding/unbinding and instance 0 exists
When binding or unbinding to an address family, the res_id is usually set
to zero. When logging instance 0 already exists and is owned by a different
process, this makes nfunl_recv_config return -EPERM without performing
the bind operation.
Since no operation on the foreign logging instance itself was requested,
this is incorrect. Move bind/unbind commands before the queue instance
permissions checks.
Also remove an incorrect comment.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | net/netfilter/nfnetlink_log.c | 30 |
1 files changed, 16 insertions, 14 deletions
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c index c6802c0d6ed8..bf3f19b21fe4 100644 --- a/net/netfilter/nfnetlink_log.c +++ b/net/netfilter/nfnetlink_log.c | |||
| @@ -702,20 +702,30 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, | |||
| 702 | struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); | 702 | struct nfgenmsg *nfmsg = NLMSG_DATA(nlh); |
| 703 | u_int16_t group_num = ntohs(nfmsg->res_id); | 703 | u_int16_t group_num = ntohs(nfmsg->res_id); |
| 704 | struct nfulnl_instance *inst; | 704 | struct nfulnl_instance *inst; |
| 705 | struct nfulnl_msg_config_cmd *cmd = NULL; | ||
| 705 | int ret = 0; | 706 | int ret = 0; |
| 706 | 707 | ||
| 708 | if (nfula[NFULA_CFG_CMD]) { | ||
| 709 | u_int8_t pf = nfmsg->nfgen_family; | ||
| 710 | cmd = nla_data(nfula[NFULA_CFG_CMD]); | ||
| 711 | |||
| 712 | /* Commands without queue context */ | ||
| 713 | switch (cmd->command) { | ||
| 714 | case NFULNL_CFG_CMD_PF_BIND: | ||
| 715 | return nf_log_register(pf, &nfulnl_logger); | ||
| 716 | case NFULNL_CFG_CMD_PF_UNBIND: | ||
| 717 | nf_log_unregister_pf(pf); | ||
| 718 | return 0; | ||
| 719 | } | ||
| 720 | } | ||
| 721 | |||
| 707 | inst = instance_lookup_get(group_num); | 722 | inst = instance_lookup_get(group_num); |
| 708 | if (inst && inst->peer_pid != NETLINK_CB(skb).pid) { | 723 | if (inst && inst->peer_pid != NETLINK_CB(skb).pid) { |
| 709 | ret = -EPERM; | 724 | ret = -EPERM; |
| 710 | goto out_put; | 725 | goto out_put; |
| 711 | } | 726 | } |
| 712 | 727 | ||
| 713 | if (nfula[NFULA_CFG_CMD]) { | 728 | if (cmd != NULL) { |
| 714 | u_int8_t pf = nfmsg->nfgen_family; | ||
| 715 | struct nfulnl_msg_config_cmd *cmd; | ||
| 716 | |||
| 717 | cmd = nla_data(nfula[NFULA_CFG_CMD]); | ||
| 718 | |||
| 719 | switch (cmd->command) { | 729 | switch (cmd->command) { |
| 720 | case NFULNL_CFG_CMD_BIND: | 730 | case NFULNL_CFG_CMD_BIND: |
| 721 | if (inst) { | 731 | if (inst) { |
| @@ -738,14 +748,6 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb, | |||
| 738 | 748 | ||
| 739 | instance_destroy(inst); | 749 | instance_destroy(inst); |
| 740 | goto out; | 750 | goto out; |
| 741 | case NFULNL_CFG_CMD_PF_BIND: | ||
| 742 | ret = nf_log_register(pf, &nfulnl_logger); | ||
| 743 | break; | ||
| 744 | case NFULNL_CFG_CMD_PF_UNBIND: | ||
| 745 | /* This is a bug and a feature. We cannot unregister | ||
| 746 | * other handlers, like nfnetlink_inst can */ | ||
| 747 | nf_log_unregister_pf(pf); | ||
| 748 | break; | ||
| 749 | default: | 751 | default: |
| 750 | ret = -ENOTSUPP; | 752 | ret = -ENOTSUPP; |
| 751 | break; | 753 | break; |
