netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Christian Brauner <christian@brauner.io>
To: jbenc@redhat.com, davem@davemloft.net, dsahern@gmail.com,
	stephen@networkplumber.org, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org
Cc: Christian Brauner <christian@brauner.io>
Subject: [PATCH net-next 5/7] phonet: add RTM_GETADDR2
Date: Thu, 27 Sep 2018 19:58:55 +0200	[thread overview]
Message-ID: <20180927175857.3511-6-christian@brauner.io> (raw)
In-Reply-To: <20180927175857.3511-1-christian@brauner.io>

Various userspace programs (e.g. iproute2) have sent RTM_GETADDR
requests with struct ifinfomsg. This is wrong and should have been
struct ifaddrmsg all along as mandated by the manpages. However, dump
requests so far didn't parse the netlink message that was sent and
succeeded even when a wrong struct was passed along.

Currently, the message is parsed under the assumption that the correct
struct ifaddrmsg is sent down. If the parsing fails the kernel will
still fulfill the request to preserve backwards compatability but a
rate-limited message that there were leftover bytes after parsing the
message is recorded in dmesg. It has been argued that this is
unacceptable [1].

But various new features that got and will get added to RTM_GETADDR make
it necessary to definitely know what header was passed along.
This is currently not possible without resorting to (likely unreliable)
hacks such as introducing a nested attribute that ensures that
RTM_GETADDR which pass along properties such as IFA_TARGET_NETNSID
always exceed RTM_GETADDR requests that send down the wrong struct
ifinfomsg [2]. Basically, multiple approaches to solve this have been
shut down. Furthermore, the API expressed via RTM_GETADDR is apparently
frozen [3] so the wiggle room at this point seems very much zero.

The correct solution at this point seems to me to introduce a new
RTM_GETADDR2 request. This way we can parse the message and fail hard if
the struct is not struct ifaddrmsg and can safely extend it in the
future. Userspace tools that rely on the buggy RTM_GETADDR API will
still keep working without even having to see any log messages and new
userspace tools that want to make user of new features can make use of
the new RTM_GETADDR2 requests.

[1]: https://lists.openwall.net/netdev/2018/09/25/59
[2]: https://lists.openwall.net/netdev/2018/09/25/75
[3]: https://lists.openwall.net/netdev/2018/09/26/166

Signed-off-by: Christian Brauner <christian@brauner.io>
Cc: David Ahern <dsahern@gmail.com>
Cc: Jiri Benc <jbenc@redhat.com>
Cc: Stephen Hemminger <stephen@networkplumber.org>
---
 net/phonet/pn_netlink.c | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)

diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c
index 871eaf2cb85e..acba4fe9a612 100644
--- a/net/phonet/pn_netlink.c
+++ b/net/phonet/pn_netlink.c
@@ -131,13 +131,22 @@ static int fill_addr(struct sk_buff *skb, struct net_device *dev, u8 addr,
 	return -EMSGSIZE;
 }
 
-static int getaddr_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
+static int getaddr_dumpit_common(struct sk_buff *skb,
+				 struct netlink_callback *cb, int rtm_type)
 {
 	struct phonet_device_list *pndevs;
+	struct nlattr *tb[IFA_MAX+1];
 	struct phonet_device *pnd;
-	int dev_idx = 0, dev_start_idx = cb->args[0];
+	int err, dev_idx = 0, dev_start_idx = cb->args[0];
 	int addr_idx = 0, addr_start_idx = cb->args[1];
 
+	if (rtm_type == RTM_GETADDR2) {
+		err = nlmsg_parse(cb->nlh, sizeof(struct ifaddrmsg), tb,
+				  IFA_MAX, ifa_phonet_policy, NULL);
+		if (err < 0)
+			return err;
+	}
+
 	pndevs = phonet_device_list(sock_net(skb->sk));
 	rcu_read_lock();
 	list_for_each_entry_rcu(pnd, &pndevs->list, list) {
@@ -168,6 +177,16 @@ static int getaddr_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
 	return skb->len;
 }
 
+static int getaddr_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	return getaddr_dumpit_common(skb, cb, RTM_GETADDR);
+}
+
+static int getaddr_dumpit2(struct sk_buff *skb, struct netlink_callback *cb)
+{
+	return getaddr_dumpit_common(skb, cb, RTM_GETADDR2);
+}
+
 /* Routes handling */
 
 static int fill_route(struct sk_buff *skb, struct net_device *dev, u8 dst,
@@ -309,6 +328,8 @@ int __init phonet_netlink_register(void)
 			     addr_doit, NULL, 0);
 	rtnl_register_module(THIS_MODULE, PF_PHONET, RTM_GETADDR,
 			     NULL, getaddr_dumpit, 0);
+	rtnl_register_module(THIS_MODULE, PF_PHONET, RTM_GETADDR2,
+			     NULL, getaddr_dumpit2, 0);
 	rtnl_register_module(THIS_MODULE, PF_PHONET, RTM_NEWROUTE,
 			     route_doit, NULL, 0);
 	rtnl_register_module(THIS_MODULE, PF_PHONET, RTM_DELROUTE,
-- 
2.17.1

  parent reply	other threads:[~2018-09-27 17:58 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-27 17:58 [PATCH net-next 0/7] rtnetlink: add RTM_GETADDR2 Christian Brauner
2018-09-27 17:58 ` [PATCH net-next 1/7] " Christian Brauner
2018-09-27 17:58 ` [PATCH net-next 2/7] ipv4: " Christian Brauner
2018-09-27 17:58 ` [PATCH net-next 3/7] ipv6: " Christian Brauner
2018-09-27 17:58 ` [PATCH net-next 4/7] decnet: " Christian Brauner
2018-09-27 17:58 ` Christian Brauner [this message]
2018-09-27 17:58 ` [PATCH net-next 6/7] selinux: " Christian Brauner
2018-09-27 17:58 ` [PATCH net-next 7/7] rtnetlink: enable RTM_GETADDR2 Christian Brauner
2018-09-27 20:24 ` [PATCH net-next 0/7] rtnetlink: add RTM_GETADDR2 David Ahern
2018-09-27 20:31   ` Christian Brauner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180927175857.3511-6-christian@brauner.io \
    --to=christian@brauner.io \
    --cc=davem@davemloft.net \
    --cc=dsahern@gmail.com \
    --cc=jbenc@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=stephen@networkplumber.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).