Commit 5d04bff0 authored by Patrick McHardy's avatar Patrick McHardy Committed by David S. Miller
Browse files

[NETFILTER]: Convert x_tables matches/targets to centralized error checking


Signed-off-by: default avatarPatrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7f939713
......@@ -39,47 +39,22 @@ target(struct sk_buff **pskb,
return XT_CONTINUE;
}
static int
checkentry(const char *tablename,
const void *e,
void *targinfo,
unsigned int targinfosize,
unsigned int hook_mask)
{
if (targinfosize != XT_ALIGN(sizeof(struct xt_classify_target_info))){
printk(KERN_ERR "CLASSIFY: invalid size (%u != %Zu).\n",
targinfosize,
XT_ALIGN(sizeof(struct xt_classify_target_info)));
return 0;
}
if (hook_mask & ~((1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) |
(1 << NF_IP_POST_ROUTING))) {
printk(KERN_ERR "CLASSIFY: only valid in LOCAL_OUT, FORWARD "
"and POST_ROUTING.\n");
return 0;
}
if (strcmp(tablename, "mangle") != 0) {
printk(KERN_ERR "CLASSIFY: can only be called from "
"\"mangle\" table, not \"%s\".\n",
tablename);
return 0;
}
return 1;
}
static struct xt_target classify_reg = {
.name = "CLASSIFY",
.target = target,
.checkentry = checkentry,
.targetsize = sizeof(struct xt_classify_target_info),
.table = "mangle",
.hooks = (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) |
(1 << NF_IP_POST_ROUTING),
.me = THIS_MODULE,
};
static struct xt_target classify6_reg = {
.name = "CLASSIFY",
.target = target,
.checkentry = checkentry,
.targetsize = sizeof(struct xt_classify_target_info),
.table = "mangle",
.hooks = (1 << NF_IP_LOCAL_OUT) | (1 << NF_IP_FORWARD) |
(1 << NF_IP_POST_ROUTING),
.me = THIS_MODULE,
};
......
......@@ -79,12 +79,6 @@ checkentry(const char *tablename,
unsigned int hook_mask)
{
struct xt_connmark_target_info *matchinfo = targinfo;
if (targinfosize != XT_ALIGN(sizeof(struct xt_connmark_target_info))) {
printk(KERN_WARNING "CONNMARK: targinfosize %u != %Zu\n",
targinfosize,
XT_ALIGN(sizeof(struct xt_connmark_target_info)));
return 0;
}
if (matchinfo->mode == XT_CONNMARK_RESTORE) {
if (strcmp(tablename, "mangle") != 0) {
......@@ -102,16 +96,19 @@ checkentry(const char *tablename,
}
static struct xt_target connmark_reg = {
.name = "CONNMARK",
.target = &target,
.checkentry = &checkentry,
.me = THIS_MODULE
.name = "CONNMARK",
.target = target,
.targetsize = sizeof(struct xt_connmark_target_info),
.checkentry = checkentry,
.me = THIS_MODULE
};
static struct xt_target connmark6_reg = {
.name = "CONNMARK",
.target = &target,
.checkentry = &checkentry,
.me = THIS_MODULE
.name = "CONNMARK",
.target = target,
.targetsize = sizeof(struct xt_connmark_target_info),
.checkentry = checkentry,
.me = THIS_MODULE
};
static int __init init(void)
......
......@@ -78,23 +78,10 @@ checkentry_v0(const char *tablename,
{
struct xt_mark_target_info *markinfo = targinfo;
if (targinfosize != XT_ALIGN(sizeof(struct xt_mark_target_info))) {
printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n",
targinfosize,
XT_ALIGN(sizeof(struct xt_mark_target_info)));
return 0;
}
if (strcmp(tablename, "mangle") != 0) {
printk(KERN_WARNING "MARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
return 0;
}
if (markinfo->mark > 0xffffffff) {
printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n");
return 0;
}
return 1;
}
......@@ -107,18 +94,6 @@ checkentry_v1(const char *tablename,
{
struct xt_mark_target_info_v1 *markinfo = targinfo;
if (targinfosize != XT_ALIGN(sizeof(struct xt_mark_target_info_v1))){
printk(KERN_WARNING "MARK: targinfosize %u != %Zu\n",
targinfosize,
XT_ALIGN(sizeof(struct xt_mark_target_info_v1)));
return 0;
}
if (strcmp(tablename, "mangle") != 0) {
printk(KERN_WARNING "MARK: can only be called from \"mangle\" table, not \"%s\"\n", tablename);
return 0;
}
if (markinfo->mode != XT_MARK_SET
&& markinfo->mode != XT_MARK_AND
&& markinfo->mode != XT_MARK_OR) {
......@@ -126,18 +101,18 @@ checkentry_v1(const char *tablename,
markinfo->mode);
return 0;
}
if (markinfo->mark > 0xffffffff) {
printk(KERN_WARNING "MARK: Only supports 32bit wide mark\n");
return 0;
}
return 1;
}
static struct xt_target ipt_mark_reg_v0 = {
.name = "MARK",
.target = target_v0,
.targetsize = sizeof(struct xt_mark_target_info),
.table = "mangle",
.checkentry = checkentry_v0,
.me = THIS_MODULE,
.revision = 0,
......@@ -146,6 +121,8 @@ static struct xt_target ipt_mark_reg_v0 = {
static struct xt_target ipt_mark_reg_v1 = {
.name = "MARK",
.target = target_v1,
.targetsize = sizeof(struct xt_mark_target_info_v1),
.table = "mangle",
.checkentry = checkentry_v1,
.me = THIS_MODULE,
.revision = 1,
......@@ -154,6 +131,8 @@ static struct xt_target ipt_mark_reg_v1 = {
static struct xt_target ip6t_mark_reg_v0 = {
.name = "MARK",
.target = target_v0,
.targetsize = sizeof(struct xt_mark_target_info),
.table = "mangle",
.checkentry = checkentry_v0,
.me = THIS_MODULE,
.revision = 0,
......
......@@ -36,41 +36,24 @@ target(struct sk_buff **pskb,
return NF_QUEUE_NR(tinfo->queuenum);
}
static int
checkentry(const char *tablename,
const void *entry,
void *targinfo,
unsigned int targinfosize,
unsigned int hook_mask)
{
if (targinfosize != XT_ALIGN(sizeof(struct xt_NFQ_info))) {
printk(KERN_WARNING "NFQUEUE: targinfosize %u != %Zu\n",
targinfosize,
XT_ALIGN(sizeof(struct xt_NFQ_info)));
return 0;
}
return 1;
}
static struct xt_target ipt_NFQ_reg = {
.name = "NFQUEUE",
.target = target,
.checkentry = checkentry,
.targetsize = sizeof(struct xt_NFQ_info),
.me = THIS_MODULE,
};
static struct xt_target ip6t_NFQ_reg = {
.name = "NFQUEUE",
.target = target,
.checkentry = checkentry,
.targetsize = sizeof(struct xt_NFQ_info),
.me = THIS_MODULE,
};
static struct xt_target arpt_NFQ_reg = {
.name = "NFQUEUE",
.target = target,
.checkentry = checkentry,
.targetsize = sizeof(struct xt_NFQ_info),
.me = THIS_MODULE,
};
......
......@@ -33,38 +33,20 @@ target(struct sk_buff **pskb,
return XT_CONTINUE;
}
static int
checkentry(const char *tablename,
const void *entry,
void *targinfo,
unsigned int targinfosize,
unsigned int hook_mask)
{
if (targinfosize != 0) {
printk(KERN_WARNING "NOTRACK: targinfosize %u != 0\n",
targinfosize);
return 0;
}
if (strcmp(tablename, "raw") != 0) {
printk(KERN_WARNING "NOTRACK: can only be called from \"raw\" table, not \"%s\"\n", tablename);
return 0;
}
return 1;
}
static struct xt_target notrack_reg = {
.name = "NOTRACK",
.target = target,
.checkentry = checkentry,
.me = THIS_MODULE,
static struct xt_target notrack_reg = {
.name = "NOTRACK",
.target = target,
.targetsize = 0,
.table = "raw",
.me = THIS_MODULE,
};
static struct xt_target notrack6_reg = {
.name = "NOTRACK",
.target = target,
.checkentry = checkentry,
.me = THIS_MODULE,
static struct xt_target notrack6_reg = {
.name = "NOTRACK",
.target = target,
.targetsize = 0,
.table = "raw",
.me = THIS_MODULE,
};
static int __init init(void)
......
......@@ -28,30 +28,17 @@ match(const struct sk_buff *skb,
return 1;
}
static int
checkentry(const char *tablename,
const void *ip,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)
{
/* Check the size */
if (matchsize != XT_ALIGN(sizeof(struct xt_comment_info)))
return 0;
return 1;
}
static struct xt_match comment_match = {
.name = "comment",
.match = match,
.checkentry = checkentry,
.matchsize = sizeof(struct xt_comment_info),
.me = THIS_MODULE
};
static struct xt_match comment6_match = {
.name = "comment",
.match = match,
.checkentry = checkentry,
.matchsize = sizeof(struct xt_comment_info),
.me = THIS_MODULE
};
......
......@@ -128,9 +128,6 @@ static int check(const char *tablename,
{
const struct xt_connbytes_info *sinfo = matchinfo;
if (matchsize != XT_ALIGN(sizeof(struct xt_connbytes_info)))
return 0;
if (sinfo->what != XT_CONNBYTES_PKTS &&
sinfo->what != XT_CONNBYTES_BYTES &&
sinfo->what != XT_CONNBYTES_AVGPKT)
......@@ -146,14 +143,16 @@ static int check(const char *tablename,
static struct xt_match connbytes_match = {
.name = "connbytes",
.match = &match,
.checkentry = &check,
.match = match,
.checkentry = check,
.matchsize = sizeof(struct xt_connbytes_info),
.me = THIS_MODULE
};
static struct xt_match connbytes6_match = {
.name = "connbytes",
.match = &match,
.checkentry = &check,
.match = match,
.checkentry = check,
.matchsize = sizeof(struct xt_connbytes_info),
.me = THIS_MODULE
};
......
......@@ -56,33 +56,31 @@ checkentry(const char *tablename,
unsigned int matchsize,
unsigned int hook_mask)
{
struct xt_connmark_info *cm =
(struct xt_connmark_info *)matchinfo;
if (matchsize != XT_ALIGN(sizeof(struct xt_connmark_info)))
return 0;
struct xt_connmark_info *cm = (struct xt_connmark_info *)matchinfo;
if (cm->mark > 0xffffffff || cm->mask > 0xffffffff) {
printk(KERN_WARNING "connmark: only support 32bit mark\n");
return 0;
}
return 1;
}
static struct xt_match connmark_match = {
.name = "connmark",
.match = &match,
.checkentry = &checkentry,
.me = THIS_MODULE
.name = "connmark",
.match = match,
.matchsize = sizeof(struct xt_connmark_info),
.checkentry = checkentry,
.me = THIS_MODULE
};
static struct xt_match connmark6_match = {
.name = "connmark",
.match = &match,
.checkentry = &checkentry,
.me = THIS_MODULE
.name = "connmark",
.match = match,
.matchsize = sizeof(struct xt_connmark_info),
.checkentry = checkentry,
.me = THIS_MODULE
};
static int __init init(void)
{
int ret;
......
......@@ -201,22 +201,10 @@ match(const struct sk_buff *skb,
#endif /* CONFIG_NF_IP_CONNTRACK */
static int check(const char *tablename,
const void *ip,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)
{
if (matchsize != XT_ALIGN(sizeof(struct xt_conntrack_info)))
return 0;
return 1;
}
static struct xt_match conntrack_match = {
.name = "conntrack",
.match = &match,
.checkentry = &check,
.match = match,
.matchsize = sizeof(struct xt_conntrack_info),
.me = THIS_MODULE,
};
......
......@@ -133,52 +133,29 @@ checkentry(const char *tablename,
unsigned int matchsize,
unsigned int hook_mask)
{
const struct ipt_ip *ip = inf;
const struct xt_dccp_info *info;
const struct xt_dccp_info *info = matchinfo;
info = (const struct xt_dccp_info *)matchinfo;
return ip->proto == IPPROTO_DCCP
&& !(ip->invflags & XT_INV_PROTO)
&& matchsize == XT_ALIGN(sizeof(struct xt_dccp_info))
&& !(info->flags & ~XT_DCCP_VALID_FLAGS)
&& !(info->invflags & ~XT_DCCP_VALID_FLAGS)
&& !(info->invflags & ~info->flags);
}
static int
checkentry6(const char *tablename,
const void *inf,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)
{
const struct ip6t_ip6 *ip = inf;
const struct xt_dccp_info *info;
info = (const struct xt_dccp_info *)matchinfo;
return ip->proto == IPPROTO_DCCP
&& !(ip->invflags & XT_INV_PROTO)
&& matchsize == XT_ALIGN(sizeof(struct xt_dccp_info))
&& !(info->flags & ~XT_DCCP_VALID_FLAGS)
return !(info->flags & ~XT_DCCP_VALID_FLAGS)
&& !(info->invflags & ~XT_DCCP_VALID_FLAGS)
&& !(info->invflags & ~info->flags);
}
static struct xt_match dccp_match =
{
.name = "dccp",
.match = &match,
.checkentry = &checkentry,
.match = match,
.matchsize = sizeof(struct xt_dccp_info),
.proto = IPPROTO_DCCP,
.checkentry = checkentry,
.me = THIS_MODULE,
};
static struct xt_match dccp6_match =
{
.name = "dccp",
.match = &match,
.checkentry = &checkentry6,
.match = match,
.matchsize = sizeof(struct xt_dccp_info),
.proto = IPPROTO_DCCP,
.checkentry = checkentry,
.me = THIS_MODULE,
};
......
......@@ -142,24 +142,21 @@ static int check(const char *tablename,
struct xt_helper_info *info = matchinfo;
info->name[29] = '\0';
/* verify size */
if (matchsize != XT_ALIGN(sizeof(struct xt_helper_info)))
return 0;
return 1;
}
static struct xt_match helper_match = {
.name = "helper",
.match = &match,
.checkentry = &check,
.match = match,
.matchsize = sizeof(struct xt_helper_info),
.checkentry = check,
.me = THIS_MODULE,
};
static struct xt_match helper6_match = {
.name = "helper",
.match = &match,
.checkentry = &check,
.match = match,
.matchsize = sizeof(struct xt_helper_info),
.checkentry = check,
.me = THIS_MODULE,
};
......
......@@ -50,29 +50,17 @@ match6(const struct sk_buff *skb,
return (pktlen >= info->min && pktlen <= info->max) ^ info->invert;
}
static int
checkentry(const char *tablename,
const void *ip,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)
{
if (matchsize != XT_ALIGN(sizeof(struct xt_length_info)))
return 0;
return 1;
}
static struct xt_match length_match = {
.name = "length",
.match = &match,
.checkentry = &checkentry,
.match = match,
.matchsize = sizeof(struct xt_length_info),
.me = THIS_MODULE,
};
static struct xt_match length6_match = {
.name = "length",
.match = &match6,
.checkentry = &checkentry,
.match = match6,
.matchsize = sizeof(struct xt_length_info),
.me = THIS_MODULE,
};
......
......@@ -113,9 +113,6 @@ ipt_limit_checkentry(const char *tablename,
{
struct xt_rateinfo *r = matchinfo;
if (matchsize != XT_ALIGN(sizeof(struct xt_rateinfo)))
return 0;
/* Check for overflow. */
if (r->burst == 0
|| user2credits(r->avg * r->burst) < user2credits(r->avg)) {
......@@ -140,12 +137,14 @@ ipt_limit_checkentry(const char *tablename,
static struct xt_match ipt_limit_reg = {
.name = "limit",
.match = ipt_limit_match,
.matchsize = sizeof(struct xt_rateinfo),
.checkentry = ipt_limit_checkentry,
.me = THIS_MODULE,
};
static struct xt_match limit6_reg = {
.name = "limit",
.match = ipt_limit_match,
.matchsize = sizeof(struct xt_rateinfo),
.checkentry = ipt_limit_checkentry,
.me = THIS_MODULE,
};
......
......@@ -42,37 +42,20 @@ match(const struct sk_buff *skb,
^ info->invert));
}
static int
ipt_mac_checkentry(const char *tablename,
const void *inf,
void *matchinfo,
unsigned int matchsize,
unsigned int hook_mask)
{
/* FORWARD isn't always valid, but it's nice to be able to do --RR */
if (hook_mask
& ~((1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN)
| (1 << NF_IP_FORWARD))) {
printk("xt_mac: only valid for PRE_ROUTING, LOCAL_IN or FORWARD.\n");
return 0;
}
if (matchsize != XT_ALIGN(sizeof(struct xt_mac_info)))
return 0;
return 1;
}
static struct xt_match mac_match = {
.name = "mac",
.match = &match,
.checkentry = &ipt_mac_checkentry,
.match = match,
.matchsize = sizeof(struct xt_mac_info),
.hooks = (1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) |
(1 << NF_IP_FORWARD),
.me = THIS_MODULE,
};
static struct xt_match mac6_match = {
.name = "mac",
.match = &match,
.checkentry = &ipt_mac_checkentry,
.match = match,
.matchsize = sizeof(struct xt_mac_info),
.hooks = (1 << NF_IP_PRE_ROUTING) | (1 << NF_IP_LOCAL_IN) |
(1 << NF_IP_FORWARD),
.me = THIS_MODULE,
};