• Florian Westphal's avatar
    netfilter: ebtables: reject bogus getopt len value · 5c04da55
    Florian Westphal authored
    syzkaller reports splat:
    ------------[ cut here ]------------
    Buffer overflow detected (80 < 137)!
    Call Trace:
     do_ebt_get_ctl+0x2b4/0x790 net/bridge/netfilter/ebtables.c:2317
     nf_getsockopt+0x72/0xd0 net/netfilter/nf_sockopt.c:116
     ip_getsockopt net/ipv4/ip_sockglue.c:1778 [inline]
    
    caused by a copy-to-user with a too-large "*len" value.
    This adds a argument check on *len just like in the non-compat version
    of the handler.
    
    Before the "Fixes" commit, the reproducer fails with -EINVAL as
    expected:
    1. core calls the "compat" getsockopt version
    2. compat getsockopt version detects the *len value is possibly
       in 64-bit layout (*len != compat_len)
    3. compat getsockopt version delegates everything to native getsockopt
       version
    4. native getsockopt rejects invalid *len
    
    -> compat handler only sees len == sizeof(compat_struct) for GET_ENTRIES.
    
    After the refactor, event sequence is:
    1. getsockopt calls "compat" version (len != native_len)
    2. compat version attempts to copy *len bytes, where *len is random
       value from userspace
    
    Fixes: fc66de8e ("netfilter/ebtables: clean up compat {get, set}sockopt handling")
    Reported-by: syzbot+5accb5c62faa1d346480@syzkaller.appspotmail.com
    Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
    Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
    Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
    5c04da55
ebtables.c 61.7 KB