13 Mar, 2020

1 commit

  • Unlike other SET type commands, modifying netdev features is required to
    provide a reply telling userspace what was actually changed, compared to
    what was requested. For that purpose, the "modified" flag provided by
    ethnl_update_bitset() is not sufficient, we need full information which
    bits were requested to change.

    Therefore provide ethnl_parse_bitset() returning effective value and mask
    bitmaps equivalent to the contents of a bitset nested attribute.

    v2: use non-atomic __set_bit() (suggested by David Miller)

    Signed-off-by: Michal Kubecek
    Signed-off-by: David S. Miller

    Michal Kubecek
     

27 Feb, 2020

1 commit

  • Syzbot reported that ethnl_compact_sanity_checks() can be tricked into
    reading past the end of ETHTOOL_A_BITSET_VALUE and ETHTOOL_A_BITSET_MASK
    attributes and even the message by passing a value between (u32)(-31)
    and (u32)(-1) as ETHTOOL_A_BITSET_SIZE.

    The problem is that DIV_ROUND_UP(attr_nbits, 32) is 0 for such values so
    that zero length ETHTOOL_A_BITSET_VALUE will pass the length check but
    ethnl_bitmap32_not_zero() check would try to access up to 512 MB of
    attribute "payload".

    Prevent this overflow byt limiting the bitset size. Technically, compact
    bitset format would allow bitset sizes up to almost 2^18 (so that the
    nest size does not exceed U16_MAX) but bitsets used by ethtool are much
    shorter. S16_MAX, the largest value which can be directly used as an
    upper limit in policy, should be a reasonable compromise.

    Fixes: 10b518d4e6dd ("ethtool: netlink bitset handling")
    Reported-by: syzbot+7fd4ed5b4234ab1fdccd@syzkaller.appspotmail.com
    Reported-by: syzbot+709b7a64d57978247e44@syzkaller.appspotmail.com
    Reported-by: syzbot+983cb8fb2d17a7af549d@syzkaller.appspotmail.com
    Signed-off-by: Michal Kubecek
    Signed-off-by: David S. Miller

    Michal Kubecek
     

28 Dec, 2019

1 commit

  • The ethtool netlink code uses common framework for passing arbitrary
    length bit sets to allow future extensions. A bitset can be a list (only
    one bitmap) or can consist of value and mask pair (used e.g. when client
    want to modify only some bits). A bitset can use one of two formats:
    verbose (bit by bit) or compact.

    Verbose format consists of bitset size (number of bits), list flag and
    an array of bit nests, telling which bits are part of the list or which
    bits are in the mask and which of them are to be set. In requests, bits
    can be identified by index (position) or by name. In replies, kernel
    provides both index and name. Verbose format is suitable for "one shot"
    applications like standard ethtool command as it avoids the need to
    either keep bit names (e.g. link modes) in sync with kernel or having to
    add an extra roundtrip for string set request (e.g. for private flags).

    Compact format uses one (list) or two (value/mask) arrays of 32-bit
    words to store the bitmap(s). It is more suitable for long running
    applications (ethtool in monitor mode or network management daemons)
    which can retrieve the names once and then pass only compact bitmaps to
    save space.

    Userspace requests can use either format; ETHTOOL_FLAG_COMPACT_BITSETS
    flag in request header tells kernel which format to use in reply.
    Notifications always use compact format.

    As some code uses arrays of unsigned long for internal representation and
    some arrays of u32 (or even a single u32), two sets of parse/compose
    helpers are introduced. To avoid code duplication, helpers for unsigned
    long arrays are implemented as wrappers around helpers for u32 arrays.
    There are two reasons for this choice: (1) u32 arrays are more frequent in
    ethtool code and (2) unsigned long array can be always interpreted as an
    u32 array on little endian 64-bit and all 32-bit architectures while we
    would need special handling for odd number of u32 words in the opposite
    direction.

    Signed-off-by: Michal Kubecek
    Reviewed-by: Florian Fainelli
    Signed-off-by: David S. Miller

    Michal Kubecek