lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20121127115905.GA16701@casper.infradead.org>
Date:	Tue, 27 Nov 2012 11:59:05 +0000
From:	Thomas Graf <tgraf@...g.ch>
To:	Cong Wang <amwang@...hat.com>
Cc:	netdev@...r.kernel.org, bridge@...ts.linux-foundation.org,
	Herbert Xu <herbert@...dor.hengli.com.au>,
	Stephen Hemminger <shemminger@...tta.com>,
	"David S. Miller" <davem@...emloft.net>,
	Jesper Dangaard Brouer <brouer@...hat.com>
Subject: Re: [RFC PATCH 2/2] bridge: export multicast database via netlink

On 11/27/12 at 05:49pm, Cong Wang wrote:
> +static int br_rports_fill_info(struct sk_buff *skb, struct netlink_callback *cb,
> +			       u32 seq, struct net_device *dev)
> +{
> +	struct net_bridge *br = netdev_priv(dev);
> +	struct net_bridge_port *p;
> +	struct hlist_node *n;
> +	struct nlattr *nest, *nest2;
> +
> +	if (!br->multicast_router || hlist_empty(&br->router_list)) {
> +		printk(KERN_INFO "no router on bridge\n");
> +		return 0;
> +	}
> +
> +	nest = nla_nest_start(skb, MDBA_ROUTER);
> +	if (nest == NULL)
> +		return -EMSGSIZE;
> +	nest2 = nla_nest_start(skb, MDBA_MDB_BRPORT);
> +	if (nest2 == NULL)
> +		goto fail;
> +
> +	hlist_for_each_entry_rcu(p, n, &br->router_list, rlist) {
> +		if (p && nla_put_u16(skb, MDBA_BRPORT_NO, p->port_no)) {
> +			nla_nest_cancel(skb, nest2);
> +			goto fail;
> +		}
> +	}
> +
> +	nla_nest_end(skb, nest2);
> +	nla_nest_end(skb, nest);

I would simplify the MDBA_ROUTER attribute to a u16[len(br->router_list)]. If
we ever need something more complex we can retire the MDBA_ROUTER
attribute and replace it with something newer.

> +	nest = nla_nest_start(skb, MDBA_MDB);
> +	if (nest == NULL)
> +		return -EMSGSIZE;
> +
> +	for (i = 0; i < mdb->max; i++) {
> +		struct hlist_node *h;
> +		struct net_bridge_mdb_entry *mp;
> +		struct net_bridge_port_group *p, **pp;
> +		struct net_bridge_port *port;
> +
> +		hlist_for_each_entry_rcu(mp, h, &mdb->mhash[i], hlist[mdb->ver]) {
> +			if (nla_put_be32(skb, MDBA_MDB_MCADDR, mp->addr.u.ip4))
> +				goto fail;
> +
> +			nest2 = nla_nest_start(skb, MDBA_MDB_BRPORT);
> +			if (nest2 == NULL)
> +				goto fail;

What if you can't fit all theh hash entries into a single netlink
message? You need to allow splitting theh hash across multiple
messages. Therefore I suggest that you add a container attribute
for each mdb_entry like this:

MDBA_MDB = {
  1 = {
    MDBA_MDB_MCADDR = { ... },
    MDBA_MDB_BRPORT = { ... },
  },
  2 = {
    MDBA_MDB_MCADDR = { ... },
    MDBA_MDB_BR_PORT = { ... },
  },
  [...]
}

> +static int br_mdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
> +{
> +	struct net_device *dev;
> +	struct net *net = sock_net(skb->sk);
> +	struct nlmsghdr *nlh;
> +	u32 seq = cb->nlh->nlmsg_seq;
> +	int idx = 0, s_idx;
> +
> +	s_idx = cb->args[0];
> +
> +	rcu_read_lock();
> +	cb->seq = net->dev_base_seq;

Using RCU read lock is OK but that means you must be prepared to
handle additions/removals to the table between dump iterations
and thus you must introduce a seq counter bumped on each table
change and add it to the dev_base_seq above.

> +	for_each_netdev_rcu(net, dev) {
> +		if (dev->priv_flags & IFF_EBRIDGE) {
> +			struct br_port_msg *bpm;
> +
> +			if (idx < s_idx)
> +				goto cont;
> +
> +			nlh = nlmsg_put(skb, NETLINK_CB(cb->skb).portid,
> +					seq, RTM_GETMDB,
> +					sizeof(*bpm), NLM_F_MULTI);
> +			if (nlh == NULL)
> +				break;
> +
> +			bpm = nlmsg_data(nlh);
> +			bpm->ifindex = dev->ifindex;
> +			if (br_mdb_fill_info(skb, cb, seq, dev) < 0) {
> +				printk(KERN_INFO "br_mdb_fill_info failed\n");
> +				goto fail;

As stated above I believe that you should allow for hashtable to be
split across multiple messages so you need to store the hash table
offset as well and properly finalize and send the message on error
here.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ