* netlink: 16 bytes leftover after parsing attributes in process `ip'. @ 2018-09-25 3:19 David Ahern 2018-09-25 9:49 ` Christian Brauner 0 siblings, 1 reply; 11+ messages in thread From: David Ahern @ 2018-09-25 3:19 UTC (permalink / raw) To: Christian Brauner; +Cc: netdev@vger.kernel.org, David Miller On top of net-next I am see a dmesg error: netlink: 16 bytes leftover after parsing attributes in process `ip'. I traced it to address lists and commit: commit 6ecf4c37eb3e89b0832c9616089a5cdca3747da7 Author: Christian Brauner <christian@brauner.io> Date: Tue Sep 4 21:53:50 2018 +0200 ipv6: enable IFA_TARGET_NETNSID for RTM_GETADDR Per the commit you are trying to guess whether the ancillary header is an ifinfomsg or a ifaddrmsg. I am guessing you are guessing wrong. :-) I don't have time to take this to ground, but address listing is not the only area subject to iproute2's SNAFU of infomsg everywhere on dumps. I have thought about this for route dumps, but its solution does not work here. You'll need to find something because the current warning on every address dump is not acceptable. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: netlink: 16 bytes leftover after parsing attributes in process `ip'. 2018-09-25 3:19 netlink: 16 bytes leftover after parsing attributes in process `ip' David Ahern @ 2018-09-25 9:49 ` Christian Brauner 2018-09-25 12:07 ` Stephen Hemminger 2018-09-25 14:47 ` Jiri Benc 0 siblings, 2 replies; 11+ messages in thread From: Christian Brauner @ 2018-09-25 9:49 UTC (permalink / raw) To: David Ahern; +Cc: netdev@vger.kernel.org, David Miller [-- Attachment #1: Type: text/plain, Size: 3208 bytes --] On Mon, Sep 24, 2018 at 09:19:06PM -0600, David Ahern wrote: > On top of net-next I am see a dmesg error: > > netlink: 16 bytes leftover after parsing attributes in process `ip'. > > I traced it to address lists and commit: > > commit 6ecf4c37eb3e89b0832c9616089a5cdca3747da7 > Author: Christian Brauner <christian@brauner.io> > Date: Tue Sep 4 21:53:50 2018 +0200 > > ipv6: enable IFA_TARGET_NETNSID for RTM_GETADDR > > Per the commit you are trying to guess whether the ancillary header is > an ifinfomsg or a ifaddrmsg. I am guessing you are guessing wrong. :-) Well, I currently don't guess at all. :) I'm parsing with struct ifaddrmsg as assumed header size but ignore parsing errors when that fails. You don't get the niceties of the new property if you don't pack it up nicely in an ifaddrmsg struct. :) > > I don't have time to take this to ground, but address listing is not the > only area subject to iproute2's SNAFU of infomsg everywhere on dumps. I > have thought about this for route dumps, but its solution does not work > here. You'll need to find something because the current warning on every > address dump is not acceptable. Two points before I propose a migitation: 1. The burded of seeing pr_warn_ratelimited() messages in dmesg when userspace is doing something wrong is imho justifiable. Actually, I would argue that we should not hide the problem from userspace at all. The rate-limited (so no logging DOS afaict) warning messages are a perfect indicator that a tool is doing something wrong *without* introducing any regressions. The rtnetlink manpage clearly indicates that ifaddrmsg is supposed to be used too. Additionally, userspace stuffs an ifinfomsg in there but expects to receive ifaddrmsg. They should be warned loudly. :) So I actually like the warning messages. 2. Userspace should be fixed. Especially such an important standard tool as iproute2 that is maintained on git.kernel.org (glibc is already doing the right.). So if people really want to hide this issue as much as we can then we can play the guessing game. I could send a patch that roughly does the following: if (nlmsg_len(cb->nlh) < sizeof(struct ifinfomsg)) guessed_header_len = sizeof(struct ifaddrmsg); else guessed_header_len = sizeof(struct ifinfomsg); This will work since sizeof(ifaddrmsg) == 8 and sizeof(ifinfomsg) == 16. The only valid property for RTM_GETADDR requests is IFA_TARGET_NETNSID. This propert is a __s32 which should bring the message up to 12 bytes (not sure about alignment requiremnts and where we might wend up ten) which is still less than the 16 bytes without that property from ifinfomsg. That's a hacky hacky hack-hack and will likely work but will break when ifaddrmsg grows a new member or we introduce another property that is valid in RTM_GETADDR requests. It also will not work cleanly when users stuff additional properties in there that are valid for the address family but are not used int RTM_GETADDR requests. I would like to hear what other people and davem think we should do. Patch it away or print the warning. Christian [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: netlink: 16 bytes leftover after parsing attributes in process `ip'. 2018-09-25 9:49 ` Christian Brauner @ 2018-09-25 12:07 ` Stephen Hemminger [not found] ` <CAHrFyr55vt78akhC+WE5maDPLzmurUeB6wT-DmHcCmnAfPKrgw@mail.gmail.com> 2018-09-25 14:47 ` Jiri Benc 1 sibling, 1 reply; 11+ messages in thread From: Stephen Hemminger @ 2018-09-25 12:07 UTC (permalink / raw) To: Christian Brauner; +Cc: David Ahern, netdev@vger.kernel.org, David Miller On Tue, 25 Sep 2018 11:49:10 +0200 Christian Brauner <christian@brauner.io> wrote: > On Mon, Sep 24, 2018 at 09:19:06PM -0600, David Ahern wrote: > > On top of net-next I am see a dmesg error: > > > > netlink: 16 bytes leftover after parsing attributes in process `ip'. > > > > I traced it to address lists and commit: > > > > commit 6ecf4c37eb3e89b0832c9616089a5cdca3747da7 > > Author: Christian Brauner <christian@brauner.io> > > Date: Tue Sep 4 21:53:50 2018 +0200 > > > > ipv6: enable IFA_TARGET_NETNSID for RTM_GETADDR > > > > Per the commit you are trying to guess whether the ancillary header is > > an ifinfomsg or a ifaddrmsg. I am guessing you are guessing wrong. :-) > > Well, I currently don't guess at all. :) I'm parsing with struct > ifaddrmsg as assumed header size but ignore parsing errors when that > fails. You don't get the niceties of the new property if you don't pack There are legacy parts of netlink interface with kernel. The ABI has evolved over time but some old parts are stuck in the past. > > I don't have time to take this to ground, but address listing is not the > > only area subject to iproute2's SNAFU of infomsg everywhere on dumps. I > > have thought about this for route dumps, but its solution does not work > > here. You'll need to find something because the current warning on every > > address dump is not acceptable. > > Two points before I propose a migitation: > > 1. The burded of seeing pr_warn_ratelimited() messages in dmesg when > userspace is doing something wrong is imho justifiable. > Actually, I would argue that we should not hide the problem from > userspace at all. The rate-limited (so no logging DOS afaict) warning > messages are a perfect indicator that a tool is doing something wrong > *without* introducing any regressions. > The rtnetlink manpage clearly indicates that ifaddrmsg is supposed to > be used too. Additionally, userspace stuffs an ifinfomsg in there but > expects to receive ifaddrmsg. They should be warned loudly. :) So I > actually like the warning messages. > 2. Userspace should be fixed. Especially such an important standard tool > as iproute2 that is maintained on git.kernel.org (glibc is already > doing the right.). > > So if people really want to hide this issue as much as we can then we > can play the guessing game. I could send a patch that roughly does the > following: > > if (nlmsg_len(cb->nlh) < sizeof(struct ifinfomsg)) > guessed_header_len = sizeof(struct ifaddrmsg); > else > guessed_header_len = sizeof(struct ifinfomsg); > > This will work since sizeof(ifaddrmsg) == 8 and sizeof(ifinfomsg) == 16. > The only valid property for RTM_GETADDR requests is IFA_TARGET_NETNSID. > This propert is a __s32 which should bring the message up to 12 bytes > (not sure about alignment requiremnts and where we might wend up ten) > which is still less than the 16 bytes without that property from > ifinfomsg. That's a hacky hacky hack-hack and will likely work but will > break when ifaddrmsg grows a new member or we introduce another property > that is valid in RTM_GETADDR requests. It also will not work cleanly > when users stuff additional properties in there that are valid for the > address family but are not used int RTM_GETADDR requests. > > I would like to hear what other people and davem think we should do. > Patch it away or print the warning. > > Christian You can't break old programs. That is one of the rules of kernel. Therefore, please either revert the kernel change or put the new attribute in a place where old versions do not cause problem. There are people who run new kernels on old versions of iproute (like enterprise distributions) and vice versa. ^ permalink raw reply [flat|nested] 11+ messages in thread
[parent not found: <CAHrFyr55vt78akhC+WE5maDPLzmurUeB6wT-DmHcCmnAfPKrgw@mail.gmail.com>]
* Re: netlink: 16 bytes leftover after parsing attributes in process `ip'. [not found] ` <CAHrFyr55vt78akhC+WE5maDPLzmurUeB6wT-DmHcCmnAfPKrgw@mail.gmail.com> @ 2018-09-25 13:16 ` Stephen Hemminger 2018-09-26 10:45 ` Christian Brauner 0 siblings, 1 reply; 11+ messages in thread From: Stephen Hemminger @ 2018-09-25 13:16 UTC (permalink / raw) To: Christian Brauner; +Cc: David Ahern, netdev@vger.kernel.org, David Miller On Tue, 25 Sep 2018 14:34:08 +0200 Christian Brauner <christian@brauner.io> wrote: > On Tue, Sep 25, 2018, 14:07 Stephen Hemminger <stephen@networkplumber.org> > wrote: > > > On Tue, 25 Sep 2018 11:49:10 +0200 > > Christian Brauner <christian@brauner.io> wrote: > > > > > On Mon, Sep 24, 2018 at 09:19:06PM -0600, David Ahern wrote: > > > > On top of net-next I am see a dmesg error: > > > > > > > > netlink: 16 bytes leftover after parsing attributes in process `ip'. > > > > > > > > I traced it to address lists and commit: > > > > > > > > commit 6ecf4c37eb3e89b0832c9616089a5cdca3747da7 > > > > Author: Christian Brauner <christian@brauner.io> > > > > Date: Tue Sep 4 21:53:50 2018 +0200 > > > > > > > > ipv6: enable IFA_TARGET_NETNSID for RTM_GETADDR > > > > > > > > Per the commit you are trying to guess whether the ancillary header is > > > > an ifinfomsg or a ifaddrmsg. I am guessing you are guessing wrong. > > :-) > > > > > > Well, I currently don't guess at all. :) I'm parsing with struct > > > ifaddrmsg as assumed header size but ignore parsing errors when that > > > fails. You don't get the niceties of the new property if you don't pack > > > > There are legacy parts of netlink interface with kernel. > > The ABI has evolved over time but some old parts are stuck in the past. > > > > > > > > I don't have time to take this to ground, but address listing is not > > the > > > > only area subject to iproute2's SNAFU of infomsg everywhere on dumps. I > > > > have thought about this for route dumps, but its solution does not work > > > > here. You'll need to find something because the current warning on > > every > > > > address dump is not acceptable. > > > > > > Two points before I propose a migitation: > > > > > > 1. The burded of seeing pr_warn_ratelimited() messages in dmesg when > > > userspace is doing something wrong is imho justifiable. > > > Actually, I would argue that we should not hide the problem from > > > userspace at all. The rate-limited (so no logging DOS afaict) warning > > > messages are a perfect indicator that a tool is doing something wrong > > > *without* introducing any regressions. > > > The rtnetlink manpage clearly indicates that ifaddrmsg is supposed to > > > be used too. Additionally, userspace stuffs an ifinfomsg in there but > > > expects to receive ifaddrmsg. They should be warned loudly. :) So I > > > actually like the warning messages. > > > 2. Userspace should be fixed. Especially such an important standard tool > > > as iproute2 that is maintained on git.kernel.org (glibc is already > > > doing the right.). > > > > > > So if people really want to hide this issue as much as we can then we > > > can play the guessing game. I could send a patch that roughly does the > > > following: > > > > > > if (nlmsg_len(cb->nlh) < sizeof(struct ifinfomsg)) > > > guessed_header_len = sizeof(struct ifaddrmsg); > > > else > > > guessed_header_len = sizeof(struct ifinfomsg); > > > > > > This will work since sizeof(ifaddrmsg) == 8 and sizeof(ifinfomsg) == 16. > > > The only valid property for RTM_GETADDR requests is IFA_TARGET_NETNSID. > > > This propert is a __s32 which should bring the message up to 12 bytes > > > (not sure about alignment requiremnts and where we might wend up ten) > > > which is still less than the 16 bytes without that property from > > > ifinfomsg. That's a hacky hacky hack-hack and will likely work but will > > > break when ifaddrmsg grows a new member or we introduce another property > > > that is valid in RTM_GETADDR requests. It also will not work cleanly > > > when users stuff additional properties in there that are valid for the > > > address family but are not used int RTM_GETADDR requests. > > > > > > I would like to hear what other people and davem think we should do. > > > Patch it away or print the warning. > > > > > > Christian > > > > You can't break old programs. That is one of the rules of kernel. > > Therefore, please either revert the kernel change or put the new attribute > > in a place where old versions do not cause problem. > > > > Sorry, there's a misunderstanding here. The code doesn't regress anything. > The patch was written in a backward compatible way. The only thing it > causes are rate-limited logging messages when the wrong struct is passed. > But the request still succeeds. The issue is with the logging afaict. > > Christian That still means enterprise distributions that use the current kernel will get customer complaints. You need to remove the warning. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: netlink: 16 bytes leftover after parsing attributes in process `ip'. 2018-09-25 13:16 ` Stephen Hemminger @ 2018-09-26 10:45 ` Christian Brauner 0 siblings, 0 replies; 11+ messages in thread From: Christian Brauner @ 2018-09-26 10:45 UTC (permalink / raw) To: Stephen Hemminger; +Cc: David Ahern, netdev@vger.kernel.org, David Miller On Tue, Sep 25, 2018 at 02:16:12PM +0100, Stephen Hemminger wrote: > On Tue, 25 Sep 2018 14:34:08 +0200 > Christian Brauner <christian@brauner.io> wrote: > > > On Tue, Sep 25, 2018, 14:07 Stephen Hemminger <stephen@networkplumber.org> > > wrote: > > > > > On Tue, 25 Sep 2018 11:49:10 +0200 > > > Christian Brauner <christian@brauner.io> wrote: > > > > > > > On Mon, Sep 24, 2018 at 09:19:06PM -0600, David Ahern wrote: > > > > > On top of net-next I am see a dmesg error: > > > > > > > > > > netlink: 16 bytes leftover after parsing attributes in process `ip'. > > > > > > > > > > I traced it to address lists and commit: > > > > > > > > > > commit 6ecf4c37eb3e89b0832c9616089a5cdca3747da7 > > > > > Author: Christian Brauner <christian@brauner.io> > > > > > Date: Tue Sep 4 21:53:50 2018 +0200 > > > > > > > > > > ipv6: enable IFA_TARGET_NETNSID for RTM_GETADDR > > > > > > > > > > Per the commit you are trying to guess whether the ancillary header is > > > > > an ifinfomsg or a ifaddrmsg. I am guessing you are guessing wrong. > > > :-) > > > > > > > > Well, I currently don't guess at all. :) I'm parsing with struct > > > > ifaddrmsg as assumed header size but ignore parsing errors when that > > > > fails. You don't get the niceties of the new property if you don't pack > > > > > > There are legacy parts of netlink interface with kernel. > > > The ABI has evolved over time but some old parts are stuck in the past. > > > > > > > > > > > I don't have time to take this to ground, but address listing is not > > > the > > > > > only area subject to iproute2's SNAFU of infomsg everywhere on dumps. I > > > > > have thought about this for route dumps, but its solution does not work > > > > > here. You'll need to find something because the current warning on > > > every > > > > > address dump is not acceptable. > > > > > > > > Two points before I propose a migitation: > > > > > > > > 1. The burded of seeing pr_warn_ratelimited() messages in dmesg when > > > > userspace is doing something wrong is imho justifiable. > > > > Actually, I would argue that we should not hide the problem from > > > > userspace at all. The rate-limited (so no logging DOS afaict) warning > > > > messages are a perfect indicator that a tool is doing something wrong > > > > *without* introducing any regressions. > > > > The rtnetlink manpage clearly indicates that ifaddrmsg is supposed to > > > > be used too. Additionally, userspace stuffs an ifinfomsg in there but > > > > expects to receive ifaddrmsg. They should be warned loudly. :) So I > > > > actually like the warning messages. > > > > 2. Userspace should be fixed. Especially such an important standard tool > > > > as iproute2 that is maintained on git.kernel.org (glibc is already > > > > doing the right.). > > > > > > > > So if people really want to hide this issue as much as we can then we > > > > can play the guessing game. I could send a patch that roughly does the > > > > following: > > > > > > > > if (nlmsg_len(cb->nlh) < sizeof(struct ifinfomsg)) > > > > guessed_header_len = sizeof(struct ifaddrmsg); > > > > else > > > > guessed_header_len = sizeof(struct ifinfomsg); > > > > > > > > This will work since sizeof(ifaddrmsg) == 8 and sizeof(ifinfomsg) == 16. > > > > The only valid property for RTM_GETADDR requests is IFA_TARGET_NETNSID. > > > > This propert is a __s32 which should bring the message up to 12 bytes > > > > (not sure about alignment requiremnts and where we might wend up ten) > > > > which is still less than the 16 bytes without that property from > > > > ifinfomsg. That's a hacky hacky hack-hack and will likely work but will > > > > break when ifaddrmsg grows a new member or we introduce another property > > > > that is valid in RTM_GETADDR requests. It also will not work cleanly > > > > when users stuff additional properties in there that are valid for the > > > > address family but are not used int RTM_GETADDR requests. > > > > > > > > I would like to hear what other people and davem think we should do. > > > > Patch it away or print the warning. > > > > > > > > Christian > > > > > > You can't break old programs. That is one of the rules of kernel. > > > Therefore, please either revert the kernel change or put the new attribute > > > in a place where old versions do not cause problem. > > > > > > > Sorry, there's a misunderstanding here. The code doesn't regress anything. > > The patch was written in a backward compatible way. The only thing it > > causes are rate-limited logging messages when the wrong struct is passed. > > But the request still succeeds. The issue is with the logging afaict. > > > > Christian > > > That still means enterprise distributions that use the current kernel will > get customer complaints. You need to remove the warning. First, you're the senior developer and I totally accept your decision so we'll make the warning go away! Rate-limited messages in dmesg on an edge kernel in response to wrong userspace behavior *without any functional regressions* is something that I find justifiable and to some extent necessary. The promise about not regressing userspace is about identical results from the kernel on unchanged userspace behavior. The contract doesn't and shouldn't include "We're also not going to tell you that you're doing something wrong.". The log messages are an indicator to userspace that "Hey, you're passing me something wrong in this request. I still will fulfill your request just as before but please, think about changing this.". That's basically the only way we have to get userspace to correct false prior behavior without introducing regressions. Considering warnings in log messages to be regressions leaves us with nothing visible to do. Christian ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: netlink: 16 bytes leftover after parsing attributes in process `ip'. 2018-09-25 9:49 ` Christian Brauner 2018-09-25 12:07 ` Stephen Hemminger @ 2018-09-25 14:47 ` Jiri Benc 2018-09-25 15:37 ` David Ahern 1 sibling, 1 reply; 11+ messages in thread From: Jiri Benc @ 2018-09-25 14:47 UTC (permalink / raw) To: Christian Brauner; +Cc: David Ahern, netdev@vger.kernel.org, David Miller On Tue, 25 Sep 2018 11:49:10 +0200, Christian Brauner wrote: > So if people really want to hide this issue as much as we can then we > can play the guessing game. I could send a patch that roughly does the > following: > > if (nlmsg_len(cb->nlh) < sizeof(struct ifinfomsg)) > guessed_header_len = sizeof(struct ifaddrmsg); > else > guessed_header_len = sizeof(struct ifinfomsg); > > This will work since sizeof(ifaddrmsg) == 8 and sizeof(ifinfomsg) == 16. > The only valid property for RTM_GETADDR requests is IFA_TARGET_NETNSID. > This propert is a __s32 which should bring the message up to 12 bytes > (not sure about alignment requiremnts and where we might wend up ten) > which is still less than the 16 bytes without that property from > ifinfomsg. That's a hacky hacky hack-hack and will likely work but will > break when ifaddrmsg grows a new member or we introduce another property > that is valid in RTM_GETADDR requests. It also will not work cleanly > when users stuff additional properties in there that are vaif (nlmsg_parse(cb->nlh, sizeof(struct ifaddrmsg), tb, IFA_MAX,lid for the > address family but are not used int RTM_GETADDR requests. I'd expect that any potential existing code that makes use of other attributes already assumes ifaddrmsg. Hence, if the nlmsg_len is > sizeof(ifinfomsg), you can be sure that there are attributes and thus the struct used was ifaddrmsg. So, in order for RTM_GETADDR to work reliably with attributes, you have to ensure that the length is > sizeof(ifinfomsg). This can be achieved by putting IFA_TARGET_NETNSID into a nested attribute. Just define IFA_EXTENDED (feel free to invent a better name, of course) and put IFA_TARGET_NETNSID inside. Then in the code, attempt to parse only when the size is large enough: if (nlmsg_len(cb->nlh) > sizeof(struct ifinfomsg)) { int err; err = nlmsg_parse(cb->nlh, sizeof(struct ifaddrmsg), tb, IFA_MAX, ifa_ipv6_policy, NULL); if (err < 0) return err; if (tb[IFA_EXTENDED]) { ...parse the nested attribute... if (tb_nested[IFA_TARGET_NETNSID]) { ...etc... } } } Another option is forcing the user space to add another attribute, for example, IFA_FLAGS_PRESENT, and attempt parsing only when it is present. The logic would then be: if (nlmsg_len(cb->nlh) > sizeof(struct ifinfomsg)) { int err; err = nlmsg_parse(cb->nlh, sizeof(struct ifaddrmsg), tb, IFA_MAX, ifa_ipv6_policy, NULL); if (err < 0) return err; if (tb[IFA_FLAGS_PRESENT] && tb[IFA_TARGET_NETNSID]) { ...etc... } } Jiri ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: netlink: 16 bytes leftover after parsing attributes in process `ip'. 2018-09-25 14:47 ` Jiri Benc @ 2018-09-25 15:37 ` David Ahern 2018-09-26 5:51 ` Jiri Benc 2018-09-26 9:49 ` Christian Brauner 0 siblings, 2 replies; 11+ messages in thread From: David Ahern @ 2018-09-25 15:37 UTC (permalink / raw) To: Jiri Benc, Christian Brauner; +Cc: netdev@vger.kernel.org, David Miller On 9/25/18 8:47 AM, Jiri Benc wrote: > On Tue, 25 Sep 2018 11:49:10 +0200, Christian Brauner wrote: >> So if people really want to hide this issue as much as we can then we >> can play the guessing game. I could send a patch that roughly does the >> following: >> >> if (nlmsg_len(cb->nlh) < sizeof(struct ifinfomsg)) >> guessed_header_len = sizeof(struct ifaddrmsg); >> else >> guessed_header_len = sizeof(struct ifinfomsg); >> >> This will work since sizeof(ifaddrmsg) == 8 and sizeof(ifinfomsg) == 16. >> The only valid property for RTM_GETADDR requests is IFA_TARGET_NETNSID. >> This propert is a __s32 which should bring the message up to 12 bytes >> (not sure about alignment requiremnts and where we might wend up ten) >> which is still less than the 16 bytes without that property from >> ifinfomsg. That's a hacky hacky hack-hack and will likely work but will >> break when ifaddrmsg grows a new member or we introduce another property >> that is valid in RTM_GETADDR requests. It also will not work cleanly >> when users stuff additional properties in there that are vaif (nlmsg_parse(cb->nlh, sizeof(struct ifaddrmsg), tb, IFA_MAX,lid for the >> address family but are not used int RTM_GETADDR requests. > > I'd expect that any potential existing code that makes use of other > attributes already assumes ifaddrmsg. Hence, if the nlmsg_len is > > sizeof(ifinfomsg), you can be sure that there are attributes and thus > the struct used was ifaddrmsg. > > So, in order for RTM_GETADDR to work reliably with attributes, you have > to ensure that the length is > sizeof(ifinfomsg). One of the many on-going efforts I have in progress is kernel side filtering of route dumps. It has this same problem. For it I am proposing a new flag: #define RTM_F_PROPER_HEADER 0x4000 ifinfomsg is 16 bytes which is > rtmsg at 12. If the message length is > 16, then rtm_flags can be checked to know if the proper header is sent. For ifaddrmsg things do not line up as well. Worst all of the flag bits are used. But, perhaps one can be overloaded with the limit that you can never filter on its presence. Since you are adding the first filter to address dumps such a limitation should be ok. For example something like this (whitespace damaged on paste) to remove the guess work: diff --git a/include/uapi/linux/if_addr.h b/include/uapi/linux/if_addr.h index dfcf3ce0097f..8e3e9d475db5 100644 --- a/include/uapi/linux/if_addr.h +++ b/include/uapi/linux/if_addr.h @@ -41,6 +41,11 @@ enum { #define IFA_MAX (__IFA_MAX - 1) /* ifa_flags */ +/* IFA_F_PROPER_HEADER is only set in ifa_flags for dumps + * to indicate the ancillary header is the expected ifaddrmsg + * vs ifinfomsg from legacy userspace + */ +#define IFA_F_PROPER_HEADER 0x01 #define IFA_F_SECONDARY 0x01 #define IFA_F_TEMPORARY IFA_F_SECONDARY diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index bfe3ec7ecb14..256b9f88db8f 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -5022,8 +5022,13 @@ static int inet6_dump_addr(struct sk_buff *skb, struct netlink_callback *cb, s_idx = idx = cb->args[1]; s_ip_idx = ip_idx = cb->args[2]; - if (nlmsg_parse(cb->nlh, sizeof(struct ifaddrmsg), tb, IFA_MAX, - ifa_ipv6_policy, NULL) >= 0) { + if (nlmsg_len(cb->nlh) >= sizeof(struct ifaddrmsg) && + ((struct ifaddrmsg *) nlmsg_data(cb->nlh))->ifa_flags & IFA_F_PROPER_HEADER) { + + if (nlmsg_parse(cb->nlh, sizeof(struct ifaddrmsg), tb, IFA_MAX, + ifa_ipv6_policy, NULL) >= 0) { + ... + if (tb[IFA_TARGET_NETNSID]) { netnsid = nla_get_s32(tb[IFA_TARGET_NETNSID]); For ifaddrmsg ifa_flags aligns with ifi_type which is set by kernel side so this should be ok. ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: netlink: 16 bytes leftover after parsing attributes in process `ip'. 2018-09-25 15:37 ` David Ahern @ 2018-09-26 5:51 ` Jiri Benc 2018-09-26 14:54 ` David Ahern 2018-09-26 9:49 ` Christian Brauner 1 sibling, 1 reply; 11+ messages in thread From: Jiri Benc @ 2018-09-26 5:51 UTC (permalink / raw) To: David Ahern; +Cc: Christian Brauner, netdev@vger.kernel.org, David Miller On Tue, 25 Sep 2018 09:37:41 -0600, David Ahern wrote: > For ifaddrmsg ifa_flags aligns with ifi_type which is set by kernel side > so this should be ok. Does the existing user space set ifi_type to anything? Does it zero out the field? Are we able to find a flag value that is not going to be set by unaware user space? I.e., a bit that is unused by the current ARPHRD values on both little and big endian? (ARPHRD_NONE might be a problem, though...) Jiri ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: netlink: 16 bytes leftover after parsing attributes in process `ip'. 2018-09-26 5:51 ` Jiri Benc @ 2018-09-26 14:54 ` David Ahern 2018-09-26 15:02 ` Stephen Hemminger 0 siblings, 1 reply; 11+ messages in thread From: David Ahern @ 2018-09-26 14:54 UTC (permalink / raw) To: Jiri Benc; +Cc: Christian Brauner, netdev@vger.kernel.org, David Miller On 9/25/18 11:51 PM, Jiri Benc wrote: > On Tue, 25 Sep 2018 09:37:41 -0600, David Ahern wrote: >> For ifaddrmsg ifa_flags aligns with ifi_type which is set by kernel side >> so this should be ok. > > Does the existing user space set ifi_type to anything? Does it zero out > the field? > > Are we able to find a flag value that is not going to be set by unaware > user space? I.e., a bit that is unused by the current ARPHRD values on > both little and big endian? (ARPHRD_NONE might be a problem, though...) The goal is for userpsace to pass something to the kernel to definitively state which header is used. ifaddrmsg (proper header and one Christian's patch wants to use) is 8 bytes; ifinfomsg (legacy header from broken userspace) is 16. If you can not trust that ifi_type is currently 0 on a dump request then you can not trust ifi_flags to be correct or ifi_change to be correct and so you can not move past the header and parse attributes. If that is the case we are done - Christian's patches should be reverted as you can never trust what is beyond the family entry. But I do not believe that to be the case because of the route dump analogy. As I mentioned route dumps have the same problem: sometimes ifinfomsg is passed and sometimes rtmsg. Yet the kernel always looks at rtm_flags. In terms of which field to use the most logical to me is to pass in a flag. Current address dumps have no reason to pass in a flag so it is not like the field can be misinterpreted. ifa_flags is a single byte so are there really endian issues to worry about? ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: netlink: 16 bytes leftover after parsing attributes in process `ip'. 2018-09-26 14:54 ` David Ahern @ 2018-09-26 15:02 ` Stephen Hemminger 0 siblings, 0 replies; 11+ messages in thread From: Stephen Hemminger @ 2018-09-26 15:02 UTC (permalink / raw) To: David Ahern Cc: Jiri Benc, Christian Brauner, netdev@vger.kernel.org, David Miller On Wed, 26 Sep 2018 08:54:43 -0600 David Ahern <dsahern@gmail.com> wrote: > On 9/25/18 11:51 PM, Jiri Benc wrote: > > On Tue, 25 Sep 2018 09:37:41 -0600, David Ahern wrote: > >> For ifaddrmsg ifa_flags aligns with ifi_type which is set by kernel side > >> so this should be ok. > > > > Does the existing user space set ifi_type to anything? Does it zero out > > the field? > > > > Are we able to find a flag value that is not going to be set by unaware > > user space? I.e., a bit that is unused by the current ARPHRD values on > > both little and big endian? (ARPHRD_NONE might be a problem, though...) > > The goal is for userpsace to pass something to the kernel to > definitively state which header is used. > You can not safely assume anything about older code. iproute2 is not the only thing using the API, others include Quagga, and other tools. Sorry, this API is frozen. ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: netlink: 16 bytes leftover after parsing attributes in process `ip'. 2018-09-25 15:37 ` David Ahern 2018-09-26 5:51 ` Jiri Benc @ 2018-09-26 9:49 ` Christian Brauner 1 sibling, 0 replies; 11+ messages in thread From: Christian Brauner @ 2018-09-26 9:49 UTC (permalink / raw) To: David Ahern; +Cc: Jiri Benc, netdev@vger.kernel.org, David Miller [-- Attachment #1: Type: text/plain, Size: 4411 bytes --] On Tue, Sep 25, 2018 at 09:37:41AM -0600, David Ahern wrote: > On 9/25/18 8:47 AM, Jiri Benc wrote: > > On Tue, 25 Sep 2018 11:49:10 +0200, Christian Brauner wrote: > >> So if people really want to hide this issue as much as we can then we > >> can play the guessing game. I could send a patch that roughly does the > >> following: > >> > >> if (nlmsg_len(cb->nlh) < sizeof(struct ifinfomsg)) > >> guessed_header_len = sizeof(struct ifaddrmsg); > >> else > >> guessed_header_len = sizeof(struct ifinfomsg); > >> > >> This will work since sizeof(ifaddrmsg) == 8 and sizeof(ifinfomsg) == 16. > >> The only valid property for RTM_GETADDR requests is IFA_TARGET_NETNSID. > >> This propert is a __s32 which should bring the message up to 12 bytes > >> (not sure about alignment requiremnts and where we might wend up ten) > >> which is still less than the 16 bytes without that property from > >> ifinfomsg. That's a hacky hacky hack-hack and will likely work but will > >> break when ifaddrmsg grows a new member or we introduce another property > >> that is valid in RTM_GETADDR requests. It also will not work cleanly > >> when users stuff additional properties in there that are vaif (nlmsg_parse(cb->nlh, sizeof(struct ifaddrmsg), tb, IFA_MAX,lid for the > >> address family but are not used int RTM_GETADDR requests. > > > > I'd expect that any potential existing code that makes use of other > > attributes already assumes ifaddrmsg. Hence, if the nlmsg_len is > > > sizeof(ifinfomsg), you can be sure that there are attributes and thus > > the struct used was ifaddrmsg. > > > > So, in order for RTM_GETADDR to work reliably with attributes, you have > > to ensure that the length is > sizeof(ifinfomsg). > > One of the many on-going efforts I have in progress is kernel side > filtering of route dumps. It has this same problem. For it I am > proposing a new flag: > > #define RTM_F_PROPER_HEADER 0x4000 > > ifinfomsg is 16 bytes which is > rtmsg at 12. If the message length is > > 16, then rtm_flags can be checked to know if the proper header is sent. > > For ifaddrmsg things do not line up as well. Worst all of the flag bits > are used. But, perhaps one can be overloaded with the limit that you can > never filter on its presence. Since you are adding the first filter to > address dumps such a limitation should be ok. > > For example something like this (whitespace damaged on paste) to remove > the guess work: > > diff --git a/include/uapi/linux/if_addr.h b/include/uapi/linux/if_addr.h > index dfcf3ce0097f..8e3e9d475db5 100644 > --- a/include/uapi/linux/if_addr.h > +++ b/include/uapi/linux/if_addr.h > @@ -41,6 +41,11 @@ enum { > #define IFA_MAX (__IFA_MAX - 1) > > /* ifa_flags */ > +/* IFA_F_PROPER_HEADER is only set in ifa_flags for dumps > + * to indicate the ancillary header is the expected ifaddrmsg > + * vs ifinfomsg from legacy userspace > + */ > +#define IFA_F_PROPER_HEADER 0x01 > #define IFA_F_SECONDARY 0x01 > #define IFA_F_TEMPORARY IFA_F_SECONDARY > > diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c > index bfe3ec7ecb14..256b9f88db8f 100644 > --- a/net/ipv6/addrconf.c > +++ b/net/ipv6/addrconf.c > @@ -5022,8 +5022,13 @@ static int inet6_dump_addr(struct sk_buff *skb, > struct netlink_callback *cb, > s_idx = idx = cb->args[1]; > s_ip_idx = ip_idx = cb->args[2]; > > - if (nlmsg_parse(cb->nlh, sizeof(struct ifaddrmsg), tb, IFA_MAX, > - ifa_ipv6_policy, NULL) >= 0) { > + if (nlmsg_len(cb->nlh) >= sizeof(struct ifaddrmsg) && > + ((struct ifaddrmsg *) nlmsg_data(cb->nlh))->ifa_flags & > IFA_F_PROPER_HEADER) { > + > + if (nlmsg_parse(cb->nlh, sizeof(struct ifaddrmsg), tb, > IFA_MAX, > + ifa_ipv6_policy, NULL) >= 0) { > + ... > + > if (tb[IFA_TARGET_NETNSID]) { > netnsid = nla_get_s32(tb[IFA_TARGET_NETNSID]); > > > For ifaddrmsg ifa_flags aligns with ifi_type which is set by kernel side > so this should be ok. I like this idea way more than forcing userspace to create a nested attribute. If Jiri's question is answered can we get this patch on the road soon? Are you happy to send it on-top of net-next or do you want me to do it? Christian [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 833 bytes --] ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2018-09-26 21:16 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2018-09-25 3:19 netlink: 16 bytes leftover after parsing attributes in process `ip' David Ahern 2018-09-25 9:49 ` Christian Brauner 2018-09-25 12:07 ` Stephen Hemminger [not found] ` <CAHrFyr55vt78akhC+WE5maDPLzmurUeB6wT-DmHcCmnAfPKrgw@mail.gmail.com> 2018-09-25 13:16 ` Stephen Hemminger 2018-09-26 10:45 ` Christian Brauner 2018-09-25 14:47 ` Jiri Benc 2018-09-25 15:37 ` David Ahern 2018-09-26 5:51 ` Jiri Benc 2018-09-26 14:54 ` David Ahern 2018-09-26 15:02 ` Stephen Hemminger 2018-09-26 9:49 ` Christian Brauner
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).