Commit Graph

146 Commits

Author SHA1 Message Date
Petr Oros b0a62f285a genetlink: introduce helpers to do filtered multicast
JIRA: https://issues.redhat.com/browse/RHEL-30145

Upstream commit(s):
commit 971b4ad88293bef00160e1d38659077fe3a93af6
Author: Jiri Pirko <jiri@nvidia.com>
Date:   Sat Dec 16 13:29:59 2023 +0100

    genetlink: introduce helpers to do filtered multicast

    Currently it is possible for netlink kernel user to pass custom
    filter function to broadcast send function netlink_broadcast_filtered().
    However, this is not exposed to multicast send and to generic
    netlink users.

    Extend the api and introduce a netlink helper nlmsg_multicast_filtered()
    and a generic netlink helper genlmsg_multicast_netns_filtered()
    to allow generic netlink families to specify filter function
    while sending multicast messages.

    Signed-off-by: Jiri Pirko <jiri@nvidia.com>
    Signed-off-by: Paolo Abeni <pabeni@redhat.com>

Signed-off-by: Petr Oros <poros@redhat.com>
2024-04-26 17:16:10 +02:00
Petr Oros 147089bf66 rtnetlink: introduce nlmsg_new_large and use it in rtnl_getlink
JIRA: https://issues.redhat.com/browse/RHEL-30145

Upstream commit(s):
commit ac40916a3f7243efbe6e129ebf495b5c33a3adfe
Author: Li RongQing <lirongqing@baidu.com>
Date:   Wed Nov 15 20:01:08 2023 +0800

    rtnetlink: introduce nlmsg_new_large and use it in rtnl_getlink

    if a PF has 256 or more VFs, ip link command will allocate an order 3
    memory or more, and maybe trigger OOM due to memory fragment,
    the VFs needed memory size is computed in rtnl_vfinfo_size.

    so introduce nlmsg_new_large which calls netlink_alloc_large_skb in
    which vmalloc is used for large memory, to avoid the failure of
    allocating memory

        ip invoked oom-killer: gfp_mask=0xc2cc0(GFP_KERNEL|__GFP_NOWARN|\
            __GFP_COMP|__GFP_NOMEMALLOC), order=3, oom_score_adj=0
        CPU: 74 PID: 204414 Comm: ip Kdump: loaded Tainted: P           OE
        Call Trace:
        dump_stack+0x57/0x6a
        dump_header+0x4a/0x210
        oom_kill_process+0xe4/0x140
        out_of_memory+0x3e8/0x790
        __alloc_pages_slowpath.constprop.116+0x953/0xc50
        __alloc_pages_nodemask+0x2af/0x310
        kmalloc_large_node+0x38/0xf0
        __kmalloc_node_track_caller+0x417/0x4d0
        __kmalloc_reserve.isra.61+0x2e/0x80
        __alloc_skb+0x82/0x1c0
        rtnl_getlink+0x24f/0x370
        rtnetlink_rcv_msg+0x12c/0x350
        netlink_rcv_skb+0x50/0x100
        netlink_unicast+0x1b2/0x280
        netlink_sendmsg+0x355/0x4a0
        sock_sendmsg+0x5b/0x60
        ____sys_sendmsg+0x1ea/0x250
        ___sys_sendmsg+0x88/0xd0
        __sys_sendmsg+0x5e/0xa0
        do_syscall_64+0x33/0x40
        entry_SYSCALL_64_after_hwframe+0x44/0xa9
        RIP: 0033:0x7f95a65a5b70

    Cc: Yunsheng Lin <linyunsheng@huawei.com>
    Signed-off-by: Li RongQing <lirongqing@baidu.com>
    Link: https://lore.kernel.org/r/20231115120108.3711-1-lirongqing@baidu.com
    Signed-off-by: Jakub Kicinski <kuba@kernel.org>

Signed-off-by: Petr Oros <poros@redhat.com>
2024-04-26 17:16:06 +02:00
Petr Oros 471e234dcd netlink: make range pointers in policies const
JIRA: https://issues.redhat.com/browse/RHEL-30145

Conflicts:
- Unmerged path(s) missing in rhel: drivers/net/vxlan/vxlan_mdb.c
  net/ipv6/ioam6_iptunnel.c

Upstream commit(s):
commit ea23fbd2a8f7dadfa9cd9b9d73f3b8a69eec0671
Author: Jakub Kicinski <kuba@kernel.org>
Date:   Wed Oct 25 09:22:04 2023 -0700

    netlink: make range pointers in policies const

    struct nla_policy is usually constant itself, but unless
    we make the ranges inside constant we won't be able to
    make range structs const. The ranges are not modified
    by the core.

    Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
    Reviewed-by: David Ahern <dsahern@kernel.org>
    Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
    Reviewed-by: Jiri Pirko <jiri@nvidia.com>
    Link: https://lore.kernel.org/r/20231025162204.132528-1-kuba@kernel.org
    Signed-off-by: Jakub Kicinski <kuba@kernel.org>

Signed-off-by: Petr Oros <poros@redhat.com>
2024-04-26 17:16:04 +02:00
Petr Oros e942232c80 netlink: add variable-length / auto integers
JIRA: https://issues.redhat.com/browse/RHEL-30145

Upstream commit(s):
commit 374d345d9b5e13380c66d7042f9533a6ac6d1195
Author: Jakub Kicinski <kuba@kernel.org>
Date:   Wed Oct 18 14:39:20 2023 -0700

    netlink: add variable-length / auto integers

    We currently push everyone to use padding to align 64b values
    in netlink. Un-padded nla_put_u64() doesn't even exist any more.

    The story behind this possibly start with this thread:
    https://lore.kernel.org/netdev/20121204.130914.1457976839967676240.davem@davemloft.net/
    where DaveM was concerned about the alignment of a structure
    containing 64b stats. If user space tries to access such struct
    directly:

            struct some_stats *stats = nla_data(attr);
            printf("A: %llu", stats->a);

    lack of alignment may become problematic for some architectures.
    These days we most often put every single member in a separate
    attribute, meaning that the code above would use a helper like
    nla_get_u64(), which can deal with alignment internally.
    Even for arches which don't have good unaligned access - access
    aligned to 4B should be pretty efficient.
    Kernel and well known libraries deal with unaligned input already.

    Padded 64b is quite space-inefficient (64b + pad means at worst 16B
    per attr vs 32b which takes 8B). It is also more typing:

        if (nla_put_u64_pad(rsp, NETDEV_A_SOMETHING_SOMETHING,
                            value, NETDEV_A_SOMETHING_PAD))

    Create a new attribute type which will use 32 bits at netlink
    level if value is small enough (probably most of the time?),
    and (4B-aligned) 64 bits otherwise. Kernel API is just:

        if (nla_put_uint(rsp, NETDEV_A_SOMETHING_SOMETHING, value))

    Calling this new type "just" sint / uint with no specific size
    will hopefully also make people more comfortable with using it.
    Currently telling people "don't use u8, you may need the bits,
    and netlink will round up to 4B, anyway" is the #1 comment
    we give to newcomers.

    In terms of netlink layout it looks like this:

             0       4       8       12      16
    32b:     [nlattr][ u32  ]
    64b:     [  pad ][nlattr][     u64      ]
    uint(32) [nlattr][ u32  ]
    uint(64) [nlattr][     u64      ]

    Signed-off-by: Jakub Kicinski <kuba@kernel.org>
    Acked-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>

Signed-off-by: Petr Oros <poros@redhat.com>
2024-04-26 17:16:03 +02:00
Ivan Vecera 925381f8e9 netlink: allow be16 and be32 types in all uint policy checks
JIRA: https://issues.redhat.com/browse/RHEL-30656

commit 5fac9b7c16c50c6c7699517f582b56e3743f453a
Author: Florian Westphal <fw@strlen.de>
Date:   Tue Jul 18 09:52:29 2023 +0200

    netlink: allow be16 and be32 types in all uint policy checks

    __NLA_IS_BEINT_TYPE(tp) isn't useful.  NLA_BE16/32 are identical to
    NLA_U16/32, the only difference is that it tells the netlink validation
    functions that byteorder conversion might be needed before comparing
    the value to the policy min/max ones.

    After this change all policy macros that can be used with UINT types,
    such as NLA_POLICY_MASK() can also be used with NLA_BE16/32.

    This will be used to validate nf_tables flag attributes which
    are in bigendian byte order.

    Signed-off-by: Florian Westphal <fw@strlen.de>

Signed-off-by: Ivan Vecera <ivecera@redhat.com>
2024-04-10 09:19:27 +02:00
Ivan Vecera 89f11d66d7 net: netlink: recommend policy range validation
JIRA: https://issues.redhat.com/browse/RHEL-30344

commit 70eb3911d80f548a76fb9a40c8a3fd93ac061a42
Author: Johannes Berg <johannes.berg@intel.com>
Date:   Fri Jan 27 08:45:06 2023 +0100

    net: netlink: recommend policy range validation

    For large ranges (outside of s16) the documentation currently
    recommends open-coding the validation, but it's better to use
    the NLA_POLICY_FULL_RANGE() or NLA_POLICY_FULL_RANGE_SIGNED()
    policy validation instead; recommend that.

    Signed-off-by: Johannes Berg <johannes.berg@intel.com>
    Reviewed-by: Ido Schimmel <idosch@nvidia.com>
    Link: https://lore.kernel.org/r/20230127084506.09f280619d64.I5dece85f06efa8ab0f474ca77df9e26d3553d4ab@changeid
    Signed-off-by: Jakub Kicinski <kuba@kernel.org>

Signed-off-by: Ivan Vecera <ivecera@redhat.com>
2024-04-02 11:15:39 +02:00
Ivan Vecera 38f3d6cdb1 netlink: introduce bigendian integer types
JIRA: https://issues.redhat.com/browse/RHEL-30344

commit ecaf75ffd5f5db320d8b1da0198eef5a5ce64a3f
Author: Florian Westphal <fw@strlen.de>
Date:   Mon Oct 31 13:34:07 2022 +0100

    netlink: introduce bigendian integer types

    Jakub reported that the addition of the "network_byte_order"
    member in struct nla_policy increases size of 32bit platforms.

    Instead of scraping the bit from elsewhere Johannes suggested
    to add explicit NLA_BE types instead, so do this here.

    NLA_POLICY_MAX_BE() macro is removed again, there is no need
    for it: NLA_POLICY_MAX(NLA_BE.., ..) will do the right thing.

    NLA_BE64 can be added later.

    Fixes: 08724ef69907 ("netlink: introduce NLA_POLICY_MAX_BE")
    Reported-by: Jakub Kicinski <kuba@kernel.org>
    Suggested-by: Johannes Berg <johannes@sipsolutions.net>
    Signed-off-by: Florian Westphal <fw@strlen.de>
    Link: https://lore.kernel.org/r/20221031123407.9158-1-fw@strlen.de
    Signed-off-by: Jakub Kicinski <kuba@kernel.org>

Signed-off-by: Ivan Vecera <ivecera@redhat.com>
2024-04-02 11:15:38 +02:00
Ivan Vecera e3ad0f633f rtnetlink: pass netlink message header and portid to rtnl_configure_link()
JIRA: https://issues.redhat.com/browse/RHEL-30344

commit 1d997f1013079c05b642c739901e3584a3ae558d
Author: Hangbin Liu <liuhangbin@gmail.com>
Date:   Fri Oct 28 04:42:21 2022 -0400

    rtnetlink: pass netlink message header and portid to rtnl_configure_link()

    This patch pass netlink message header and portid to rtnl_configure_link()
    All the functions in this call chain need to add the parameters so we can
    use them in the last call rtnl_notify(), and notify the userspace about
    the new link info if NLM_F_ECHO flag is set.

    - rtnl_configure_link()
      - __dev_notify_flags()
        - rtmsg_ifinfo()
          - rtmsg_ifinfo_event()
            - rtmsg_ifinfo_build_skb()
            - rtmsg_ifinfo_send()
              - rtnl_notify()

    Also move __dev_notify_flags() declaration to net/core/dev.h, as Jakub
    suggested.

    Signed-off-by: Hangbin Liu <liuhangbin@gmail.com>
    Reviewed-by: Guillaume Nault <gnault@redhat.com>
    Signed-off-by: Jakub Kicinski <kuba@kernel.org>

Signed-off-by: Ivan Vecera <ivecera@redhat.com>
2024-04-02 11:15:37 +02:00
Ivan Vecera 039cbecfe1 netlink: split up copies in the ack construction
JIRA: https://issues.redhat.com/browse/RHEL-30344

commit 738136a0e3757a8534df3ad97d6ff6d7f429f6c1
Author: Jakub Kicinski <kuba@kernel.org>
Date:   Thu Oct 27 14:25:53 2022 -0700

    netlink: split up copies in the ack construction

    Clean up the use of unsafe_memcpy() by adding a flexible array
    at the end of netlink message header and splitting up the header
    and data copies.

    Reviewed-by: Kees Cook <keescook@chromium.org>
    Signed-off-by: Jakub Kicinski <kuba@kernel.org>
    Signed-off-by: David S. Miller <davem@davemloft.net>

Signed-off-by: Ivan Vecera <ivecera@redhat.com>
2024-04-02 11:15:37 +02:00
Ivan Vecera 42352dcfd8 netlink: hide validation union fields from kdoc
JIRA: https://issues.redhat.com/browse/RHEL-30344

commit 7354c9024f2835f6122ed9612e21ab379df050f9
Author: Jakub Kicinski <kuba@kernel.org>
Date:   Thu Oct 27 14:21:07 2022 -0700

    netlink: hide validation union fields from kdoc

    Mark the validation fields as private, users shouldn't set
    them directly and they are too complicated to explain in
    a more succinct way (there's already a long explanation
    in the comment above).

    The strict_start_type field is set directly and has a dedicated
    comment so move that above the "private" section.

    Link: https://lore.kernel.org/r/20221027212107.2639255-1-kuba@kernel.org
    Signed-off-by: Jakub Kicinski <kuba@kernel.org>

Signed-off-by: Ivan Vecera <ivecera@redhat.com>
2024-04-02 11:15:37 +02:00
Ivan Vecera 6ef1376225 netlink: introduce NLA_POLICY_MAX_BE
JIRA: https://issues.redhat.com/browse/RHEL-30344

commit 08724ef69907214ce622344fe4945412e38368f0
Author: Florian Westphal <fw@strlen.de>
Date:   Mon Sep 5 12:09:36 2022 +0200

    netlink: introduce NLA_POLICY_MAX_BE

    netlink allows to specify allowed ranges for integer types.
    Unfortunately, nfnetlink passes integers in big endian, so the existing
    NLA_POLICY_MAX() cannot be used.

    At the moment, nfnetlink users, such as nf_tables, need to resort to
    programmatic checking via helpers such as nft_parse_u32_check().

    This is both cumbersome and error prone.  This adds NLA_POLICY_MAX_BE
    which adds range check support for BE16, BE32 and BE64 integers.

    Signed-off-by: Florian Westphal <fw@strlen.de>
    Signed-off-by: David S. Miller <davem@davemloft.net>

Signed-off-by: Ivan Vecera <ivecera@redhat.com>
2024-03-26 15:41:50 +01:00
Ivan Vecera 03626b89e8 netlink: fix some kernel-doc comments
JIRA: https://issues.redhat.com/browse/RHEL-30344

commit 0bf73255d3a3cf3b0416e95f2c9f7c53095c2e1a
Author: Zhengchao Shao <shaozhengchao@huawei.com>
Date:   Wed Aug 24 09:36:21 2022 +0800

    netlink: fix some kernel-doc comments

    Modify the comment of input parameter of nlmsg_ and nla_ function.

    Signed-off-by: Zhengchao Shao <shaozhengchao@huawei.com>
    Link: https://lore.kernel.org/r/20220824013621.365103-1-shaozhengchao@huawei.com
    Signed-off-by: Jakub Kicinski <kuba@kernel.org>

Signed-off-by: Ivan Vecera <ivecera@redhat.com>
2024-03-26 15:41:50 +01:00
Ivan Vecera 2792cda806 net: netlink: add the case when nlh is NULL
JIRA: https://issues.redhat.com/browse/RHEL-30344

commit f9b282b36dfa9b6c6d6b3e8816cdf0e4defff482
Author: Yajun Deng <yajun.deng@linux.dev>
Date:   Tue Jul 27 11:41:41 2021 +0800

    net: netlink: add the case when nlh is NULL

    Add the case when nlh is NULL in nlmsg_report(),
    so that the caller doesn't need to deal with this case.

    Signed-off-by: Yajun Deng <yajun.deng@linux.dev>
    Signed-off-by: David S. Miller <davem@davemloft.net>

Signed-off-by: Ivan Vecera <ivecera@redhat.com>
2024-03-26 14:44:57 +01:00
Sabrina Dubroca 71e2d7b190 net: add reserved fields to nla_policy
JIRA: https://issues.redhat.com/browse/RHEL-21356
Upstream Status: RHEL-only

struct nla_policy is protected by kABI, add 4 reserved fields.

Signed-off-by: Sabrina Dubroca <sdubroca@redhat.com>
2024-01-12 14:27:38 +01:00
Francis Laniel 872f690341 treewide: rename nla_strlcpy to nla_strscpy.
Calls to nla_strlcpy are now replaced by calls to nla_strscpy which is the new
name of this function.

Signed-off-by: Francis Laniel <laniel_francis@privacyrequired.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2020-11-16 08:08:54 -08:00
Francis Laniel 9ca718743a Modify return value of nla_strlcpy to match that of strscpy.
nla_strlcpy now returns -E2BIG if src was truncated when written to dst.
It also returns this error value if dstsize is 0 or higher than INT_MAX.

For example, if src is "foo\0" and dst is 3 bytes long, the result will be:
1. "foG" after memcpy (G means garbage).
2. "fo\0" after memset.
3. -E2BIG is returned because src was not completely written into dst.

The callers of nla_strlcpy were modified to take into account this modification.

Signed-off-by: Francis Laniel <laniel_francis@privacyrequired.com>
Reviewed-by: Kees Cook <keescook@chromium.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2020-11-16 08:08:54 -08:00
Johannes Berg 44f3625bc6 netlink: export policy in extended ACK
Add a new attribute NLMSGERR_ATTR_POLICY to the extended ACK
to advertise the policy, e.g. if an attribute was out of range,
you'll know the range that's permissible.

Add new NL_SET_ERR_MSG_ATTR_POL() and NL_SET_ERR_MSG_ATTR_POL()
macros to set this, since realistically it's only useful to do
this when the bad attribute (offset) is also returned.

Use it in lib/nlattr.c which practically does all the policy
validation.

v2:
 - add and use netlink_policy_dump_attr_size_estimate()
v3:
 - remove redundant break
v4:
 - really remove redundant break ... sorry

Reviewed-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
2020-10-09 20:22:32 -07:00
Jakub Kicinski bdbb4e29df netlink: add mask validation
We don't have good validation policy for existing unsigned int attrs
which serve as flags (for new ones we could use NLA_BITFIELD32).
With increased use of policy dumping having the validation be
expressed as part of the policy is important. Add validation
policy in form of a mask of supported/valid bits.

Support u64 in the uAPI to be future-proof, but really for now
the embedded mask member can only hold 32 bits, so anything with
bit 32+ set will always fail validation.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-06 06:25:55 -07:00
Jakub Kicinski ddcf3b70c5 netlink: create helpers for checking type is an int
There's a number of policies which check if type is a uint or sint.
Factor the checking against the list of value sizes to a helper
for easier reuse.

v2: - new patch

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-06 06:25:55 -07:00
Johannes Berg 04a351a62b netlink: rework policy dump to support multiple policies
Rework the policy dump code a bit to support adding multiple
policies to a single dump, in order to e.g. support per-op
policies in generic netlink.

v2:
 - move kernel-doc to implementation [Jakub]
 - squash the first patch to not flip-flop on the prototype
   [Jakub]
 - merge netlink_policy_dump_get_policy_idx() with the old
   get_policy_idx() we already had
 - rebase without Jakub's patch to have per-op dump

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-03 14:18:29 -07:00
Jakub Kicinski adc848450f genetlink: add a structure for dump state
Whenever netlink dump uses more than 2 cb->args[] entries
code gets hard to read. We're about to add more state to
ctrl_dumppolicy() so create a structure.

Since the structure is typed and clearly named we can remove
the local fam_id variable and use ctx->fam_id directly.

v3:
 - rebase onto explicit free fix
v1:
 - s/nl_policy_dump/netlink_policy_dump_state/
 - forward declare struct netlink_policy_dump_state,
   and move from passing unsigned long to actual pointer type
 - add build bug on
 - u16 fam_id
 - s/args/ctx/

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 19:11:12 -07:00
Johannes Berg 949ca6b82e netlink: fix policy dump leak
[ Upstream commit a95bc734e6 ]

If userspace doesn't complete the policy dump, we leak the
allocated state. Fix this.

Fixes: d07dcf9aad ("netlink: add infrastructure to expose policies to userspace")
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Reviewed-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-10-02 13:07:42 -07:00
David S. Miller 3ab0a7a0c3 Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Two minor conflicts:

1) net/ipv4/route.c, adding a new local variable while
   moving another local variable and removing it's
   initial assignment.

2) drivers/net/dsa/microchip/ksz9477.c, overlapping changes.
   One pretty prints the port mode differently, whilst another
   changes the driver to try and obtain the port mode from
   the port node rather than the switch node.

Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-22 16:45:34 -07:00
Nicolas Dichtel 553d87b658 netlink: fix doc about nlmsg_parse/nla_validate
There is no @validate argument.

CC: Johannes Berg <johannes.berg@intel.com>
Fixes: 3de6440354 ("netlink: re-add parse/validate functions in strict mode")
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-09-10 15:13:43 -07:00
Johannes Berg 8aa26c575f netlink: make NLA_BINARY validation more flexible
Add range validation for NLA_BINARY, allowing validation of any
combination of combination minimum or maximum lengths, using the
existing NLA_POLICY_RANGE()/NLA_POLICY_FULL_RANGE() macros, just
like for integers where the value is checked.

Also make NLA_POLICY_EXACT_LEN(), NLA_POLICY_EXACT_LEN_WARN()
and NLA_POLICY_MIN_LEN() special cases of this, removing the old
types NLA_EXACT_LEN and NLA_MIN_LEN.

This allows us to save some code where both minimum and maximum
lengths are requires, currently the policy only allows maximum
(NLA_BINARY), minimum (NLA_MIN_LEN) or exact (NLA_EXACT_LEN), so
a range of lengths cannot be accepted and must be checked by the
code that consumes the attributes later.

Also, this allows advertising the correct ranges in the policy
export to userspace. Here, NLA_MIN_LEN and NLA_EXACT_LEN already
were special cases of NLA_BINARY with min and min/max length
respectively.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-08-18 12:28:45 -07:00
Johannes Berg d07dcf9aad netlink: add infrastructure to expose policies to userspace
Add, and use in generic netlink, helpers to dump out a netlink
policy to userspace, including all the range validation data,
nested policies etc.

This lets userspace discover what the kernel understands.

For families/commands other than generic netlink, the helpers
need to be used directly in an appropriate command, or we can
add some infrastructure (a new netlink family) that those can
register their policies with for introspection. I'm not that
familiar with non-generic netlink, so that's left out for now.

The data exposed to userspace also includes min and max length
for binary/string data, I've done that instead of letting the
userspace tools figure out whether min/max is intended based
on the type so that we can extend this later in the kernel, we
might want to just use the range data for example.

Because of this, I opted to not directly expose the NLA_*
values, even if some of them are already exposed via BPF, as
with min/max length we don't need to have different types here
for NLA_BINARY/NLA_MIN_LEN/NLA_EXACT_LEN, we just make them
all NL_ATTR_TYPE_BINARY with min/max length optionally set.

Similarly, we don't really need NLA_MSECS, and perhaps can
remove it in the future - but not if we encode it into the
userspace API now. It gets mapped to NL_ATTR_TYPE_U64 here.

Note that the exposing here corresponds to the strict policy
interpretation, and NLA_UNSPEC items are omitted entirely.
To get those, change them to NLA_MIN_LEN which behaves in
exactly the same way, but is exposed.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-04-30 17:51:42 -07:00
Johannes Berg 2c28ae48f2 netlink: factor out policy range helpers
Add helpers to get the policy's signed/unsigned range
validation data.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-04-30 17:51:42 -07:00
Johannes Berg c7721c05a6 netlink: remove NLA_EXACT_LEN_WARN
Use a validation type instead, so we can later expose
the NLA_* values to userspace for policy descriptions.

Some transformations were done with this spatch:

    @@
    identifier p;
    expression X, L, A;
    @@
    struct nla_policy p[X] = {
    [A] =
    -{ .type = NLA_EXACT_LEN_WARN, .len = L },
    +NLA_POLICY_EXACT_LEN_WARN(L),
    ...
    };

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-04-30 17:51:42 -07:00
Johannes Berg da4063bdfc netlink: allow NLA_MSECS to have range validation
Since NLA_MSECS is really equivalent to NLA_U64, allow
it to have range validation as well.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-04-30 17:51:42 -07:00
Johannes Berg d06a09b94c netlink: extend policy range validation
Using a pointer to a struct indicating the min/max values,
extend the ability to do range validation for arbitrary
values. Small values in the s16 range can be kept in the
policy directly.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-04-30 17:51:42 -07:00
Johannes Berg 47a1494b82 netlink: remove type-unsafe validation_data pointer
In the netlink policy, we currently have a void *validation_data
that's pointing to different things:
 * a u32 value for bitfield32,
 * the netlink policy for nested/nested array
 * the string for NLA_REJECT

Remove the pointer and place appropriate type-safe items in the
union instead.

While at it, completely dissolve the pointer for the bitfield32
case and just put the value there directly.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-04-30 17:51:41 -07:00
Jiri Pirko 8953b0770f net: introduce nla_put_bitfield32() helper and use it
Introduce a helper to pass value and selector to. The helper packs them
into struct and puts them into netlink message.

Signed-off-by: Jiri Pirko <jiri@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2020-03-30 11:06:49 -07:00
Michal Kubecek 32d5109a9d netlink: rename nl80211_validate_nested() to nla_validate_nested()
Function nl80211_validate_nested() is not specific to nl80211, it's
a counterpart to nla_validate_nested_deprecated() with strict validation.
For consistency with other validation and parse functions, rename it to
nla_validate_nested().

Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-12-12 17:07:05 -08:00
David Ahern d00ee64e1d netlink: Fix nlmsg_parse as a wrapper for strict message parsing
Eric reported a syzbot warning:

BUG: KMSAN: uninit-value in nh_valid_get_del_req+0x6f1/0x8c0 net/ipv4/nexthop.c:1510
CPU: 0 PID: 11812 Comm: syz-executor444 Not tainted 5.3.0-rc3+ #17
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Call Trace:
 __dump_stack lib/dump_stack.c:77 [inline]
 dump_stack+0x191/0x1f0 lib/dump_stack.c:113
 kmsan_report+0x162/0x2d0 mm/kmsan/kmsan_report.c:109
 __msan_warning+0x75/0xe0 mm/kmsan/kmsan_instr.c:294
 nh_valid_get_del_req+0x6f1/0x8c0 net/ipv4/nexthop.c:1510
 rtm_del_nexthop+0x1b1/0x610 net/ipv4/nexthop.c:1543
 rtnetlink_rcv_msg+0x115a/0x1580 net/core/rtnetlink.c:5223
 netlink_rcv_skb+0x431/0x620 net/netlink/af_netlink.c:2477
 rtnetlink_rcv+0x50/0x60 net/core/rtnetlink.c:5241
 netlink_unicast_kernel net/netlink/af_netlink.c:1302 [inline]
 netlink_unicast+0xf6c/0x1050 net/netlink/af_netlink.c:1328
 netlink_sendmsg+0x110f/0x1330 net/netlink/af_netlink.c:1917
 sock_sendmsg_nosec net/socket.c:637 [inline]
 sock_sendmsg net/socket.c:657 [inline]
 ___sys_sendmsg+0x14ff/0x1590 net/socket.c:2311
 __sys_sendmmsg+0x53a/0xae0 net/socket.c:2413
 __do_sys_sendmmsg net/socket.c:2442 [inline]
 __se_sys_sendmmsg+0xbd/0xe0 net/socket.c:2439
 __x64_sys_sendmmsg+0x56/0x70 net/socket.c:2439
 do_syscall_64+0xbc/0xf0 arch/x86/entry/common.c:297
 entry_SYSCALL_64_after_hwframe+0x63/0xe7

The root cause is nlmsg_parse calling __nla_parse which means the
header struct size is not checked.

nlmsg_parse should be a wrapper around __nlmsg_parse with
NL_VALIDATE_STRICT for the validate argument very much like
nlmsg_parse_deprecated is for NL_VALIDATE_LIBERAL.

Fixes: 3de6440354 ("netlink: re-add parse/validate functions in strict mode")
Reported-by: Eric Dumazet <edumazet@google.com>
Reported-by: syzbot <syzkaller@googlegroups.com>
Signed-off-by: David Ahern <dsahern@gmail.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
2019-08-13 20:37:16 -07:00
Ido Schimmel c82481f7ea netlink: Add field to skip in-kernel notifications
The struct includes a 'skip_notify' flag that indicates if netlink
notifications to user space should be suppressed. As explained in commit
3b1137fe74 ("net: ipv6: Change notifications for multipath add to
RTA_MULTIPATH"), this is useful to suppress per-nexthop RTM_NEWROUTE
notifications when an IPv6 multipath route is added / deleted. Instead,
one notification is sent for the entire multipath route.

This concept is also useful for in-kernel notifications. Sending one
in-kernel notification for the addition / deletion of an IPv6 multipath
route - instead of one per-nexthop - provides a significant increase in
the insertion / deletion rate to underlying devices.

Add a 'skip_notify_kernel' flag to suppress in-kernel notifications.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: David Ahern <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-06-18 09:45:36 -07:00
Ido Schimmel 3de205cde4 netlink: Document all fields of 'struct nl_info'
Some fields were not documented. Add documentation.

Signed-off-by: Ido Schimmel <idosch@mellanox.com>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Reviewed-by: David Ahern <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-06-18 09:45:36 -07:00
Johannes Berg 901bb98918 nl80211: require and validate vendor command policy
Require that each vendor command give a policy of its sub-attributes
in NL80211_ATTR_VENDOR_DATA, and then (stricly) check the contents,
including the NLA_F_NESTED flag that we couldn't check on the outer
layer because there we don't know yet.

It is possible to use VENDOR_CMD_RAW_DATA for raw data, but then no
nested data can be given (NLA_F_NESTED flag must be clear) and the
data is just passed as is to the command.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
2019-06-14 14:12:01 +02:00
Michal Kubecek b424e432e7 netlink: add validation of NLA_F_NESTED flag
Add new validation flag NL_VALIDATE_NESTED which adds three consistency
checks of NLA_F_NESTED_FLAG:

  - the flag is set on attributes with NLA_NESTED{,_ARRAY} policy
  - the flag is not set on attributes with other policies except NLA_UNSPEC
  - the flag is set on attribute passed to nla_parse_nested()

Signed-off-by: Michal Kubecek <mkubecek@suse.cz>

v2: change error messages to mention NLA_F_NESTED explicitly
Reviewed-by: Johannes Berg <johannes@sipsolutions.net>
Reviewed-by: David Ahern <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-05-04 01:27:11 -04:00
Johannes Berg 56738f4608 netlink: add strict parsing for future attributes
Unfortunately, we cannot add strict parsing for all attributes, as
that would break existing userspace. We currently warn about it, but
that's about all we can do.

For new attributes, however, the story is better: nobody is using
them, so we can reject bad sizes.

Also, for new attributes, we need not accept them when the policy
doesn't declare their usage.

David Ahern and I went back and forth on how to best encode this, and
the best way we found was to have a "boundary type", from which point
on new attributes have all possible validation applied, and NLA_UNSPEC
is rejected.

As we didn't want to add another argument to all functions that get a
netlink policy, the workaround is to encode that boundary in the first
entry of the policy array (which is for type 0 and thus probably not
really valid anyway). I put it into the validation union for the rare
possibility that somebody is actually using attribute 0, which would
continue to work fine unless they tried to use the extended validation,
which isn't likely. We also didn't find any in-tree users with type 0.

The reason for setting the "start strict here" attribute is that we
never really need to start strict from 0, which is invalid anyway (or
in legacy families where that isn't true, it cannot be set to strict),
so we can thus reserve the value 0 for "don't do this check" and don't
have to add the tag to all policies right now.

Thus, policies can now opt in to this validation, which we should do
for all existing policies, at least when adding new attributes.

Note that entirely *new* policies won't need to set it, as the use
of that should be using nla_parse()/nlmsg_parse() etc. which anyway
do fully strict validation now, regardless of this.

So in effect, this patch only covers the "existing command with new
attribute" case.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-04-27 17:07:22 -04:00
Johannes Berg 3de6440354 netlink: re-add parse/validate functions in strict mode
This re-adds the parse and validate functions like nla_parse()
that are now actually strict after the previous rename and were
just split out to make sure everything is converted (and if not
compilation of the previous patch would fail.)

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-04-27 17:07:22 -04:00
Johannes Berg 8cb081746c netlink: make validation more configurable for future strictness
We currently have two levels of strict validation:

 1) liberal (default)
     - undefined (type >= max) & NLA_UNSPEC attributes accepted
     - attribute length >= expected accepted
     - garbage at end of message accepted
 2) strict (opt-in)
     - NLA_UNSPEC attributes accepted
     - attribute length >= expected accepted

Split out parsing strictness into four different options:
 * TRAILING     - check that there's no trailing data after parsing
                  attributes (in message or nested)
 * MAXTYPE      - reject attrs > max known type
 * UNSPEC       - reject attributes with NLA_UNSPEC policy entries
 * STRICT_ATTRS - strictly validate attribute size

The default for future things should be *everything*.
The current *_strict() is a combination of TRAILING and MAXTYPE,
and is renamed to _deprecated_strict().
The current regular parsing has none of this, and is renamed to
*_parse_deprecated().

Additionally it allows us to selectively set one of the new flags
even on old policies. Notably, the UNSPEC flag could be useful in
this case, since it can be arranged (by filling in the policy) to
not be an incompatible userspace ABI change, but would then going
forward prevent forgetting attribute entries. Similar can apply
to the POLICY flag.

We end up with the following renames:
 * nla_parse           -> nla_parse_deprecated
 * nla_parse_strict    -> nla_parse_deprecated_strict
 * nlmsg_parse         -> nlmsg_parse_deprecated
 * nlmsg_parse_strict  -> nlmsg_parse_deprecated_strict
 * nla_parse_nested    -> nla_parse_nested_deprecated
 * nla_validate_nested -> nla_validate_nested_deprecated

Using spatch, of course:
    @@
    expression TB, MAX, HEAD, LEN, POL, EXT;
    @@
    -nla_parse(TB, MAX, HEAD, LEN, POL, EXT)
    +nla_parse_deprecated(TB, MAX, HEAD, LEN, POL, EXT)

    @@
    expression NLH, HDRLEN, TB, MAX, POL, EXT;
    @@
    -nlmsg_parse(NLH, HDRLEN, TB, MAX, POL, EXT)
    +nlmsg_parse_deprecated(NLH, HDRLEN, TB, MAX, POL, EXT)

    @@
    expression NLH, HDRLEN, TB, MAX, POL, EXT;
    @@
    -nlmsg_parse_strict(NLH, HDRLEN, TB, MAX, POL, EXT)
    +nlmsg_parse_deprecated_strict(NLH, HDRLEN, TB, MAX, POL, EXT)

    @@
    expression TB, MAX, NLA, POL, EXT;
    @@
    -nla_parse_nested(TB, MAX, NLA, POL, EXT)
    +nla_parse_nested_deprecated(TB, MAX, NLA, POL, EXT)

    @@
    expression START, MAX, POL, EXT;
    @@
    -nla_validate_nested(START, MAX, POL, EXT)
    +nla_validate_nested_deprecated(START, MAX, POL, EXT)

    @@
    expression NLH, HDRLEN, MAX, POL, EXT;
    @@
    -nlmsg_validate(NLH, HDRLEN, MAX, POL, EXT)
    +nlmsg_validate_deprecated(NLH, HDRLEN, MAX, POL, EXT)

For this patch, don't actually add the strict, non-renamed versions
yet so that it breaks compile if I get it wrong.

Also, while at it, make nla_validate and nla_parse go down to a
common __nla_validate_parse() function to avoid code duplication.

Ultimately, this allows us to have very strict validation for every
new caller of nla_parse()/nlmsg_parse() etc as re-introduced in the
next patch, while existing things will continue to work as is.

In effect then, this adds fully strict validation for any new command.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-04-27 17:07:21 -04:00
Johannes Berg 6f455f5f4e netlink: add NLA_MIN_LEN
Rather than using NLA_UNSPEC for this type of thing, use NLA_MIN_LEN
so we can make NLA_UNSPEC be NLA_REJECT under certain conditions for
future attributes.

While at it, also use NLA_EXACT_LEN for the struct example.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-04-27 17:07:21 -04:00
Michal Kubecek ae0be8de9a netlink: make nla_nest_start() add NLA_F_NESTED flag
Even if the NLA_F_NESTED flag was introduced more than 11 years ago, most
netlink based interfaces (including recently added ones) are still not
setting it in kernel generated messages. Without the flag, message parsers
not aware of attribute semantics (e.g. wireshark dissector or libmnl's
mnl_nlmsg_fprintf()) cannot recognize nested attributes and won't display
the structure of their contents.

Unfortunately we cannot just add the flag everywhere as there may be
userspace applications which check nlattr::nla_type directly rather than
through a helper masking out the flags. Therefore the patch renames
nla_nest_start() to nla_nest_start_noflag() and introduces nla_nest_start()
as a wrapper adding NLA_F_NESTED. The calls which add NLA_F_NESTED manually
are rewritten to use nla_nest_start().

Except for changes in include/net/netlink.h, the patch was generated using
this semantic patch:

@@ expression E1, E2; @@
-nla_nest_start(E1, E2)
+nla_nest_start_noflag(E1, E2)

@@ expression E1, E2; @@
-nla_nest_start_noflag(E1, E2 | NLA_F_NESTED)
+nla_nest_start(E1, E2)

Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
Acked-by: Jiri Pirko <jiri@mellanox.com>
Acked-by: David Ahern <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2019-04-27 17:03:44 -04:00
Johannes Berg 23323289b1 netlink: reduce NLA_POLICY_NESTED{,_ARRAY} arguments
In typical cases, there's no need to pass both the maxattr
and the policy array pointer, as the maxattr should just be
ARRAY_SIZE(policy) - 1. Therefore, to be less error prone,
just remove the maxattr argument from the default macros
and deduce the size accordingly.

Leave the original macros with a leading underscore to use
here and in case somebody needs to pass a policy pointer
where the policy isn't declared in the same place and thus
ARRAY_SIZE() cannot be used.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
2019-02-01 11:06:55 +01:00
Johannes Berg 5886d932e5 netlink: replace __NLA_ENSURE implementation
We already have BUILD_BUG_ON_ZERO() which I just hadn't found
before, so we should use it here instead of open-coding another
implementation thereof.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-10-12 11:00:22 -07:00
David Ahern a5f6cba291 netlink: Add strict version of nlmsg_parse and nla_parse
nla_parse is currently lenient on message parsing, allowing type to be 0
or greater than max expected and only logging a message

    "netlink: %d bytes leftover after parsing attributes in process `%s'."

if the netlink message has unknown data at the end after parsing. What this
could mean is that the header at the front of the attributes is actually
wrong and the parsing is shifted from what is expected.

Add a new strict version that actually fails with EINVAL if there are any
bytes remaining after the parsing loop completes, if the atttrbitue type
is 0 or greater than max expected.

Signed-off-by: David Ahern <dsahern@gmail.com>
Acked-by: Christian Brauner <christian@brauner.io>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-10-08 10:39:04 -07:00
David Ahern 3d0d4337d7 netlink: Add extack message to nlmsg_parse for invalid header length
Give a user a reason why EINVAL is returned in nlmsg_parse.

Signed-off-by: David Ahern <dsahern@gmail.com>
Acked-by: Christian Brauner <christian@brauner.io>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-10-08 10:39:03 -07:00
David S. Miller 6f41617bf2 Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Minor conflict in net/core/rtnetlink.c, David Ahern's bug fix in 'net'
overlapped the renaming of a netlink attribute in net-next.

Signed-off-by: David S. Miller <davem@davemloft.net>
2018-10-03 21:00:17 -07:00
Johannes Berg 33188bd643 netlink: add validation function to policy
Add the ability to have an arbitrary validation function attached
to a netlink policy that doesn't already use the validation_data
pointer in another way.

This can be useful to validate for example the content of a binary
attribute, like in nl80211 the "(information) elements", which must
be valid streams of "u8 type, u8 length, u8 value[length]".

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-10-01 23:05:31 -07:00
Johannes Berg 3e48be05f3 netlink: add attribute range validation to policy
Without further bloating the policy structs, we can overload
the `validation_data' pointer with a struct of s16 min, max
and use those to validate ranges in NLA_{U,S}{8,16,32,64}
attributes.

It may sound strange to validate NLA_U32 with a s16 max, but
in many cases NLA_U32 is used for enums etc. since there's no
size benefit in using a smaller attribute width anyway, due
to netlink attribute alignment; in cases like that it's still
useful, particularly when the attribute really transports an
enum value.

Doing so lets us remove quite a bit of validation code, if we
can be sure that these attributes aren't used by userspace in
places where they're ignored today.

To achieve all this, split the 'type' field and introduce a
new 'validation_type' field which indicates what further
validation (beyond the validation prescribed by the type of
the attribute) is done. This currently allows for no further
validation (the default), as well as min, max and range checks.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2018-10-01 23:05:31 -07:00