• Jann Horn's avatar
    bpf: fix incorrect tracking of register size truncation · 0c17d1d2
    Jann Horn authored
    Properly handle register truncation to a smaller size.
    
    The old code first mirrors the clearing of the high 32 bits in the bitwise
    tristate representation, which is correct. But then, it computes the new
    arithmetic bounds as the intersection between the old arithmetic bounds and
    the bounds resulting from the bitwise tristate representation. Therefore,
    when coerce_reg_to_32() is called on a number with bounds
    [0xffff'fff8, 0x1'0000'0007], the verifier computes
    [0xffff'fff8, 0xffff'ffff] as bounds of the truncated number.
    This is incorrect: The truncated number could also be in the range [0, 7],
    and no meaningful arithmetic bounds can be computed in that case apart from
    the obvious [0, 0xffff'ffff].
    
    Starting with v4.14, this is exploitable by unprivileged users as long as
    the unprivileged_bpf_disabled sysctl isn't set.
    
    Debian assigned CVE-2017-16996 for this issue.
    
    v2:
     - flip the mask during arithmetic bounds calculation (Ben Hutchings)
    v3:
     - add CVE number (Ben Hutchings)
    
    Fixes: b03c9f9f ("bpf/verifier: track signed and unsigned min/max values")
    Signed-off-by: default avatarJann Horn <jannh@google.com>
    Acked-by: default avatarEdward Cree <ecree@solarflare.com>
    Signed-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
    Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
    0c17d1d2
verifier.c 136 KB