[NETFILTER]: attribute count is an attribute of message type, not subsytem
authorHarald Welte <laforge@netfilter.org>
Wed, 10 Aug 2005 03:03:40 +0000 (20:03 -0700)
committerDavid S. Miller <davem@sunset.davemloft.net>
Mon, 29 Aug 2005 22:39:14 +0000 (15:39 -0700)
Prior to this patch, every nfnetlink subsystem had to specify it's
attribute count.  However, in reality the attribute count depends on
the message type within the subsystem, not the subsystem itself.  This
patch moves 'attr_count' from 'struct nfnetlink_subsys' into
nfnl_callback to fix this.

Signed-off-by: Harald Welte <laforge@netfilter.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/linux/netfilter/nfnetlink.h
net/ipv4/netfilter/ip_conntrack_netlink.c
net/netfilter/nfnetlink.c
net/netfilter/nfnetlink_log.c
net/netfilter/nfnetlink_queue.c

index 561f9df288088d32299c58be31fad8a115f203b9..b0feb2374079b5b0ec7aa4c93d05a8fa820a2b61 100644 (file)
@@ -85,9 +85,10 @@ struct nfgenmsg {
 
 struct nfnl_callback
 {
-       kernel_cap_t cap_required; /* capabilities required for this msg */
        int (*call)(struct sock *nl, struct sk_buff *skb, 
                struct nlmsghdr *nlh, struct nfattr *cda[], int *errp);
+       kernel_cap_t cap_required; /* capabilities required for this msg */
+       u_int16_t attr_count;   /* number of nfattr's */
 };
 
 struct nfnetlink_subsystem
@@ -95,7 +96,6 @@ struct nfnetlink_subsystem
        const char *name;
        __u8 subsys_id;         /* nfnetlink subsystem ID */
        __u8 cb_count;          /* number of callbacks */
-       u_int32_t attr_count;   /* number of nfattr's */
        struct nfnl_callback *cb; /* callback for individual types */
 };
 
index 23f18f6a5535a9321c320c5b6a3df553f2ba74a1..53d98974dcf038c0288ea269573c05b2a9772f7b 100644 (file)
@@ -1484,21 +1484,28 @@ static struct notifier_block ctnl_notifier_exp = {
 
 static struct nfnl_callback ctnl_cb[IPCTNL_MSG_MAX] = {
        [IPCTNL_MSG_CT_NEW]             = { .call = ctnetlink_new_conntrack,
+                                           .attr_count = CTA_MAX,
                                            .cap_required = CAP_NET_ADMIN },
        [IPCTNL_MSG_CT_GET]             = { .call = ctnetlink_get_conntrack,
+                                           .attr_count = CTA_MAX,
                                            .cap_required = CAP_NET_ADMIN },
        [IPCTNL_MSG_CT_DELETE]          = { .call = ctnetlink_del_conntrack,
+                                           .attr_count = CTA_MAX,
                                            .cap_required = CAP_NET_ADMIN },
        [IPCTNL_MSG_CT_GET_CTRZERO]     = { .call = ctnetlink_get_conntrack,
+                                           .attr_count = CTA_MAX,
                                            .cap_required = CAP_NET_ADMIN },
 };
 
 static struct nfnl_callback ctnl_exp_cb[IPCTNL_MSG_MAX] = {
        [IPCTNL_MSG_EXP_GET]            = { .call = ctnetlink_get_expect,
+                                           .attr_count = CTA_EXPECT_MAX,
                                            .cap_required = CAP_NET_ADMIN },
        [IPCTNL_MSG_EXP_NEW]            = { .call = ctnetlink_new_expect,
+                                           .attr_count = CTA_EXPECT_MAX,
                                            .cap_required = CAP_NET_ADMIN },
        [IPCTNL_MSG_EXP_DELETE]         = { .call = ctnetlink_del_expect,
+                                           .attr_count = CTA_EXPECT_MAX,
                                            .cap_required = CAP_NET_ADMIN },
 };
 
@@ -1506,7 +1513,6 @@ static struct nfnetlink_subsystem ctnl_subsys = {
        .name                           = "conntrack",
        .subsys_id                      = NFNL_SUBSYS_CTNETLINK,
        .cb_count                       = IPCTNL_MSG_MAX,
-       .attr_count                     = CTA_MAX,
        .cb                             = ctnl_cb,
 };
 
@@ -1514,7 +1520,6 @@ static struct nfnetlink_subsystem ctnl_exp_subsys = {
        .name                           = "conntrack_expect",
        .subsys_id                      = NFNL_SUBSYS_CTNETLINK_EXP,
        .cb_count                       = IPCTNL_MSG_EXP_MAX,
-       .attr_count                     = CTA_MAX,
        .cb                             = ctnl_exp_cb,
 };
 
index 30b25f47f7cc149ca9f74a7686c8ec97f9585715..578e4fe40945aa600e6f5bfb381cc4830c186181 100644 (file)
@@ -155,8 +155,18 @@ nfnetlink_check_attributes(struct nfnetlink_subsystem *subsys,
                           struct nlmsghdr *nlh, struct nfattr *cda[])
 {
        int min_len;
+       u_int16_t attr_count;
+       u_int8_t cb_id = NFNL_MSG_TYPE(nlh->nlmsg_type);
 
-       memset(cda, 0, sizeof(struct nfattr *) * subsys->attr_count);
+       if (unlikely(cb_id >= subsys->cb_count)) {
+               DEBUGP("msgtype %u >= %u, returning\n",
+                       cb_id, subsys->cb_count);
+               return -EINVAL;
+       }
+       
+       attr_count = subsys->cb[cb_id].attr_count;
+
+       memset(cda, 0, sizeof(struct nfattr *) * attr_count);
 
        /* check attribute lengths. */
        min_len = NLMSG_ALIGN(sizeof(struct nfgenmsg));
@@ -170,7 +180,7 @@ nfnetlink_check_attributes(struct nfnetlink_subsystem *subsys,
                while (NFA_OK(attr, attrlen)) {
                        unsigned flavor = attr->nfa_type;
                        if (flavor) {
-                               if (flavor > subsys->attr_count)
+                               if (flavor > attr_count)
                                        return -EINVAL;
                                cda[flavor - 1] = attr;
                        }
@@ -256,9 +266,11 @@ static inline int nfnetlink_rcv_msg(struct sk_buff *skb,
        }
 
        {
-               struct nfattr *cda[ss->attr_count];
+               u_int16_t attr_count = 
+                       ss->cb[NFNL_MSG_TYPE(nlh->nlmsg_type)].attr_count;
+               struct nfattr *cda[attr_count];
 
-               memset(cda, 0, ss->attr_count*sizeof(struct nfattr *));
+               memset(cda, 0, sizeof(struct nfattr *) * attr_count);
                
                err = nfnetlink_check_attributes(ss, nlh, cda);
                if (err < 0)
index f41045e385ae42ee3ba80847eeec5c53b7fdf76b..1750f0d6e4de4ca217f785ad241fcb10b0e13713 100644 (file)
@@ -805,8 +805,10 @@ out_put:
 
 static struct nfnl_callback nfulnl_cb[NFULNL_MSG_MAX] = {
        [NFULNL_MSG_PACKET]     = { .call = nfulnl_recv_unsupp,
-                                   .cap_required = CAP_NET_ADMIN },
+                                   .attr_count = NFULA_MAX,
+                                   .cap_required = CAP_NET_ADMIN, },
        [NFULNL_MSG_CONFIG]     = { .call = nfulnl_recv_config,
+                                   .attr_count = NFULA_CFG_MAX,
                                    .cap_required = CAP_NET_ADMIN },
 };
 
@@ -814,7 +816,6 @@ static struct nfnetlink_subsystem nfulnl_subsys = {
        .name           = "log",
        .subsys_id      = NFNL_SUBSYS_ULOG,
        .cb_count       = NFULNL_MSG_MAX,
-       .attr_count     = NFULA_MAX,
        .cb             = nfulnl_cb,
 };
 
index d7b0330d64b4416e13711400c42d14b9aeccc2fe..04323ee1eb8dfdd22e0f6f7fd40d91ca331d8b51 100644 (file)
@@ -877,10 +877,13 @@ out_put:
 
 static struct nfnl_callback nfqnl_cb[NFQNL_MSG_MAX] = {
        [NFQNL_MSG_PACKET]      = { .call = nfqnl_recv_unsupp,
+                                   .attr_count = NFQA_MAX,
                                    .cap_required = CAP_NET_ADMIN },
        [NFQNL_MSG_VERDICT]     = { .call = nfqnl_recv_verdict,
+                                   .attr_count = NFQA_MAX,
                                    .cap_required = CAP_NET_ADMIN },
        [NFQNL_MSG_CONFIG]      = { .call = nfqnl_recv_config,
+                                   .attr_count = NFQA_CFG_MAX,
                                    .cap_required = CAP_NET_ADMIN },
 };
 
@@ -888,7 +891,6 @@ static struct nfnetlink_subsystem nfqnl_subsys = {
        .name           = "nf_queue",
        .subsys_id      = NFNL_SUBSYS_QUEUE,
        .cb_count       = NFQNL_MSG_MAX,
-       .attr_count     = NFQA_MAX,
        .cb             = nfqnl_cb,
 };