diff --git a/sys/netlink/netlink_message_parser.h b/sys/netlink/netlink_message_parser.h index 96fd1c7337b..3f64c1967f0 100644 --- a/sys/netlink/netlink_message_parser.h +++ b/sys/netlink/netlink_message_parser.h @@ -213,9 +213,19 @@ nl_parse_header(void *hdr, int len, const struct nlhdr_parser *parser, int error; if (__predict_false(len < parser->nl_hdr_off)) { - nlmsg_report_err_msg(npt, "header too short: expected %d, got %d", - parser->nl_hdr_off, len); - return (EINVAL); + if (npt->strict) { + nlmsg_report_err_msg(npt, "header too short: expected %d, got %d", + parser->nl_hdr_off, len); + return (EINVAL); + } + + /* Compat with older applications: pretend there's a full header */ + void *tmp_hdr = npt_alloc(npt, parser->nl_hdr_off); + if (tmp_hdr == NULL) + return (EINVAL); + memcpy(tmp_hdr, hdr, len); + hdr = tmp_hdr; + len = parser->nl_hdr_off; } if (npt->strict && parser->sp != NULL && !parser->sp(hdr, npt)) diff --git a/tests/sys/netlink/test_rtnl_ifaddr.py b/tests/sys/netlink/test_rtnl_ifaddr.py index bd1c55e268e..ec349fcd6fd 100644 --- a/tests/sys/netlink/test_rtnl_ifaddr.py +++ b/tests/sys/netlink/test_rtnl_ifaddr.py @@ -8,6 +8,7 @@ from atf_python.sys.net.netlink import NetlinkTestTemplate from atf_python.sys.net.netlink import NlConst from atf_python.sys.net.netlink import NlHelper from atf_python.sys.net.netlink import NlmBaseFlags +from atf_python.sys.net.netlink import Nlmsghdr from atf_python.sys.net.netlink import NlMsgType from atf_python.sys.net.netlink import NlRtMsgType from atf_python.sys.net.netlink import Nlsock @@ -68,6 +69,25 @@ class TestRtNlIfaddr(NetlinkTestTemplate, SingleVnetTestTemplate): assert len([r for r in ret if r[0] == ifname and r[1] == socket.AF_INET6]) == 2 assert len(ret) == 3 + def test_46_filter_family_compat(self): + """Tests that family filtering works with the stripped header""" + + hdr = Nlmsghdr( + nlmsg_len=17, + nlmsg_type=NlRtMsgType.RTM_GETADDR.value, + nlmsg_flags=NlmBaseFlags.NLM_F_ACK.value | NlmBaseFlags.NLM_F_REQUEST.value, + nlmsg_seq=self.helper.get_seq() + ) + data = bytes(hdr) + struct.pack("@B", socket.AF_INET) + self.nlsock.write_data(data) + + ret = [] + for rx_msg in self.read_msg_list(hdr.nlmsg_seq, NlRtMsgType.RTM_NEWADDR): + ifname = socket.if_indextoname(rx_msg.base_hdr.ifa_index) + family = rx_msg.base_hdr.ifa_family + ret.append((ifname, family, rx_msg)) + assert len(ret) == 2 + def filter_iface_family(self, family, num_items): """Tests that listing outputs IPv4 for the specific interface""" epair_ifname = self.vnet.iface_alias_map["if1"].name