• Dmitry Safonov's avatar
    jump_label: Prevent key->enabled int overflow · eb8c5072
    Dmitry Safonov authored
    1. With CONFIG_JUMP_LABEL=n static_key_slow_inc() doesn't have any
       protection against key->enabled refcounter overflow.
    2. With CONFIG_JUMP_LABEL=y static_key_slow_inc_cpuslocked()
       still may turn the refcounter negative as (v + 1) may overflow.
    
    key->enabled is indeed a ref-counter as it's documented in multiple
    places: top comment in jump_label.h, Documentation/staging/static-keys.rst,
    etc.
    
    As -1 is reserved for static key that's in process of being enabled,
    functions would break with negative key->enabled refcount:
    - for CONFIG_JUMP_LABEL=n negative return of static_key_count()
      breaks static_key_false(), static_key_true()
    - the ref counter may become 0 from negative side by too many
      static_key_slow_inc() calls and lead to use-after-free issues.
    
    These flaws result in that some users have to introduce an additional
    mutex and prevent the reference counter from overflowing themselves,
    see bpf_enable_runtime_stats() checking the counter against INT_MAX / 2.
    
    Prevent the reference counter overflow by checking if (v + 1) > 0.
    Change functions API to return whether the increment was successful.
    Signed-off-by: default avatarDmitry Safonov <dima@arista.com>
    Acked-by: default avatarJakub Kicinski <kuba@kernel.org>
    Acked-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
    Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
    eb8c5072
jump_label.c 21.1 KB