diff options
author | Eric Dumazet <dada1@cosmosbay.com> | 2009-02-18 13:11:39 -0500 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2009-02-18 13:11:39 -0500 |
commit | 4f1c3b7e7ee4d841c8af3a074dc361d6a7a77803 (patch) | |
tree | b6f0e6172806ee8ab3ec2f6442399322b9a89534 /net/netfilter | |
parent | cfac5ef7b92a2d504563989ecd0beb563920444b (diff) |
netfilter: xt_physdev fixes
1) physdev_mt() incorrectly assumes nulldevname[] is aligned on an int
2) It also uses word comparisons, while it could use long word ones.
Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/netfilter')
-rw-r--r-- | net/netfilter/xt_physdev.c | 23 |
1 files changed, 11 insertions, 12 deletions
diff --git a/net/netfilter/xt_physdev.c b/net/netfilter/xt_physdev.c index 1bcdfc12cf59..4b13ef7ce145 100644 --- a/net/netfilter/xt_physdev.c +++ b/net/netfilter/xt_physdev.c | |||
@@ -24,9 +24,9 @@ static bool | |||
24 | physdev_mt(const struct sk_buff *skb, const struct xt_match_param *par) | 24 | physdev_mt(const struct sk_buff *skb, const struct xt_match_param *par) |
25 | { | 25 | { |
26 | int i; | 26 | int i; |
27 | static const char nulldevname[IFNAMSIZ]; | 27 | static const char nulldevname[IFNAMSIZ] __attribute__((aligned(sizeof(long)))); |
28 | const struct xt_physdev_info *info = par->matchinfo; | 28 | const struct xt_physdev_info *info = par->matchinfo; |
29 | bool ret; | 29 | unsigned long ret; |
30 | const char *indev, *outdev; | 30 | const char *indev, *outdev; |
31 | const struct nf_bridge_info *nf_bridge; | 31 | const struct nf_bridge_info *nf_bridge; |
32 | 32 | ||
@@ -68,10 +68,10 @@ physdev_mt(const struct sk_buff *skb, const struct xt_match_param *par) | |||
68 | if (!(info->bitmask & XT_PHYSDEV_OP_IN)) | 68 | if (!(info->bitmask & XT_PHYSDEV_OP_IN)) |
69 | goto match_outdev; | 69 | goto match_outdev; |
70 | indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname; | 70 | indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname; |
71 | for (i = 0, ret = false; i < IFNAMSIZ/sizeof(unsigned int); i++) { | 71 | for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) { |
72 | ret |= (((const unsigned int *)indev)[i] | 72 | ret |= (((const unsigned long *)indev)[i] |
73 | ^ ((const unsigned int *)info->physindev)[i]) | 73 | ^ ((const unsigned long *)info->physindev)[i]) |
74 | & ((const unsigned int *)info->in_mask)[i]; | 74 | & ((const unsigned long *)info->in_mask)[i]; |
75 | } | 75 | } |
76 | 76 | ||
77 | if (!ret ^ !(info->invert & XT_PHYSDEV_OP_IN)) | 77 | if (!ret ^ !(info->invert & XT_PHYSDEV_OP_IN)) |
@@ -82,13 +82,12 @@ match_outdev: | |||
82 | return true; | 82 | return true; |
83 | outdev = nf_bridge->physoutdev ? | 83 | outdev = nf_bridge->physoutdev ? |
84 | nf_bridge->physoutdev->name : nulldevname; | 84 | nf_bridge->physoutdev->name : nulldevname; |
85 | for (i = 0, ret = false; i < IFNAMSIZ/sizeof(unsigned int); i++) { | 85 | for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) { |
86 | ret |= (((const unsigned int *)outdev)[i] | 86 | ret |= (((const unsigned long *)outdev)[i] |
87 | ^ ((const unsigned int *)info->physoutdev)[i]) | 87 | ^ ((const unsigned long *)info->physoutdev)[i]) |
88 | & ((const unsigned int *)info->out_mask)[i]; | 88 | & ((const unsigned long *)info->out_mask)[i]; |
89 | } | 89 | } |
90 | 90 | return (!!ret ^ !(info->invert & XT_PHYSDEV_OP_OUT)); | |
91 | return ret ^ !(info->invert & XT_PHYSDEV_OP_OUT); | ||
92 | } | 91 | } |
93 | 92 | ||
94 | static bool physdev_mt_check(const struct xt_mtchk_param *par) | 93 | static bool physdev_mt_check(const struct xt_mtchk_param *par) |