[ofa-general] [PATCH] IPoIB: check multicast address format (V2)
Jason Gunthorpe
jgunthorpe at obsidianresearch.com
Tue Sep 1 13:27:47 PDT 2009
Check that the format of the multicast link address is correct before
taking it from dev->mc_list to priv->multicast_list. This way we never
try to send a bogus address to the SA, and prevents badness from
erronous 'ip maddr addr add', broken bonding drivers, or whatever.
Signed-off-by: Jason Gunthorpe <jgunthorpe at obsidianresearch.com>
---
drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 19 +++++++++++++++++++
1 files changed, 19 insertions(+), 0 deletions(-)
> The idea seems sound but checkpatch.pl gives 6 errors for this small
> patch! Also:
Indeed, sorry, I don't do this very often, forgot that step. I added
the 6 missing spaces.
> name of the function could make it clearer what the expected return
> value is ... eg mcast_addr_is_valid() or something like that.
Yes, done
> > + if (addrlen != 20)
> We have INFINIBAND_ALEN defined, seems better than a magic # here.
Great, I looked for that for a few mins..
> > + if (memcmp(addr,broadcast,6) != 0)
> Personal taste here, but "if (foo != 0)" always seems silly to me when
> we could just do "if (foo)" -- haven't looked at what usage of memcmp()
> is more idiomatic in the kernel tho.
OK, much of the rest of the kernel is without the operator. I do it
this way because the discordance of:
if (cmp(a, b)) means a is not b,
if (!cmp(a, b)) means a is b
if (is_something(a)) means a is something
hurts my brain, even though I know that is how it all
works..
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 425e311..a6485c4 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -758,6 +758,20 @@ void ipoib_mcast_dev_flush(struct net_device *dev)
}
}
+static int ipoib_mcast_addr_is_valid(const u8 *addr, unsigned int addrlen,
+ const u8 *broadcast)
+{
+ if (addrlen != INFINIBAND_ALEN)
+ return 0;
+ /* reserved QPN, prefix, scope */
+ if (memcmp(addr, broadcast, 6))
+ return 0;
+ /* signature lower, pkey */
+ if (memcmp(addr + 7, broadcast + 7, 3))
+ return 0;
+ return 1;
+}
+
void ipoib_mcast_restart_task(struct work_struct *work)
{
struct ipoib_dev_priv *priv =
@@ -791,6 +805,11 @@ void ipoib_mcast_restart_task(struct work_struct *work)
for (mclist = dev->mc_list; mclist; mclist = mclist->next) {
union ib_gid mgid;
+ if (!ipoib_mcast_addr_is_valid(mclist->dmi_addr,
+ mclist->dmi_addrlen,
+ dev->broadcast))
+ continue;
+
memcpy(mgid.raw, mclist->dmi_addr + 4, sizeof mgid);
mcast = __ipoib_mcast_find(dev, &mgid);
--
1.5.4.2
More information about the general
mailing list