sphinx.addnodesdocument)}( rawsourcechildren]( translations LanguagesNode)}(hhh](h pending_xref)}(hhh]docutils.nodesTextChinese (Simplified)}parenthsba attributes}(ids]classes]names]dupnames]backrefs] refdomainstdreftypedoc reftarget$/translations/zh_CN/dev-tools/kfencemodnameN classnameN refexplicitutagnamehhh ubh)}(hhh]hChinese (Traditional)}hh2sbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/zh_TW/dev-tools/kfencemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hItalian}hhFsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/it_IT/dev-tools/kfencemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hJapanese}hhZsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/ja_JP/dev-tools/kfencemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hKorean}hhnsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/ko_KR/dev-tools/kfencemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hPortuguese (Brazilian)}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/pt_BR/dev-tools/kfencemodnameN classnameN refexplicituh1hhh ubh)}(hhh]hSpanish}hhsbah}(h]h ]h"]h$]h&] refdomainh)reftypeh+ reftarget$/translations/sp_SP/dev-tools/kfencemodnameN classnameN refexplicituh1hhh ubeh}(h]h ]h"]h$]h&]current_languageEnglishuh1h hh _documenthsourceNlineNubhcomment)}(h SPDX-License-Identifier: GPL-2.0h]h SPDX-License-Identifier: GPL-2.0}hhsbah}(h]h ]h"]h$]h&] xml:spacepreserveuh1hhhhhh>/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence.rsthKubh)}(hCopyright (C) 2020, Google LLC.h]hCopyright (C) 2020, Google LLC.}hhsbah}(h]h ]h"]h$]h&]hhuh1hhhhhhhhKubhsection)}(hhh](htitle)}(hKernel Electric-Fence (KFENCE)h]hKernel Electric-Fence (KFENCE)}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhhhhhKubh paragraph)}(hKernel Electric-Fence (KFENCE) is a low-overhead sampling-based memory safety error detector. KFENCE detects heap out-of-bounds access, use-after-free, and invalid-free errors.h]hKernel Electric-Fence (KFENCE) is a low-overhead sampling-based memory safety error detector. KFENCE detects heap out-of-bounds access, use-after-free, and invalid-free errors.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhhhhubh)}(hXKFENCE is designed to be enabled in production kernels, and has near zero performance overhead. Compared to KASAN, KFENCE trades performance for precision. The main motivation behind KFENCE's design, is that with enough total uptime KFENCE will detect bugs in code paths not typically exercised by non-production test workloads. One way to quickly achieve a large enough total uptime is when the tool is deployed across a large fleet of machines.h]hXKFENCE is designed to be enabled in production kernels, and has near zero performance overhead. Compared to KASAN, KFENCE trades performance for precision. The main motivation behind KFENCE’s design, is that with enough total uptime KFENCE will detect bugs in code paths not typically exercised by non-production test workloads. One way to quickly achieve a large enough total uptime is when the tool is deployed across a large fleet of machines.}(hhhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK hhhhubh)}(hhh](h)}(hUsageh]hUsage}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hhhhhKubh)}(h-To enable KFENCE, configure the kernel with::h]h,To enable KFENCE, configure the kernel with:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKhj hhubh literal_block)}(hCONFIG_KFENCE=yh]hCONFIG_KFENCE=y}hj*sbah}(h]h ]h"]h$]h&]hhuh1j(hhhKhj hhubh)}(hTo build a kernel with KFENCE support, but disabled by default (to enable, set ``kfence.sample_interval`` to non-zero value), configure the kernel with::h](hOTo build a kernel with KFENCE support, but disabled by default (to enable, set }(hj8hhhNhNubhliteral)}(h``kfence.sample_interval``h]hkfence.sample_interval}(hjBhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj8ubh/ to non-zero value), configure the kernel with:}(hj8hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj hhubj))}(h/CONFIG_KFENCE=y CONFIG_KFENCE_SAMPLE_INTERVAL=0h]h/CONFIG_KFENCE=y CONFIG_KFENCE_SAMPLE_INTERVAL=0}hjZsbah}(h]h ]h"]h$]h&]hhuh1j(hhhKhj hhubh)}(hKFENCE provides several other configuration options to customize behaviour (see the respective help text in ``lib/Kconfig.kfence`` for more info).h](hlKFENCE provides several other configuration options to customize behaviour (see the respective help text in }(hjhhhhNhNubjA)}(h``lib/Kconfig.kfence``h]hlib/Kconfig.kfence}(hjphhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjhubh for more info).}(hjhhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKhj hhubh)}(hhh](h)}(hTuning performanceh]hTuning performance}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhK#ubh)}(hXThe most important parameter is KFENCE's sample interval, which can be set via the kernel boot parameter ``kfence.sample_interval`` in milliseconds. The sample interval determines the frequency with which heap allocations will be guarded by KFENCE. The default is configurable via the Kconfig option ``CONFIG_KFENCE_SAMPLE_INTERVAL``. Setting ``kfence.sample_interval=0`` disables KFENCE.h](hkThe most important parameter is KFENCE’s sample interval, which can be set via the kernel boot parameter }(hjhhhNhNubjA)}(h``kfence.sample_interval``h]hkfence.sample_interval}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubh in milliseconds. The sample interval determines the frequency with which heap allocations will be guarded by KFENCE. The default is configurable via the Kconfig option }(hjhhhNhNubjA)}(h!``CONFIG_KFENCE_SAMPLE_INTERVAL``h]hCONFIG_KFENCE_SAMPLE_INTERVAL}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubh . Setting }(hjhhhNhNubjA)}(h``kfence.sample_interval=0``h]hkfence.sample_interval=0}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubh disables KFENCE.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK%hjhhubh)}(hX The sample interval controls a timer that sets up KFENCE allocations. By default, to keep the real sample interval predictable, the normal timer also causes CPU wake-ups when the system is completely idle. This may be undesirable on power-constrained systems. The boot parameter ``kfence.deferrable=1`` instead switches to a "deferrable" timer which does not force CPU wake-ups on idle systems, at the risk of unpredictable sample intervals. The default is configurable via the Kconfig option ``CONFIG_KFENCE_DEFERRABLE``.h](hXThe sample interval controls a timer that sets up KFENCE allocations. By default, to keep the real sample interval predictable, the normal timer also causes CPU wake-ups when the system is completely idle. This may be undesirable on power-constrained systems. The boot parameter }(hjhhhNhNubjA)}(h``kfence.deferrable=1``h]hkfence.deferrable=1}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubh instead switches to a “deferrable” timer which does not force CPU wake-ups on idle systems, at the risk of unpredictable sample intervals. The default is configurable via the Kconfig option }(hjhhhNhNubjA)}(h``CONFIG_KFENCE_DEFERRABLE``h]hCONFIG_KFENCE_DEFERRABLE}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK,hjhhubhwarning)}(hThe KUnit test suite is very likely to fail when using a deferrable timer since it currently causes very unpredictable sample intervals.h]h)}(hThe KUnit test suite is very likely to fail when using a deferrable timer since it currently causes very unpredictable sample intervals.h]hThe KUnit test suite is very likely to fail when using a deferrable timer since it currently causes very unpredictable sample intervals.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK5hjubah}(h]h ]h"]h$]h&]uh1jhjhhhhhNubh)}(hXBy default KFENCE will only sample 1 heap allocation within each sample interval. *Burst mode* allows to sample successive heap allocations, where the kernel boot parameter ``kfence.burst`` can be set to a non-zero value which denotes the *additional* successive allocations within a sample interval; setting ``kfence.burst=N`` means that ``1 + N`` successive allocations are attempted through KFENCE for each sample interval.h](hRBy default KFENCE will only sample 1 heap allocation within each sample interval. }(hj)hhhNhNubhemphasis)}(h *Burst mode*h]h Burst mode}(hj3hhhNhNubah}(h]h ]h"]h$]h&]uh1j1hj)ubhO allows to sample successive heap allocations, where the kernel boot parameter }(hj)hhhNhNubjA)}(h``kfence.burst``h]h kfence.burst}(hjEhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj)ubh2 can be set to a non-zero value which denotes the }(hj)hhhNhNubj2)}(h *additional*h]h additional}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1j1hj)ubh: successive allocations within a sample interval; setting }(hj)hhhNhNubjA)}(h``kfence.burst=N``h]hkfence.burst=N}(hjihhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj)ubh means that }(hj)hhhNhNubjA)}(h ``1 + N``h]h1 + N}(hj{hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj)ubhN successive allocations are attempted through KFENCE for each sample interval.}(hj)hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK8hjhhubh)}(hXThe KFENCE memory pool is of fixed size, and if the pool is exhausted, no further KFENCE allocations occur. With ``CONFIG_KFENCE_NUM_OBJECTS`` (default 255), the number of available guarded objects can be controlled. Each object requires 2 pages, one for the object itself and the other one used as a guard page; object pages are interleaved with guard pages, and every object page is therefore surrounded by two guard pages.h](hqThe KFENCE memory pool is of fixed size, and if the pool is exhausted, no further KFENCE allocations occur. With }(hjhhhNhNubjA)}(h``CONFIG_KFENCE_NUM_OBJECTS``h]hCONFIG_KFENCE_NUM_OBJECTS}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubhX (default 255), the number of available guarded objects can be controlled. Each object requires 2 pages, one for the object itself and the other one used as a guard page; object pages are interleaved with guard pages, and every object page is therefore surrounded by two guard pages.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhK?hjhhubh)}(hIThe total memory dedicated to the KFENCE memory pool can be computed as::h]hHThe total memory dedicated to the KFENCE memory pool can be computed as:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKFhjhhubj))}(h ( #objects + 1 ) * 2 * PAGE_SIZEh]h ( #objects + 1 ) * 2 * PAGE_SIZE}hjsbah}(h]h ]h"]h$]h&]hhuh1j(hhhKHhjhhubh)}(hsUsing the default config, and assuming a page size of 4 KiB, results in dedicating 2 MiB to the KFENCE memory pool.h]hsUsing the default config, and assuming a page size of 4 KiB, results in dedicating 2 MiB to the KFENCE memory pool.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKJhjhhubh)}(hNote: On architectures that support huge pages, KFENCE will ensure that the pool is using pages of size ``PAGE_SIZE``. This will result in additional page tables being allocated.h](hhNote: On architectures that support huge pages, KFENCE will ensure that the pool is using pages of size }(hjhhhNhNubjA)}(h ``PAGE_SIZE``h]h PAGE_SIZE}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubh=. This will result in additional page tables being allocated.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKMhjhhubeh}(h]tuning-performanceah ]h"]tuning performanceah$]h&]uh1hhj hhhhhK#ubh)}(hhh](h)}(h Error reportsh]h Error reports}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhKRubh)}(hhThe boot parameter ``kfence.fault`` can be used to control the behavior when a KFENCE error is detected:h](hThe boot parameter }(hjhhhNhNubjA)}(h``kfence.fault``h]h kfence.fault}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubhE can be used to control the behavior when a KFENCE error is detected:}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKThjhhubh bullet_list)}(hhh](h list_item)}(hG``kfence.fault=report``: Print the error report and continue (default).h]h)}(hj?h](jA)}(h``kfence.fault=report``h]hkfence.fault=report}(hjDhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjAubh0: Print the error report and continue (default).}(hjAhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKWhj=ubah}(h]h ]h"]h$]h&]uh1j;hj8hhhhhNubj<)}(h7``kfence.fault=oops``: Print the error report and oops.h]h)}(hjdh](jA)}(h``kfence.fault=oops``h]hkfence.fault=oops}(hjihhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjfubh": Print the error report and oops.}(hjfhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKXhjbubah}(h]h ]h"]h$]h&]uh1j;hj8hhhhhNubj<)}(h:``kfence.fault=panic``: Print the error report and panic. h]h)}(h9``kfence.fault=panic``: Print the error report and panic.h](jA)}(h``kfence.fault=panic``h]hkfence.fault=panic}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubh#: Print the error report and panic.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKYhjubah}(h]h ]h"]h$]h&]uh1j;hj8hhhhhNubeh}(h]h ]h"]h$]h&]bullet-uh1j6hhhKWhjhhubh)}(h0A typical out-of-bounds access looks like this::h]h/A typical out-of-bounds access looks like this:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhK[hjhhubj))}(hXp================================================================== BUG: KFENCE: out-of-bounds read in test_out_of_bounds_read+0xa6/0x234 Out-of-bounds read at 0xffff8c3f2e291fff (1B left of kfence-#72): test_out_of_bounds_read+0xa6/0x234 kunit_try_run_case+0x61/0xa0 kunit_generic_run_threadfn_adapter+0x16/0x30 kthread+0x176/0x1b0 ret_from_fork+0x22/0x30 kfence-#72: 0xffff8c3f2e292000-0xffff8c3f2e29201f, size=32, cache=kmalloc-32 allocated by task 484 on cpu 0 at 32.919330s: test_alloc+0xfe/0x738 test_out_of_bounds_read+0x9b/0x234 kunit_try_run_case+0x61/0xa0 kunit_generic_run_threadfn_adapter+0x16/0x30 kthread+0x176/0x1b0 ret_from_fork+0x22/0x30 CPU: 0 PID: 484 Comm: kunit_try_catch Not tainted 5.13.0-rc3+ #7 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 ==================================================================h]hXp================================================================== BUG: KFENCE: out-of-bounds read in test_out_of_bounds_read+0xa6/0x234 Out-of-bounds read at 0xffff8c3f2e291fff (1B left of kfence-#72): test_out_of_bounds_read+0xa6/0x234 kunit_try_run_case+0x61/0xa0 kunit_generic_run_threadfn_adapter+0x16/0x30 kthread+0x176/0x1b0 ret_from_fork+0x22/0x30 kfence-#72: 0xffff8c3f2e292000-0xffff8c3f2e29201f, size=32, cache=kmalloc-32 allocated by task 484 on cpu 0 at 32.919330s: test_alloc+0xfe/0x738 test_out_of_bounds_read+0x9b/0x234 kunit_try_run_case+0x61/0xa0 kunit_generic_run_threadfn_adapter+0x16/0x30 kthread+0x176/0x1b0 ret_from_fork+0x22/0x30 CPU: 0 PID: 484 Comm: kunit_try_catch Not tainted 5.13.0-rc3+ #7 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 ==================================================================}hjsbah}(h]h ]h"]h$]h&]hhuh1j(hhhK]hjhhubh)}(hXThe header of the report provides a short summary of the function involved in the access. It is followed by more detailed information about the access and its origin. Note that, real kernel addresses are only shown when using the kernel command line option ``no_hash_pointers``.h](hXThe header of the report provides a short summary of the function involved in the access. It is followed by more detailed information about the access and its origin. Note that, real kernel addresses are only shown when using the kernel command line option }(hjhhhNhNubjA)}(h``no_hash_pointers``h]hno_hash_pointers}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhKuhjhhubh)}(h)Use-after-free accesses are reported as::h]h(Use-after-free accesses are reported as:}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhKzhjhhubj))}(hXG================================================================== BUG: KFENCE: use-after-free read in test_use_after_free_read+0xb3/0x143 Use-after-free read at 0xffff8c3f2e2a0000 (in kfence-#79): test_use_after_free_read+0xb3/0x143 kunit_try_run_case+0x61/0xa0 kunit_generic_run_threadfn_adapter+0x16/0x30 kthread+0x176/0x1b0 ret_from_fork+0x22/0x30 kfence-#79: 0xffff8c3f2e2a0000-0xffff8c3f2e2a001f, size=32, cache=kmalloc-32 allocated by task 488 on cpu 2 at 33.871326s: test_alloc+0xfe/0x738 test_use_after_free_read+0x76/0x143 kunit_try_run_case+0x61/0xa0 kunit_generic_run_threadfn_adapter+0x16/0x30 kthread+0x176/0x1b0 ret_from_fork+0x22/0x30 freed by task 488 on cpu 2 at 33.871358s: test_use_after_free_read+0xa8/0x143 kunit_try_run_case+0x61/0xa0 kunit_generic_run_threadfn_adapter+0x16/0x30 kthread+0x176/0x1b0 ret_from_fork+0x22/0x30 CPU: 2 PID: 488 Comm: kunit_try_catch Tainted: G B 5.13.0-rc3+ #7 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 ==================================================================h]hXG================================================================== BUG: KFENCE: use-after-free read in test_use_after_free_read+0xb3/0x143 Use-after-free read at 0xffff8c3f2e2a0000 (in kfence-#79): test_use_after_free_read+0xb3/0x143 kunit_try_run_case+0x61/0xa0 kunit_generic_run_threadfn_adapter+0x16/0x30 kthread+0x176/0x1b0 ret_from_fork+0x22/0x30 kfence-#79: 0xffff8c3f2e2a0000-0xffff8c3f2e2a001f, size=32, cache=kmalloc-32 allocated by task 488 on cpu 2 at 33.871326s: test_alloc+0xfe/0x738 test_use_after_free_read+0x76/0x143 kunit_try_run_case+0x61/0xa0 kunit_generic_run_threadfn_adapter+0x16/0x30 kthread+0x176/0x1b0 ret_from_fork+0x22/0x30 freed by task 488 on cpu 2 at 33.871358s: test_use_after_free_read+0xa8/0x143 kunit_try_run_case+0x61/0xa0 kunit_generic_run_threadfn_adapter+0x16/0x30 kthread+0x176/0x1b0 ret_from_fork+0x22/0x30 CPU: 2 PID: 488 Comm: kunit_try_catch Tainted: G B 5.13.0-rc3+ #7 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 ==================================================================}hjsbah}(h]h ]h"]h$]h&]hhuh1j(hhhK|hjhhubh)}(h)}(h/``struct kmem_cache *s`` cache being shut down h](jD)}(h``struct kmem_cache *s``h]jA)}(hj! h]hstruct kmem_cache *s}(hj# hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj ubah}(h]h ]h"]h$]h&]uh1jChX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKMhj ubj^)}(hhh]h)}(hcache being shut downh]hcache being shut down}(hj: hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj6 hKMhj7 ubah}(h]h ]h"]h$]h&]uh1j]hj ubeh}(h]h ]h"]h$]h&]uh1j=hj6 hKMhj ubah}(h]h ]h"]h$]h&]uh1j8hjubh)}(h**Description**h]j#)}(hj\ h]h Description}(hj^ hhhNhNubah}(h]h ]h"]h$]h&]uh1j"hjZ ubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKOhjubh)}(hBefore shutting down a cache, one must ensure there are no remaining objects allocated from it. Because KFENCE objects are not referenced from the cache directly, we need to check them here.h]hBefore shutting down a cache, one must ensure there are no remaining objects allocated from it. Because KFENCE objects are not referenced from the cache directly, we need to check them here.}(hjr hhhNhNubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKNhjubh)}(hNote that shutdown_cache() is internal to SL*B, and kmem_cache_destroy() does not return if allocated objects still exist: it prints an error message and simply aborts destruction of a cache, leaking memory.h]hNote that shutdown_cache() is internal to SL*B, and kmem_cache_destroy() does not return if allocated objects still exist: it prints an error message and simply aborts destruction of a cache, leaking memory.}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKRhjubh)}(hXIf the only such objects are KFENCE objects, we will not leak the entire cache, but instead try to provide more useful debug info by making allocated objects "zombie allocations". Objects may then still be used or freed (which is handled gracefully), but usage will result in showing KFENCE error reports which include stack traces to the user of the object, the original allocation site, and caller to shutdown_cache().h]hXIf the only such objects are KFENCE objects, we will not leak the entire cache, but instead try to provide more useful debug info by making allocated objects “zombie allocations”. Objects may then still be used or freed (which is handled gracefully), but usage will result in showing KFENCE error reports which include stack traces to the user of the object, the original allocation site, and caller to shutdown_cache().}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKVhjubeh}(h]h ] kernelindentah"]h$]h&]uh1jhjhhhNhNubj)}(hhh]h}(h]h ]h"]h$]h&]entries](jkfence_alloc (C function)c.kfence_allochNtauh1jhjhhhNhNubj)}(hhh](j)}(hDvoid * kfence_alloc (struct kmem_cache *s, size_t size, gfp_t flags)h]j#)}(hBvoid *kfence_alloc(struct kmem_cache *s, size_t size, gfp_t flags)h](j))}(hvoidh]hvoid}(hj hhhNhNubah}(h]h ]j5ah"]h$]h&]uh1j(hj hhhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKgubj;)}(h h]h }(hj hhhNhNubah}(h]h ]jGah"]h$]h&]uh1j:hj hhhj hKgubj)}(hjh]h*}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj hhhj hKgubjL)}(h kfence_alloch]jR)}(h kfence_alloch]h kfence_alloc}(hj hhhNhNubah}(h]h ]j^ah"]h$]h&]uh1jQhj ubah}(h]h ](jejfeh"]h$]h&]hhuh1jKhj hhhj hKgubjk)}(h0(struct kmem_cache *s, size_t size, gfp_t flags)h](jq)}(hstruct kmem_cache *sh](jw)}(hjVh]hstruct}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jvhj ubj;)}(h h]h }(hj hhhNhNubah}(h]h ]jGah"]h$]h&]uh1j:hj ubh)}(hhh]jR)}(h kmem_cacheh]h kmem_cache}(hj' hhhNhNubah}(h]h ]j^ah"]h$]h&]uh1jQhj$ ubah}(h]h ]h"]h$]h&] refdomainj reftypej reftargetj) modnameN classnameNjj)}j]j)}jj sbc.kfence_allocasbuh1hhj ubj;)}(h h]h }(hjG hhhNhNubah}(h]h ]jGah"]h$]h&]uh1j:hj ubj)}(hjh]h*}(hjU hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj ubjR)}(hjh]hs}(hjb hhhNhNubah}(h]h ]j^ah"]h$]h&]uh1jQhj ubeh}(h]h ]h"]h$]h&]noemphhhuh1jphj ubjq)}(h size_t sizeh](h)}(hhh]jR)}(hsize_th]hsize_t}(hj} hhhNhNubah}(h]h ]j^ah"]h$]h&]uh1jQhjz ubah}(h]h ]h"]h$]h&] refdomainj reftypej reftargetj modnameN classnameNjj)}j]jC c.kfence_allocasbuh1hhjv ubj;)}(h h]h }(hj hhhNhNubah}(h]h ]jGah"]h$]h&]uh1j:hjv ubjR)}(hsizeh]hsize}(hj hhhNhNubah}(h]h ]j^ah"]h$]h&]uh1jQhjv ubeh}(h]h ]h"]h$]h&]noemphhhuh1jphj ubjq)}(h gfp_t flagsh](h)}(hhh]jR)}(hgfp_th]hgfp_t}(hj hhhNhNubah}(h]h ]j^ah"]h$]h&]uh1jQhj ubah}(h]h ]h"]h$]h&] refdomainj reftypej reftargetj modnameN classnameNjj)}j]jC c.kfence_allocasbuh1hhj ubj;)}(h h]h }(hj hhhNhNubah}(h]h ]jGah"]h$]h&]uh1j:hj ubjR)}(hflagsh]hflags}(hj hhhNhNubah}(h]h ]j^ah"]h$]h&]uh1jQhj ubeh}(h]h ]h"]h$]h&]noemphhhuh1jphj ubeh}(h]h ]h"]h$]h&]hhuh1jjhj hhhj hKgubeh}(h]h ]h"]h$]h&]hhjuh1j"jjhj hhhj hKgubah}(h]j ah ](jjeh"]h$]h&]jj)jhuh1jhj hKghj hhubj)}(hhh]h)}(h/allocate a KFENCE object with a low probabilityh]h/allocate a KFENCE object with a low probability}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKghj hhubah}(h]h ]h"]h$]h&]uh1jhj hhhj hKgubeh}(h]h ](j functioneh"]h$]h&]jj jj3 jj3 jjjuh1jhhhjhNhNubj)}(hX]**Parameters** ``struct kmem_cache *s`` struct kmem_cache with object requirements ``size_t size`` exact size of the object to allocate (can be less than **s->size** e.g. for kmalloc caches) ``gfp_t flags`` GFP flags **Return** * NULL - must proceed with allocating as usual, * non-NULL - pointer to a KFENCE object. **Description** kfence_alloc() should be inserted into the heap allocation fast path, allowing it to transparently return KFENCE-allocated objects with a low probability using a static branch (the probability is controlled by the kfence.sample_interval boot parameter).h](h)}(h**Parameters**h]j#)}(hj= h]h Parameters}(hj? hhhNhNubah}(h]h ]h"]h$]h&]uh1j"hj; ubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKkhj7 ubj9)}(hhh](j>)}(hD``struct kmem_cache *s`` struct kmem_cache with object requirements h](jD)}(h``struct kmem_cache *s``h]jA)}(hj\ h]hstruct kmem_cache *s}(hj^ hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjZ ubah}(h]h ]h"]h$]h&]uh1jChX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhhjV ubj^)}(hhh]h)}(h*struct kmem_cache with object requirementsh]h*struct kmem_cache with object requirements}(hju hhhNhNubah}(h]h ]h"]h$]h&]uh1hhjq hKhhjr ubah}(h]h ]h"]h$]h&]uh1j]hjV ubeh}(h]h ]h"]h$]h&]uh1j=hjq hKhhjS ubj>)}(hl``size_t size`` exact size of the object to allocate (can be less than **s->size** e.g. for kmalloc caches) h](jD)}(h``size_t size``h]jA)}(hj h]h size_t size}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj ubah}(h]h ]h"]h$]h&]uh1jChX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKjhj ubj^)}(hhh]h)}(h[exact size of the object to allocate (can be less than **s->size** e.g. for kmalloc caches)h](h7exact size of the object to allocate (can be less than }(hj hhhNhNubj#)}(h **s->size**h]hs->size}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j"hj ubh e.g. for kmalloc caches)}(hj hhhNhNubeh}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKihj ubah}(h]h ]h"]h$]h&]uh1j]hj ubeh}(h]h ]h"]h$]h&]uh1j=hj hKjhjS ubj>)}(h``gfp_t flags`` GFP flags h](jD)}(h``gfp_t flags``h]jA)}(hj h]h gfp_t flags}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj ubah}(h]h ]h"]h$]h&]uh1jChX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKkhj ubj^)}(hhh]h)}(h GFP flagsh]h GFP flags}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hKkhj ubah}(h]h ]h"]h$]h&]uh1j]hj ubeh}(h]h ]h"]h$]h&]uh1j=hj hKkhjS ubeh}(h]h ]h"]h$]h&]uh1j8hj7 ubh)}(h **Return**h]j#)}(hj h]hReturn}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j"hj ubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKmhj7 ubj7)}(hhh](j<)}(h1NULL - must proceed with allocating as usual,h]h)}(hj7 h]h1NULL - must proceed with allocating as usual,}(hj9 hhhNhNubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKmhj5 ubah}(h]h ]h"]h$]h&]uh1j;hj2 ubj<)}(h'non-NULL - pointer to a KFENCE object. h]h)}(h&non-NULL - pointer to a KFENCE object.h]h&non-NULL - pointer to a KFENCE object.}(hjQ hhhNhNubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKnhjM ubah}(h]h ]h"]h$]h&]uh1j;hj2 ubeh}(h]h ]h"]h$]h&]jjuh1j6hjF hKmhj7 ubh)}(h**Description**h]j#)}(hjn h]h Description}(hjp hhhNhNubah}(h]h ]h"]h$]h&]uh1j"hjl ubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKphj7 ubh)}(hkfence_alloc() should be inserted into the heap allocation fast path, allowing it to transparently return KFENCE-allocated objects with a low probability using a static branch (the probability is controlled by the kfence.sample_interval boot parameter).h]hkfence_alloc() should be inserted into the heap allocation fast path, allowing it to transparently return KFENCE-allocated objects with a low probability using a static branch (the probability is controlled by the kfence.sample_interval boot parameter).}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKphj7 ubeh}(h]h ] kernelindentah"]h$]h&]uh1jhjhhhNhNubj)}(hhh]h}(h]h ]h"]h$]h&]entries](jkfence_ksize (C function)c.kfence_ksizehNtauh1jhjhhhNhNubj)}(hhh](j)}(h&size_t kfence_ksize (const void *addr)h]j#)}(h%size_t kfence_ksize(const void *addr)h](h)}(hhh]jR)}(hsize_th]hsize_t}(hj hhhNhNubah}(h]h ]j^ah"]h$]h&]uh1jQhj ubah}(h]h ]h"]h$]h&] refdomainj reftypej reftargetj modnameN classnameNjj)}j]j)}j kfence_ksizesbc.kfence_ksizeasbuh1hhj hhhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKubj;)}(h h]h }(hj hhhNhNubah}(h]h ]jGah"]h$]h&]uh1j:hj hhhj hKubjL)}(h kfence_ksizeh]jR)}(hj h]h kfence_ksize}(hj hhhNhNubah}(h]h ]j^ah"]h$]h&]uh1jQhj ubah}(h]h ](jejfeh"]h$]h&]hhuh1jKhj hhhj hKubjk)}(h(const void *addr)h]jq)}(hconst void *addrh](jw)}(hjzh]hconst}(hj hhhNhNubah}(h]h ]jah"]h$]h&]uh1jvhj ubj;)}(h h]h }(hj hhhNhNubah}(h]h ]jGah"]h$]h&]uh1j:hj ubj))}(hvoidh]hvoid}(hj hhhNhNubah}(h]h ]j5ah"]h$]h&]uh1j(hj ubj;)}(h h]h }(hj. hhhNhNubah}(h]h ]jGah"]h$]h&]uh1j:hj ubj)}(hjh]h*}(hj< hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj ubjR)}(haddrh]haddr}(hjI hhhNhNubah}(h]h ]j^ah"]h$]h&]uh1jQhj ubeh}(h]h ]h"]h$]h&]noemphhhuh1jphj ubah}(h]h ]h"]h$]h&]hhuh1jjhj hhhj hKubeh}(h]h ]h"]h$]h&]hhjuh1j"jjhj hhhj hKubah}(h]j ah ](jjeh"]h$]h&]jj)jhuh1jhj hKhj hhubj)}(hhh]h)}(h9get actual amount of memory allocated for a KFENCE objecth]h9get actual amount of memory allocated for a KFENCE object}(hjs hhhNhNubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.h؄hKhjp hhubah}(h]h ]h"]h$]h&]uh1jhj hhhj hKubeh}(h]h ](j functioneh"]h$]h&]jj jj jj jjjuh1jhhhjhNhNubj)}(hX**Parameters** ``const void *addr`` pointer to a heap object **Return** * 0 - not a KFENCE object, must call __ksize() instead, * non-0 - this many bytes can be accessed without causing a memory error. **Description** kfence_ksize() returns the number of bytes requested for a KFENCE object at allocation time. This number may be less than the object size of the corresponding struct kmem_cache.h](h)}(h**Parameters**h]j#)}(hj h]h Parameters}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j"hj ubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhj ubj9)}(hhh]j>)}(h.``const void *addr`` pointer to a heap object h](jD)}(h``const void *addr``h]jA)}(hj h]hconst void *addr}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj ubah}(h]h ]h"]h$]h&]uh1jChX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhj ubj^)}(hhh]h)}(hpointer to a heap objecth]hpointer to a heap object}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hKhj ubah}(h]h ]h"]h$]h&]uh1j]hj ubeh}(h]h ]h"]h$]h&]uh1j=hj hKhj ubah}(h]h ]h"]h$]h&]uh1j8hj ubh)}(h **Return**h]j#)}(hj h]hReturn}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1j"hj ubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhj ubj7)}(hhh](j<)}(h90 - not a KFENCE object, must call __ksize() instead,h]h)}(hj h]h90 - not a KFENCE object, must call __ksize() instead,}(hj hhhNhNubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjubah}(h]h ]h"]h$]h&]uh1j;hjubj<)}(hHnon-0 - this many bytes can be accessed without causing a memory error. h]h)}(hGnon-0 - this many bytes can be accessed without causing a memory error.h]hGnon-0 - this many bytes can be accessed without causing a memory error.}(hj$hhhNhNubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhj ubah}(h]h ]h"]h$]h&]uh1j;hjubeh}(h]h ]h"]h$]h&]jjuh1j6hjhKhj ubh)}(h**Description**h]j#)}(hjAh]h Description}(hjChhhNhNubah}(h]h ]h"]h$]h&]uh1j"hj?ubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhj ubh)}(hkfence_ksize() returns the number of bytes requested for a KFENCE object at allocation time. This number may be less than the object size of the corresponding struct kmem_cache.h]hkfence_ksize() returns the number of bytes requested for a KFENCE object at allocation time. This number may be less than the object size of the corresponding struct kmem_cache.}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhj ubeh}(h]h ] kernelindentah"]h$]h&]uh1jhjhhhNhNubj)}(hhh]h}(h]h ]h"]h$]h&]entries](j kfence_object_start (C function)c.kfence_object_starthNtauh1jhjhhhNhNubj)}(hhh](j)}(h-void * kfence_object_start (const void *addr)h]j#)}(h+void *kfence_object_start(const void *addr)h](j))}(hvoidh]hvoid}(hjhhhNhNubah}(h]h ]j5ah"]h$]h&]uh1j(hjhhhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKubj;)}(h h]h }(hjhhhNhNubah}(h]h ]jGah"]h$]h&]uh1j:hjhhhjhKubj)}(hjh]h*}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjhhhjhKubjL)}(hkfence_object_starth]jR)}(hkfence_object_starth]hkfence_object_start}(hjhhhNhNubah}(h]h ]j^ah"]h$]h&]uh1jQhjubah}(h]h ](jejfeh"]h$]h&]hhuh1jKhjhhhjhKubjk)}(h(const void *addr)h]jq)}(hconst void *addrh](jw)}(hjzh]hconst}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jvhjubj;)}(h h]h }(hjhhhNhNubah}(h]h ]jGah"]h$]h&]uh1j:hjubj))}(hvoidh]hvoid}(hjhhhNhNubah}(h]h ]j5ah"]h$]h&]uh1j(hjubj;)}(h h]h }(hjhhhNhNubah}(h]h ]jGah"]h$]h&]uh1j:hjubj)}(hjh]h*}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubjR)}(haddrh]haddr}(hjhhhNhNubah}(h]h ]j^ah"]h$]h&]uh1jQhjubeh}(h]h ]h"]h$]h&]noemphhhuh1jphjubah}(h]h ]h"]h$]h&]hhuh1jjhjhhhjhKubeh}(h]h ]h"]h$]h&]hhjuh1j"jjhj~hhhjhKubah}(h]jyah ](jjeh"]h$]h&]jj)jhuh1jhjhKhj{hhubj)}(hhh]h)}(h%find the beginning of a KFENCE objecth]h%find the beginning of a KFENCE object}(hj>hhhNhNubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhj;hhubah}(h]h ]h"]h$]h&]uh1jhj{hhhjhKubeh}(h]h ](j functioneh"]h$]h&]jj jjVjjVjjjuh1jhhhjhNhNubj)}(hX**Parameters** ``const void *addr`` address within a KFENCE-allocated object **Return** address of the beginning of the object. **Description** SL[AU]B-allocated objects are laid out within a page one by one, so it is easy to calculate the beginning of an object given a pointer inside it and the object size. The same is not true for KFENCE, which places a single object at either end of the page. This helper function is used to find the beginning of a KFENCE-allocated object.h](h)}(h**Parameters**h]j#)}(hj`h]h Parameters}(hjbhhhNhNubah}(h]h ]h"]h$]h&]uh1j"hj^ubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjZubj9)}(hhh]j>)}(h>``const void *addr`` address within a KFENCE-allocated object h](jD)}(h``const void *addr``h]jA)}(hjh]hconst void *addr}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hj}ubah}(h]h ]h"]h$]h&]uh1jChX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjyubj^)}(hhh]h)}(h(address within a KFENCE-allocated objecth]h(address within a KFENCE-allocated object}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjubah}(h]h ]h"]h$]h&]uh1j]hjyubeh}(h]h ]h"]h$]h&]uh1j=hjhKhjvubah}(h]h ]h"]h$]h&]uh1j8hjZubh)}(h **Return**h]j#)}(hjh]hReturn}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j"hjubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjZubh)}(h'address of the beginning of the object.h]h'address of the beginning of the object.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjZubh)}(h**Description**h]j#)}(hjh]h Description}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j"hjubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjZubh)}(hXOSL[AU]B-allocated objects are laid out within a page one by one, so it is easy to calculate the beginning of an object given a pointer inside it and the object size. The same is not true for KFENCE, which places a single object at either end of the page. This helper function is used to find the beginning of a KFENCE-allocated object.h]hXOSL[AU]B-allocated objects are laid out within a page one by one, so it is easy to calculate the beginning of an object given a pointer inside it and the object size. The same is not true for KFENCE, which places a single object at either end of the page. This helper function is used to find the beginning of a KFENCE-allocated object.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjZubeh}(h]h ] kernelindentah"]h$]h&]uh1jhjhhhNhNubj)}(hhh]h}(h]h ]h"]h$]h&]entries](j__kfence_free (C function)c.__kfence_freehNtauh1jhjhhhNhNubj)}(hhh](j)}(hvoid __kfence_free (void *addr)h]j#)}(hvoid __kfence_free(void *addr)h](j))}(hvoidh]hvoid}(hj&hhhNhNubah}(h]h ]j5ah"]h$]h&]uh1j(hj"hhhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKubj;)}(h h]h }(hj5hhhNhNubah}(h]h ]jGah"]h$]h&]uh1j:hj"hhhj4hKubjL)}(h __kfence_freeh]jR)}(h __kfence_freeh]h __kfence_free}(hjGhhhNhNubah}(h]h ]j^ah"]h$]h&]uh1jQhjCubah}(h]h ](jejfeh"]h$]h&]hhuh1jKhj"hhhj4hKubjk)}(h (void *addr)h]jq)}(h void *addrh](j))}(hvoidh]hvoid}(hjchhhNhNubah}(h]h ]j5ah"]h$]h&]uh1j(hj_ubj;)}(h h]h }(hjqhhhNhNubah}(h]h ]jGah"]h$]h&]uh1j:hj_ubj)}(hjh]h*}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhj_ubjR)}(haddrh]haddr}(hjhhhNhNubah}(h]h ]j^ah"]h$]h&]uh1jQhj_ubeh}(h]h ]h"]h$]h&]noemphhhuh1jphj[ubah}(h]h ]h"]h$]h&]hhuh1jjhj"hhhj4hKubeh}(h]h ]h"]h$]h&]hhjuh1j"jjhjhhhj4hKubah}(h]jah ](jjeh"]h$]h&]jj)jhuh1jhj4hKhjhhubj)}(hhh]h)}(h+release a KFENCE heap object to KFENCE poolh]h+release a KFENCE heap object to KFENCE pool}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjhhubah}(h]h ]h"]h$]h&]uh1jhjhhhj4hKubeh}(h]h ](j functioneh"]h$]h&]jj jjjjjjjuh1jhhhjhNhNubj)}(h**Parameters** ``void *addr`` object to be freed **Description** Requires: is_kfence_address(addr) Release a KFENCE object and mark it as freed.h](h)}(h**Parameters**h]j#)}(hjh]h Parameters}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j"hjubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjubj9)}(hhh]j>)}(h"``void *addr`` object to be freed h](jD)}(h``void *addr``h]jA)}(hjh]h void *addr}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1jChX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjubj^)}(hhh]h)}(hobject to be freedh]hobject to be freed}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhj hKhj ubah}(h]h ]h"]h$]h&]uh1j]hjubeh}(h]h ]h"]h$]h&]uh1j=hj hKhjubah}(h]h ]h"]h$]h&]uh1j8hjubh)}(h**Description**h]j#)}(hj2h]h Description}(hj4hhhNhNubah}(h]h ]h"]h$]h&]uh1j"hj0ubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjubh)}(h!Requires: is_kfence_address(addr)h]h!Requires: is_kfence_address(addr)}(hjHhhhNhNubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjubh)}(h-Release a KFENCE object and mark it as freed.h]h-Release a KFENCE object and mark it as freed.}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjubeh}(h]h ] kernelindentah"]h$]h&]uh1jhjhhhNhNubj)}(hhh]h}(h]h ]h"]h$]h&]entries](jkfence_free (C function) c.kfence_freehNtauh1jhjhhhNhNubj)}(hhh](j)}(hbool kfence_free (void *addr)h]j#)}(hbool kfence_free(void *addr)h](j))}(hj,h]hbool}(hjhhhNhNubah}(h]h ]j5ah"]h$]h&]uh1j(hjhhhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKubj;)}(h h]h }(hjhhhNhNubah}(h]h ]jGah"]h$]h&]uh1j:hjhhhjhKubjL)}(h kfence_freeh]jR)}(h kfence_freeh]h kfence_free}(hjhhhNhNubah}(h]h ]j^ah"]h$]h&]uh1jQhjubah}(h]h ](jejfeh"]h$]h&]hhuh1jKhjhhhjhKubjk)}(h (void *addr)h]jq)}(h void *addrh](j))}(hvoidh]hvoid}(hjhhhNhNubah}(h]h ]j5ah"]h$]h&]uh1j(hjubj;)}(h h]h }(hjhhhNhNubah}(h]h ]jGah"]h$]h&]uh1j:hjubj)}(hjh]h*}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubjR)}(haddrh]haddr}(hjhhhNhNubah}(h]h ]j^ah"]h$]h&]uh1jQhjubeh}(h]h ]h"]h$]h&]noemphhhuh1jphjubah}(h]h ]h"]h$]h&]hhuh1jjhjhhhjhKubeh}(h]h ]h"]h$]h&]hhjuh1j"jjhj~hhhjhKubah}(h]jyah ](jjeh"]h$]h&]jj)jhuh1jhjhKhj{hhubj)}(hhh]h)}(h6try to release an arbitrary heap object to KFENCE poolh]h6try to release an arbitrary heap object to KFENCE pool}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjhhubah}(h]h ]h"]h$]h&]uh1jhj{hhhjhKubeh}(h]h ](j functioneh"]h$]h&]jj jj-jj-jjjuh1jhhhjhNhNubj)}(hX**Parameters** ``void *addr`` object to be freed **Return** * false - object doesn't belong to KFENCE pool and was ignored, * true - object was released to KFENCE pool. **Description** Release a KFENCE object and mark it as freed. May be called on any object, even non-KFENCE objects, to simplify integration of the hooks into the allocator's free codepath. The allocator must check the return value to determine if it was a KFENCE object or not.h](h)}(h**Parameters**h]j#)}(hj7h]h Parameters}(hj9hhhNhNubah}(h]h ]h"]h$]h&]uh1j"hj5ubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhj1ubj9)}(hhh]j>)}(h"``void *addr`` object to be freed h](jD)}(h``void *addr``h]jA)}(hjVh]h void *addr}(hjXhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjTubah}(h]h ]h"]h$]h&]uh1jChX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjPubj^)}(hhh]h)}(hobject to be freedh]hobject to be freed}(hjohhhNhNubah}(h]h ]h"]h$]h&]uh1hhjkhKhjlubah}(h]h ]h"]h$]h&]uh1j]hjPubeh}(h]h ]h"]h$]h&]uh1j=hjkhKhjMubah}(h]h ]h"]h$]h&]uh1j8hj1ubh)}(h **Return**h]j#)}(hjh]hReturn}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j"hjubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhj1ubj7)}(hhh](j<)}(h=false - object doesn't belong to KFENCE pool and was ignored,h]h)}(hjh]h?false - object doesn’t belong to KFENCE pool and was ignored,}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjubah}(h]h ]h"]h$]h&]uh1j;hjubj<)}(h,true - object was released to KFENCE pool. h]h)}(h+true - object was released to KFENCE pool.h]h+true - object was released to KFENCE pool.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjubah}(h]h ]h"]h$]h&]uh1j;hjubeh}(h]h ]h"]h$]h&]jjuh1j6hjhKhj1ubh)}(h**Description**h]j#)}(hjh]h Description}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j"hjubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhj1ubh)}(hXRelease a KFENCE object and mark it as freed. May be called on any object, even non-KFENCE objects, to simplify integration of the hooks into the allocator's free codepath. The allocator must check the return value to determine if it was a KFENCE object or not.h]hXRelease a KFENCE object and mark it as freed. May be called on any object, even non-KFENCE objects, to simplify integration of the hooks into the allocator’s free codepath. The allocator must check the return value to determine if it was a KFENCE object or not.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhj1ubeh}(h]h ] kernelindentah"]h$]h&]uh1jhjhhhNhNubj)}(hhh]h}(h]h ]h"]h$]h&]entries](j%kfence_handle_page_fault (C function)c.kfence_handle_page_faulthNtauh1jhjhhhNhNubj)}(hhh](j)}(hWbool kfence_handle_page_fault (unsigned long addr, bool is_write, struct pt_regs *regs)h]j#)}(hVbool kfence_handle_page_fault(unsigned long addr, bool is_write, struct pt_regs *regs)h](j))}(hj,h]hbool}(hj(hhhNhNubah}(h]h ]j5ah"]h$]h&]uh1j(hj$hhhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKubj;)}(h h]h }(hj6hhhNhNubah}(h]h ]jGah"]h$]h&]uh1j:hj$hhhj5hKubjL)}(hkfence_handle_page_faulth]jR)}(hkfence_handle_page_faulth]hkfence_handle_page_fault}(hjHhhhNhNubah}(h]h ]j^ah"]h$]h&]uh1jQhjDubah}(h]h ](jejfeh"]h$]h&]hhuh1jKhj$hhhj5hKubjk)}(h9(unsigned long addr, bool is_write, struct pt_regs *regs)h](jq)}(hunsigned long addrh](j))}(hunsignedh]hunsigned}(hjdhhhNhNubah}(h]h ]j5ah"]h$]h&]uh1j(hj`ubj;)}(h h]h }(hjrhhhNhNubah}(h]h ]jGah"]h$]h&]uh1j:hj`ubj))}(hlongh]hlong}(hjhhhNhNubah}(h]h ]j5ah"]h$]h&]uh1j(hj`ubj;)}(h h]h }(hjhhhNhNubah}(h]h ]jGah"]h$]h&]uh1j:hj`ubjR)}(haddrh]haddr}(hjhhhNhNubah}(h]h ]j^ah"]h$]h&]uh1jQhj`ubeh}(h]h ]h"]h$]h&]noemphhhuh1jphj\ubjq)}(h bool is_writeh](j))}(hj,h]hbool}(hjhhhNhNubah}(h]h ]j5ah"]h$]h&]uh1j(hjubj;)}(h h]h }(hjhhhNhNubah}(h]h ]jGah"]h$]h&]uh1j:hjubjR)}(his_writeh]his_write}(hjhhhNhNubah}(h]h ]j^ah"]h$]h&]uh1jQhjubeh}(h]h ]h"]h$]h&]noemphhhuh1jphj\ubjq)}(hstruct pt_regs *regsh](jw)}(hjVh]hstruct}(hjhhhNhNubah}(h]h ]jah"]h$]h&]uh1jvhjubj;)}(h h]h }(hjhhhNhNubah}(h]h ]jGah"]h$]h&]uh1j:hjubh)}(hhh]jR)}(hpt_regsh]hpt_regs}(hjhhhNhNubah}(h]h ]j^ah"]h$]h&]uh1jQhjubah}(h]h ]h"]h$]h&] refdomainj reftypej reftargetj modnameN classnameNjj)}j]j)}jjJsbc.kfence_handle_page_faultasbuh1hhjubj;)}(h h]h }(hj'hhhNhNubah}(h]h ]jGah"]h$]h&]uh1j:hjubj)}(hjh]h*}(hj5hhhNhNubah}(h]h ]jah"]h$]h&]uh1jhjubjR)}(hregsh]hregs}(hjBhhhNhNubah}(h]h ]j^ah"]h$]h&]uh1jQhjubeh}(h]h ]h"]h$]h&]noemphhhuh1jphj\ubeh}(h]h ]h"]h$]h&]hhuh1jjhj$hhhj5hKubeh}(h]h ]h"]h$]h&]hhjuh1j"jjhj hhhj5hKubah}(h]jah ](jjeh"]h$]h&]jj)jhuh1jhj5hKhjhhubj)}(hhh]h)}(h,perform page fault handling for KFENCE pagesh]h,perform page fault handling for KFENCE pages}(hjlhhhNhNubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjihhubah}(h]h ]h"]h$]h&]uh1jhjhhhj5hKubeh}(h]h ](j functioneh"]h$]h&]jj jjjjjjjuh1jhhhjhNhNubj)}(hXL**Parameters** ``unsigned long addr`` faulting address ``bool is_write`` is access a write ``struct pt_regs *regs`` current struct pt_regs (can be NULL, but shows full stack trace) **Return** * false - address outside KFENCE pool, * true - page fault handled by KFENCE, no additional handling required. **Description** A page fault inside KFENCE pool indicates a memory error, such as an out-of-bounds access, a use-after-free or an invalid memory access. In these cases KFENCE prints an error message and marks the offending page as present, so that the kernel can proceed.h](h)}(h**Parameters**h]j#)}(hjh]h Parameters}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j"hjubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjubj9)}(hhh](j>)}(h(``unsigned long addr`` faulting address h](jD)}(h``unsigned long addr``h]jA)}(hjh]hunsigned long addr}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1jChX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjubj^)}(hhh]h)}(hfaulting addressh]hfaulting address}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjubah}(h]h ]h"]h$]h&]uh1j]hjubeh}(h]h ]h"]h$]h&]uh1j=hjhKhjubj>)}(h$``bool is_write`` is access a write h](jD)}(h``bool is_write``h]jA)}(hjh]h bool is_write}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1jChX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjubj^)}(hhh]h)}(his access a writeh]his access a write}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhKhjubah}(h]h ]h"]h$]h&]uh1j]hjubeh}(h]h ]h"]h$]h&]uh1j=hjhKhjubj>)}(hZ``struct pt_regs *regs`` current struct pt_regs (can be NULL, but shows full stack trace) h](jD)}(h``struct pt_regs *regs``h]jA)}(hjh]hstruct pt_regs *regs}(hj!hhhNhNubah}(h]h ]h"]h$]h&]uh1j@hjubah}(h]h ]h"]h$]h&]uh1jChX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjubj^)}(hhh]h)}(h@current struct pt_regs (can be NULL, but shows full stack trace)h]h@current struct pt_regs (can be NULL, but shows full stack trace)}(hj8hhhNhNubah}(h]h ]h"]h$]h&]uh1hhj4hKhj5ubah}(h]h ]h"]h$]h&]uh1j]hjubeh}(h]h ]h"]h$]h&]uh1j=hj4hKhjubeh}(h]h ]h"]h$]h&]uh1j8hjubh)}(h **Return**h]j#)}(hjZh]hReturn}(hj\hhhNhNubah}(h]h ]h"]h$]h&]uh1j"hjXubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjubj7)}(hhh](j<)}(h$false - address outside KFENCE pool,h]h)}(hjuh]h$false - address outside KFENCE pool,}(hjwhhhNhNubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjsubah}(h]h ]h"]h$]h&]uh1j;hjpubj<)}(hGtrue - page fault handled by KFENCE, no additional handling required. h]h)}(hFtrue - page fault handled by KFENCE, no additional handling required.h]hFtrue - page fault handled by KFENCE, no additional handling required.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjubah}(h]h ]h"]h$]h&]uh1j;hjpubeh}(h]h ]h"]h$]h&]jjuh1j6hjhKhjubh)}(h**Description**h]j#)}(hjh]h Description}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1j"hjubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjubh)}(hA page fault inside KFENCE pool indicates a memory error, such as an out-of-bounds access, a use-after-free or an invalid memory access. In these cases KFENCE prints an error message and marks the offending page as present, so that the kernel can proceed.h]hA page fault inside KFENCE pool indicates a memory error, such as an out-of-bounds access, a use-after-free or an invalid memory access. In these cases KFENCE prints an error message and marks the offending page as present, so that the kernel can proceed.}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhX/var/lib/git/docbuild/linux/Documentation/dev-tools/kfence:319: ./include/linux/kfence.hhKhjubeh}(h]h ] kernelindentah"]h$]h&]uh1jhjhhhNhNubeh}(h] interfaceah ]h"] interfaceah$]h&]uh1hhhhhhhhM:ubh)}(hhh](h)}(h Related Toolsh]h Related Tools}(hjhhhNhNubah}(h]h ]h"]h$]h&]uh1hhjhhhhhMGubh)}(hXIn userspace, a similar approach is taken by `GWP-ASan `_. GWP-ASan also relies on guard pages and a sampling strategy to detect memory unsafety bugs at scale. KFENCE's design is directly influenced by GWP-ASan, and can be seen as its kernel sibling. Another similar but non-sampling approach, that also inspired the name "KFENCE", can be found in the userspace `Electric Fence Malloc Debugger `_.h](h-In userspace, a similar approach is taken by }(hjhhhNhNubh reference)}(h/`GWP-ASan `_h]hGWP-ASan}(hjhhhNhNubah}(h]h ]h"]h$]h&]nameGWP-ASanrefuri!http://llvm.org/docs/GwpAsan.htmluh1jhjubhtarget)}(h$ h]h}(h]gwp-asanah ]h"]gwp-asanah$]h&]refurij uh1j  referencedKhjubhX7. GWP-ASan also relies on guard pages and a sampling strategy to detect memory unsafety bugs at scale. KFENCE’s design is directly influenced by GWP-ASan, and can be seen as its kernel sibling. Another similar but non-sampling approach, that also inspired the name “KFENCE”, can be found in the userspace }(hjhhhNhNubj)}(hF`Electric Fence Malloc Debugger `_h]hElectric Fence Malloc Debugger}(hj!hhhNhNubah}(h]h ]h"]h$]h&]nameElectric Fence Malloc Debuggerj "https://linux.die.net/man/3/efenceuh1jhjubj)}(h% h]h}(h]electric-fence-malloc-debuggerah ]h"]electric fence malloc debuggerah$]h&]refurij1uh1j jKhjubh.}(hjhhhNhNubeh}(h]h ]h"]h$]h&]uh1hhhhMIhjhhubh)}(hIn the kernel, several tools exist to debug memory access errors, and in particular KASAN can detect all bug classes that KFENCE can detect. While KASAN is more precise, relying on compiler instrumentation, this comes at a performance cost.h]hIn the kernel, several tools exist to debug memory access errors, and in particular KASAN can detect all bug classes that KFENCE can detect. While KASAN is more precise, relying on compiler instrumentation, this comes at a performance cost.}(hjIhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMQhjhhubh)}(hXIt is worth highlighting that KASAN and KFENCE are complementary, with different target environments. For instance, KASAN is the better debugging-aid, where test cases or reproducers exists: due to the lower chance to detect the error, it would require more effort using KFENCE to debug. Deployments at scale that cannot afford to enable KASAN, however, would benefit from using KFENCE to discover bugs due to code paths not exercised by test cases or fuzzers.h]hXIt is worth highlighting that KASAN and KFENCE are complementary, with different target environments. For instance, KASAN is the better debugging-aid, where test cases or reproducers exists: due to the lower chance to detect the error, it would require more effort using KFENCE to debug. Deployments at scale that cannot afford to enable KASAN, however, would benefit from using KFENCE to discover bugs due to code paths not exercised by test cases or fuzzers.}(hjWhhhNhNubah}(h]h ]h"]h$]h&]uh1hhhhMVhjhhubeh}(h] related-toolsah ]h"] related toolsah$]h&]uh1hhhhhhhhMGubeh}(h]kernel-electric-fence-kfenceah ]h"]kernel electric-fence (kfence)ah$]h&]uh1hhhhhhhhKubeh}(h]h ]h"]h$]h&]sourcehuh1hcurrent_sourceN current_lineNsettingsdocutils.frontendValues)}(hN generatorN datestampN source_linkN source_urlN toc_backlinksentryfootnote_backlinksK sectnum_xformKstrip_commentsNstrip_elements_with_classesN strip_classesN report_levelK halt_levelKexit_status_levelKdebugNwarning_streamN tracebackinput_encoding utf-8-siginput_encoding_error_handlerstrictoutput_encodingutf-8output_encoding_error_handlerjerror_encodingutf-8error_encoding_error_handlerbackslashreplace language_codeenrecord_dependenciesNconfigN id_prefixhauto_id_prefixid dump_settingsNdump_internalsNdump_transformsNdump_pseudo_xmlNexpose_internalsNstrict_visitorN_disable_configN_sourcehnj _destinationN _config_files]7/var/lib/git/docbuild/linux/Documentation/docutils.confafile_insertion_enabled raw_enabledKline_length_limitM'pep_referencesN pep_base_urlhttps://peps.python.org/pep_file_url_templatepep-%04drfc_referencesN rfc_base_url&https://datatracker.ietf.org/doc/html/ tab_widthKtrim_footnote_reference_spacesyntax_highlightlong smart_quotessmartquotes_locales]character_level_inline_markupdoctitle_xform docinfo_xformKsectsubtitle_xform image_loadinglinkembed_stylesheetcloak_email_addressessection_self_linkenvNubreporterNindirect_targets]substitution_defs}substitution_names}refnames}refids}nameids}(jrjoj%j"jjjjjjjjjjjjjgjjj;j8u nametypes}(jrj%jjjjjjjjj;uh}(johj"j jjjjjjjj(jjjjj jj j j j jyj~jjjyj~jj jgjjjj8j2u footnote_refs} citation_refs} autofootnotes]autofootnote_refs]symbol_footnotes]symbol_footnote_refs] footnotes] citations]autofootnote_startKsymbol_footnote_startK id_counter collectionsCounter}Rparse_messages]transform_messages] transformerN include_log] decorationNhhub.