Skip to content
  1. Dec 24, 2022
  2. Dec 17, 2022
  3. Dec 15, 2022
  4. Dec 03, 2022
  5. Dec 02, 2022
    • Kees Cook's avatar
      exit: Expose "oops_count" to sysfs · 9db89b41
      Kees Cook authored
      
      
      Since Oops count is now tracked and is a fairly interesting signal, add
      the entry /sys/kernel/oops_count to expose it to userspace.
      
      Cc: "Eric W. Biederman" <ebiederm@xmission.com>
      Cc: Jann Horn <jannh@google.com>
      Cc: Arnd Bergmann <arnd@arndb.de>
      Reviewed-by: default avatarLuis Chamberlain <mcgrof@kernel.org>
      Signed-off-by: default avatarKees Cook <keescook@chromium.org>
      Link: https://lore.kernel.org/r/20221117234328.594699-3-keescook@chromium.org
      9db89b41
    • Jann Horn's avatar
      exit: Put an upper limit on how often we can oops · d4ccd54d
      Jann Horn authored
      
      
      Many Linux systems are configured to not panic on oops; but allowing an
      attacker to oops the system **really** often can make even bugs that look
      completely unexploitable exploitable (like NULL dereferences and such) if
      each crash elevates a refcount by one or a lock is taken in read mode, and
      this causes a counter to eventually overflow.
      
      The most interesting counters for this are 32 bits wide (like open-coded
      refcounts that don't use refcount_t). (The ldsem reader count on 32-bit
      platforms is just 16 bits, but probably nobody cares about 32-bit platforms
      that much nowadays.)
      
      So let's panic the system if the kernel is constantly oopsing.
      
      The speed of oopsing 2^32 times probably depends on several factors, like
      how long the stack trace is and which unwinder you're using; an empirically
      important one is whether your console is showing a graphical environment or
      a text console that oopses will be printed to.
      In a quick single-threaded benchmark, it looks like oopsing in a vfork()
      child with a very short stack trace only takes ~510 microseconds per run
      when a graphical console is active; but switching to a text console that
      oopses are printed to slows it down around 87x, to ~45 milliseconds per
      run.
      (Adding more threads makes this faster, but the actual oops printing
      happens under &die_lock on x86, so you can maybe speed this up by a factor
      of around 2 and then any further improvement gets eaten up by lock
      contention.)
      
      It looks like it would take around 8-12 days to overflow a 32-bit counter
      with repeated oopsing on a multi-core X86 system running a graphical
      environment; both me (in an X86 VM) and Seth (with a distro kernel on
      normal hardware in a standard configuration) got numbers in that ballpark.
      
      12 days aren't *that* short on a desktop system, and you'd likely need much
      longer on a typical server system (assuming that people don't run graphical
      desktop environments on their servers), and this is a *very* noisy and
      violent approach to exploiting the kernel; and it also seems to take orders
      of magnitude longer on some machines, probably because stuff like EFI
      pstore will slow it down a ton if that's active.
      
      Signed-off-by: default avatarJann Horn <jannh@google.com>
      Link: https://lore.kernel.org/r/20221107201317.324457-1-jannh@google.com
      
      
      Reviewed-by: default avatarLuis Chamberlain <mcgrof@kernel.org>
      Signed-off-by: default avatarKees Cook <keescook@chromium.org>
      Link: https://lore.kernel.org/r/20221117234328.594699-2-keescook@chromium.org
      d4ccd54d
    • Kees Cook's avatar
      panic: Separate sysctl logic from CONFIG_SMP · 9360d035
      Kees Cook authored
      
      
      In preparation for adding more sysctls directly in kernel/panic.c, split
      CONFIG_SMP from the logic that adds sysctls.
      
      Cc: Petr Mladek <pmladek@suse.com>
      Cc: Andrew Morton <akpm@linux-foundation.org>
      Cc: tangmeng <tangmeng@uniontech.com>
      Cc: "Guilherme G. Piccoli" <gpiccoli@igalia.com>
      Cc: Tiezhu Yang <yangtiezhu@loongson.cn>
      Cc: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
      Reviewed-by: default avatarLuis Chamberlain <mcgrof@kernel.org>
      Signed-off-by: default avatarKees Cook <keescook@chromium.org>
      Link: https://lore.kernel.org/r/20221117234328.594699-1-keescook@chromium.org
      9360d035
    • Gustavo A. R. Silva's avatar
      mm/pgtable: Fix multiple -Wstringop-overflow warnings · 25226df4
      Gustavo A. R. Silva authored
      The actual size of the following arrays at run-time depends on
      CONFIG_X86_PAE.
      
      427         pmd_t *u_pmds[MAX_PREALLOCATED_USER_PMDS];
      428         pmd_t *pmds[MAX_PREALLOCATED_PMDS];
      
      If CONFIG_X86_PAE is not enabled, their final size will be zero (which
      is technically not a legal storage size in C, but remains "valid" via
      the GNU extension). In that case, the compiler complains about trying to
      access objects of size zero when calling functions where these objects
      are passed as arguments.
      
      Fix this by sanity-checking the size of those arrays just before the
      function calls. Also, the following warnings are fixed by these changes
      when building with GCC 11+ and -Wstringop-overflow enabled:
      
      arch/x86/mm/pgtable.c:437:13: warning: ‘preallocate_pmds.constprop’ accessing 8 bytes in a region of size 0 [-Wstringop-overflow=]
      arch/x86/mm/pgtable.c:440:13: warning: ‘preallocate_pmds.constprop’ accessing 8 bytes in a region of size 0 [-Wstringop-overflow=]
      arch/x86/mm/pgtable.c:462:9: warning: ‘free_pmds.constprop’ accessing 8 bytes in a region of size 0 [-Wstringop-overflow=]
      arch/x86/mm/pgtable.c:455:9: warning: ‘pgd_prepopulate_user_pmd’ accessing 8 bytes in a region of size 0 [-Wstringop-overflow=]
      arch/x86/mm/pgtable.c:464:9: warning: ‘free_pmds.constprop’ accessing 8 bytes in a region of size 0 [-Wstringop-overflow=]
      
      This is one of the last cases in the ongoing effort to globally enable
      -Wstringop-overflow.
      
      The alternative to this is to make the originally suggested change:
      make the pmds argument from an array pointer to a pointer pointer. That
      situation is considered "legal" for C in the sense that it does not have
      a way to reason about the storage. i.e.:
      
      -static void pgd_prepopulate_pmd(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmds[])
      +static void pgd_prepopulate_pmd(struct mm_struct *mm, pgd_t *pgd, pmd_t **pmds)
      
      With the above change, there's no difference in binary output, and the
      compiler warning is silenced.
      
      However, with this patch, the compiler can actually figure out that it
      isn't using the code at all, and it gets dropped:
      
         text    data     bss     dec     hex filename
         8218     718      32    8968    2308 arch/x86/mm/pgtable.o.before
         7765     694      32    8491    212b arch/x86/mm/pgtable.o.after
      
      So this case (fixing a warning and reducing image size) is a clear win.
      
      Additionally drops an old work-around for GCC in the same code.
      
      Link: https://github.com/KSPP/linux/issues/203
      Link: https://github.com/KSPP/linux/issues/181
      
      
      Signed-off-by: default avatarGustavo A. R. Silva <gustavoars@kernel.org>
      Reviewed-by: default avatarKees Cook <keescook@chromium.org>
      Signed-off-by: default avatarKees Cook <keescook@chromium.org>
      Link: https://lore.kernel.org/r/Yytb67xvrnctxnEe@work
      25226df4
    • Kees Cook's avatar
      mm: Make ksize() a reporting-only function · 38931d89
      Kees Cook authored
      
      
      With all "silently resizing" callers of ksize() refactored, remove the
      logic in ksize() that would allow it to be used to effectively change
      the size of an allocation (bypassing __alloc_size hints, etc). Users
      wanting this feature need to either use kmalloc_size_roundup() before an
      allocation, or use krealloc() directly.
      
      For kfree_sensitive(), move the unpoisoning logic inline. Replace the
      some of the partially open-coded ksize() in __do_krealloc with ksize()
      now that it doesn't perform unpoisoning.
      
      Adjust the KUnit tests to match the new ksize() behavior. Execution
      tested with:
      
      $ ./tools/testing/kunit/kunit.py run \
      	--kconfig_add CONFIG_KASAN=y \
      	--kconfig_add CONFIG_KASAN_GENERIC=y \
      	--arch x86_64 kasan
      
      Cc: Christoph Lameter <cl@linux.com>
      Cc: Pekka Enberg <penberg@kernel.org>
      Cc: Joonsoo Kim <iamjoonsoo.kim@lge.com>
      Cc: Andrew Morton <akpm@linux-foundation.org>
      Cc: Roman Gushchin <roman.gushchin@linux.dev>
      Cc: Hyeonggon Yoo <42.hyeyoo@gmail.com>
      Cc: Andrey Ryabinin <ryabinin.a.a@gmail.com>
      Cc: Alexander Potapenko <glider@google.com>
      Cc: Dmitry Vyukov <dvyukov@google.com>
      Cc: Vincenzo Frascino <vincenzo.frascino@arm.com>
      Cc: linux-mm@kvack.org
      Cc: kasan-dev@googlegroups.com
      Acked-by: default avatarVlastimil Babka <vbabka@suse.cz>
      Acked-by: default avatarDavid Rientjes <rientjes@google.com>
      Enhanced-by: default avatarAndrey Konovalov <andreyknvl@gmail.com>
      Signed-off-by: default avatarKees Cook <keescook@chromium.org>
      38931d89
  6. Nov 23, 2022
    • Kees Cook's avatar
      kunit/fortify: Validate __alloc_size attribute results · 9124a264
      Kees Cook authored
      
      
      Validate the effect of the __alloc_size attribute on allocators. If the
      compiler doesn't support __builtin_dynamic_object_size(), skip the
      associated tests.
      
      (For GCC, just remove the "--make_options" line below...)
      
      $ ./tools/testing/kunit/kunit.py run --arch x86_64 \
              --kconfig_add CONFIG_FORTIFY_SOURCE=y \
      	--make_options LLVM=1
              fortify
      ...
      [15:16:30] ================== fortify (10 subtests) ===================
      [15:16:30] [PASSED] known_sizes_test
      [15:16:30] [PASSED] control_flow_split_test
      [15:16:30] [PASSED] alloc_size_kmalloc_const_test
      [15:16:30] [PASSED] alloc_size_kmalloc_dynamic_test
      [15:16:30] [PASSED] alloc_size_vmalloc_const_test
      [15:16:30] [PASSED] alloc_size_vmalloc_dynamic_test
      [15:16:30] [PASSED] alloc_size_kvmalloc_const_test
      [15:16:30] [PASSED] alloc_size_kvmalloc_dynamic_test
      [15:16:30] [PASSED] alloc_size_devm_kmalloc_const_test
      [15:16:30] [PASSED] alloc_size_devm_kmalloc_dynamic_test
      [15:16:30] ===================== [PASSED] fortify =====================
      [15:16:30] ============================================================
      [15:16:30] Testing complete. Ran 10 tests: passed: 10
      [15:16:31] Elapsed time: 8.348s total, 0.002s configuring, 6.923s building, 1.075s running
      
      For earlier GCC prior to version 12, the dynamic tests will be skipped:
      
      [15:18:59] ================== fortify (10 subtests) ===================
      [15:18:59] [PASSED] known_sizes_test
      [15:18:59] [PASSED] control_flow_split_test
      [15:18:59] [PASSED] alloc_size_kmalloc_const_test
      [15:18:59] [SKIPPED] alloc_size_kmalloc_dynamic_test
      [15:18:59] [PASSED] alloc_size_vmalloc_const_test
      [15:18:59] [SKIPPED] alloc_size_vmalloc_dynamic_test
      [15:18:59] [PASSED] alloc_size_kvmalloc_const_test
      [15:18:59] [SKIPPED] alloc_size_kvmalloc_dynamic_test
      [15:18:59] [PASSED] alloc_size_devm_kmalloc_const_test
      [15:18:59] [SKIPPED] alloc_size_devm_kmalloc_dynamic_test
      [15:18:59] ===================== [PASSED] fortify =====================
      [15:18:59] ============================================================
      [15:18:59] Testing complete. Ran 10 tests: passed: 6, skipped: 4
      [15:18:59] Elapsed time: 11.965s total, 0.002s configuring, 10.540s building, 1.068s running
      
      Cc: David Gow <davidgow@google.com>
      Cc: linux-hardening@vger.kernel.org
      Signed-off-by: default avatarKees Cook <keescook@chromium.org>
      9124a264
  7. Nov 19, 2022
    • Nathan Chancellor's avatar
      drm/sti: Fix return type of sti_{dvo,hda,hdmi}_connector_mode_valid() · 0ad811cc
      Nathan Chancellor authored
      With clang's kernel control flow integrity (kCFI, CONFIG_CFI_CLANG),
      indirect call targets are validated against the expected function
      pointer prototype to make sure the call target is valid to help mitigate
      ROP attacks. If they are not identical, there is a failure at run time,
      which manifests as either a kernel panic or thread getting killed. A
      proposed warning in clang aims to catch these at compile time, which
      reveals:
      
        drivers/gpu/drm/sti/sti_hda.c:637:16: error: incompatible function pointer types initializing 'enum drm_mode_status (*)(struct drm_connector *, struct drm_display_mode *)' with an expression of type 'int (struct drm_connector *, struct drm_display_mode *)' [-Werror,-Wincompatible-function-pointer-types-strict]
                .mode_valid = sti_hda_connector_mode_valid,
                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
        drivers/gpu/drm/sti/sti_dvo.c:376:16: error: incompatible function pointer types initializing 'enum drm_mode_status (*)(struct drm_connector *, struct drm_display_mode *)' with an expression of type 'int (struct drm_connector *, struct drm_display_mode *)' [-Werror,-Wincompatible-function-pointer-types-strict]
                .mode_valid = sti_dvo_connector_mode_valid,
                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
        drivers/gpu/drm/sti/sti_hdmi.c:1035:16: error: incompatible function pointer types initializing 'enum drm_mode_status (*)(struct drm_connector *, struct drm_display_mode *)' with an expression of type 'int (struct drm_connector *, struct drm_display_mode *)' [-Werror,-Wincompatible-function-pointer-types-strict]
                .mode_valid = sti_hdmi_connector_mode_valid,
                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      
      ->mode_valid() in 'struct drm_connector_helper_funcs' expects a return
      type of 'enum drm_mode_status', not 'int'. Adjust the return type of
      sti_{dvo,hda,hdmi}_connector_mode_valid() to match the prototype's to
      resolve the warning and CFI failure.
      
      Link: https://github.com/ClangBuiltLinux/linux/issues/1750
      
      
      Signed-off-by: default avatarNathan Chancellor <nathan@kernel.org>
      Reviewed-by: default avatarKees Cook <keescook@chromium.org>
      Signed-off-by: default avatarKees Cook <keescook@chromium.org>
      Link: https://lore.kernel.org/r/20221102155623.3042869-1-nathan@kernel.org
      0ad811cc
    • Nathan Chancellor's avatar
      drm/fsl-dcu: Fix return type of fsl_dcu_drm_connector_mode_valid() · 96d845a6
      Nathan Chancellor authored
      With clang's kernel control flow integrity (kCFI, CONFIG_CFI_CLANG),
      indirect call targets are validated against the expected function
      pointer prototype to make sure the call target is valid to help mitigate
      ROP attacks. If they are not identical, there is a failure at run time,
      which manifests as either a kernel panic or thread getting killed. A
      proposed warning in clang aims to catch these at compile time, which
      reveals:
      
        drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_rgb.c:74:16: error: incompatible function pointer types initializing 'enum drm_mode_status (*)(struct drm_connector *, struct drm_display_mode *)' with an expression of type 'int (struct drm_connector *, struct drm_display_mode *)' [-Werror,-Wincompatible-function-pointer-types-strict]
                .mode_valid = fsl_dcu_drm_connector_mode_valid,
                              ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        1 error generated.
      
      ->mode_valid() in 'struct drm_connector_helper_funcs' expects a return
      type of 'enum drm_mode_status', not 'int'. Adjust the return type of
      fsl_dcu_drm_connector_mode_valid() to match the prototype's to resolve
      the warning and CFI failure.
      
      Link: https://github.com/ClangBuiltLinux/linux/issues/1750
      
      
      Reported-by: default avatarSami Tolvanen <samitolvanen@google.com>
      Signed-off-by: default avatarNathan Chancellor <nathan@kernel.org>
      Reviewed-by: default avatarKees Cook <keescook@chromium.org>
      Signed-off-by: default avatarKees Cook <keescook@chromium.org>
      Link: https://lore.kernel.org/r/20221102154215.78059-1-nathan@kernel.org
      96d845a6
    • Kees Cook's avatar
      driver core: Add __alloc_size hint to devm allocators · 74c8e6bf
      Kees Cook authored
      
      
      Mark the devm_*alloc()-family of allocations with appropriate
      __alloc_size()/__realloc_size() hints so the compiler can attempt to
      reason about buffer lengths from allocations.
      
      Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
      Cc: Rasmus Villemoes <rasmus.villemoes@prevas.dk>
      Cc: Thomas Gleixner <tglx@linutronix.de>
      Cc: Jason Gunthorpe <jgg@ziepe.ca>
      Cc: Nishanth Menon <nm@ti.com>
      Cc: Michael Kelley <mikelley@microsoft.com>
      Cc: Dan Williams <dan.j.williams@intel.com>
      Cc: Won Chung <wonchung@google.com>
      Signed-off-by: default avatarKees Cook <keescook@chromium.org>
      Reviewed-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      Link: https://lore.kernel.org/r/20221029074734.gonna.276-kees@kernel.org
      74c8e6bf
  8. Nov 09, 2022
  9. Nov 03, 2022
    • Kees Cook's avatar
      overflow: Introduce overflows_type() and castable_to_type() · 4b21d25b
      Kees Cook authored
      Implement a robust overflows_type() macro to test if a variable or
      constant value would overflow another variable or type. This can be
      used as a constant expression for static_assert() (which requires a
      constant expression[1][2]) when used on constant values. This must be
      constructed manually, since __builtin_add_overflow() does not produce
      a constant expression[3].
      
      Additionally adds castable_to_type(), similar to __same_type(), but for
      checking if a constant value would overflow if cast to a given type.
      
      Add unit tests for overflows_type(), __same_type(), and castable_to_type()
      to the existing KUnit "overflow" test:
      
      [16:03:33] ================== overflow (21 subtests) ==================
      ...
      [16:03:33] [PASSED] overflows_type_test
      [16:03:33] [PASSED] same_type_test
      [16:03:33] [PASSED] castable_to_type_test
      [16:03:33] ==================== [PASSED] overflow =====================
      [16:03:33] ============================================================
      [16:03:33] Testing complete. Ran 21 tests: passed: 21
      [16:03:33] Elapsed time: 24.022s total, 0.002s configuring, 22.598s building, 0.767s running
      
      [1] https://en.cppreference.com/w/c/language/_Static_assert
      [2] C11 standard (ISO/IEC 9899:2011): 6.7.10 Static assertions
      [3] https://gcc.gnu.org/onlinedocs/gcc/Integer-Overflow-Builtins.html
      
      
          6.56 Built-in Functions to Perform Arithmetic with Overflow Checking
          Built-in Function: bool __builtin_add_overflow (type1 a, type2 b,
      
      Cc: Luc Van Oostenryck <luc.vanoostenryck@gmail.com>
      Cc: Nathan Chancellor <nathan@kernel.org>
      Cc: Nick Desaulniers <ndesaulniers@google.com>
      Cc: Tom Rix <trix@redhat.com>
      Cc: Daniel Latypov <dlatypov@google.com>
      Cc: Vitor Massaru Iha <vitor@massaru.org>
      Cc: "Gustavo A. R. Silva" <gustavoars@kernel.org>
      Cc: Jani Nikula <jani.nikula@intel.com>
      Cc: Mauro Carvalho Chehab <mchehab@kernel.org>
      Cc: linux-hardening@vger.kernel.org
      Cc: llvm@lists.linux.dev
      Co-developed-by: default avatarGwan-gyeong Mun <gwan-gyeong.mun@intel.com>
      Signed-off-by: default avatarGwan-gyeong Mun <gwan-gyeong.mun@intel.com>
      Signed-off-by: default avatarKees Cook <keescook@chromium.org>
      Link: https://lore.kernel.org/r/20221024201125.1416422-1-gwan-gyeong.mun@intel.com
      4b21d25b
  10. Nov 02, 2022
  11. Oct 29, 2022