Commit graph

2,153 commits

Author SHA1 Message Date
Krzysztof Chruściński
458f494289 logging: Add option to process printk using static macros
Added option CONFIG_LOG_PRINTK_STATIC which redirects printk's to
logging macro which creates message during compilation by examining
argument types using _Generic keyword. When this option is enabled
printk format string is not accessed in runtime so it can be removed
(e.g. in dictionary based logging). When this option is enabled printk
is much faster. Option is implied when dictionary based logging is
enabled.

The only condition that must be met to use build time message creation
macros is that format string is a string literal and not a variable.
That is the case for printk because it is using __printf_like gcc
extension to validate that.

Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
2026-07-03 13:58:02 +02:00
Jinming Zhao
217e2913a1 lib: heap: kasan: lightweight heap write sanitizer for sys_heap
Lightweight write sanitizer for sys_heap.  Uses
-fsanitize=kernel-address compiler instrumentation combined with a
per-heap shadow bitarray (one bit per granule) to detect buffer
overflows, underflows, and use-after-free on write accesses.

Ships its own lightweight sanitizer runtime (__asan_store* callbacks);
does not depend on an external ASAN library and supports debugging on
real embedded targets.

Instrumentation is opt-in per CMake target via
zephyr_target_enable_heap_kasan(), or per directory via
zephyr_heap_kasan_enable_directory().  Only writes are checked
(-asan-instrument-reads=0).  Bulk-write library calls (memset,
memcpy, str*, printf family) are redirected to checked wrappers at
compile time via -Dfoo=__asan_foo, requiring no source changes in
application code.

Heap tracking is likewise opt-in: register each heap with
SYS_HEAP_KASAN_ENABLE() / K_HEAP_KASAN_ENABLE(), or enable
CONFIG_SYS_HEAP_KASAN_MALLOC / CONFIG_SYS_HEAP_KASAN_SYSTEM for the
common libc malloc and kernel system heaps.

Usage:

  CONFIG_SYS_HEAP_KASAN=y
  CONFIG_SYS_HEAP_KASAN_MALLOC=y   # auto-track malloc/free
  CONFIG_SYS_HEAP_KASAN_SYSTEM=y   # auto-track k_malloc/k_free

  # Instrument all sources of <target> (CMakeLists.txt)
  zephyr_target_enable_heap_kasan(app)
  # Or instrument sources under <dir>
  zephyr_heap_kasan_enable_directory(src/mymodule)

  /* Opt-in tracking for a custom heap */
  K_HEAP_DEFINE(my_heap, 4096);
  K_HEAP_KASAN_ENABLE(my_heap, 4096);

Signed-off-by: Jinming Zhao <jinmzhao@qti.qualcomm.com>
2026-07-01 05:21:22 -04:00
Fabio Baltieri
aa014f60b5 lib: heap: use single evaluation min
Change these (back) to the single use version, they have been changed
recently for "consistency" reasons but that seems to be incorrect.

Signed-off-by: Fabio Baltieri <fabiobaltieri@google.com>
2026-06-30 18:23:25 -04:00
Zach Van Camp
7e9d3e3476 kernel: Add RESET_ON_FATAL_ERROR kconfig option
Add an optional reset when a hard fault occurs.

Signed-off-by: Zach Van Camp <zach.vancamp@etcconnect.com>
2026-06-29 22:18:47 -04:00
Tomasz Leman
5cba4b75e8 lib: heap: add ASAN poisoning backend for sys_heap
Add a sys_heap sanitizer backend behind the SYS_HEAP_SANITIZER_HOOKS.
The backend integrates the toolchain's Address Sanitizer (ASAN) runtime
for use on native simulator based platforms.

The backend (heap_sanitizer_asan.c) implements the three hook entry
points as thin wrappers over the ASAN manual poisoning runtime:
sys_heap_init poisons the whole heap buffer, a successful allocation
unpoisons exactly the user-requested region and a free re-poisons the
usable region. Accesses to freed, never-allocated or out-of-bounds heap
memory are then reported by ASAN with a full backtrace and shadow dump.
The init hook runs at the end of sys_heap_init (after the bucket array
has been zeroed), so the chunk headers and internal metadata stay
poisoned for the lifetime of the heap and act as permanent redzones.

The heap implementation owns the bytes it poisons (chunk headers,
free-list links, canaries), so the heap internal sources are excluded
from ASAN instrumentation with -fno-sanitize=address. Those sources are
added to the root-scoped "zephyr" target, so the COMPILE_OPTIONS
property is set with TARGET_DIRECTORY; a plain
set_source_files_properties() in this directory does not reach the
target and leaves the sources instrumented.

SYS_HEAP_SANITIZER_ASAN requires the big-heap chunk format so the user
pointer and the end of the usable region are 8-byte aligned, matching
ASAN's shadow granularity (implied on 64-bit, explicit on 32-bit). The
runtime API and manual poisoning interface are common to GCC (libasan)
and Clang/LLVM (compiler-rt), so the feature is not tied to a single
compiler.

Verified on native_sim: in-bounds allocation and access across a range
of sizes is clean (no false positives) and a use-after-free is reported,
with both the host GCC and host LLVM toolchains.

Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
2026-06-26 13:01:30 -04:00
Tomasz Leman
f82e45c6d3 lib: heap: add sanitizer hook for sys_heap
Introduce a single set of hook points so a heap memory sanitizer can be
plugged into sys_heap without scattering backend-specific conditionals
through heap.c.

A new internal header lib/heap/heap_sanitizer.h declares three entry
points:

  heap_sanitizer_on_init (heap, mem, bytes)   poison the whole heap buffer
  heap_sanitizer_on_alloc(heap, mem, bytes)   unpoison [mem, mem+bytes)
  heap_sanitizer_on_free (heap, mem, bytes)   re-poison the usable region

heap.c calls them at the public-API boundary (sys_heap_init,
sys_heap_alloc, sys_heap_aligned_alloc, sys_heap_free) gated on a hidden
CONFIG_SYS_HEAP_SANITIZER_HOOKS symbol that a backend selects. In-place
realloc is expressed as on_free(old_usable) followed by on_alloc(new),
which produces the correct shadow for both grow and shrink without a
dedicated re-poison helper.

The allocate-and-copy realloc fallback re-grants access to the source
block's full usable region around the internal memcpy (which a
reads-checking backend would otherwise keep poisoned past the requested
size) and lets the subsequent free re-poison it.

No backend is provided here, so CONFIG_SYS_HEAP_SANITIZER_HOOKS is
unset and the hooks compile to nothing: no functional change. Verified
that tests/lib/heap still passes on native_sim.

Assisted-by: Copilot:claude-opus-4.8
Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
2026-06-26 13:01:30 -04:00
Tomasz Leman
1824b00efd lib: heap: use uppercase MIN macro in realloc paths
Replace lowercase min() with the standard Zephyr MIN() macro
in sys_heap_realloc() and sys_heap_aligned_realloc() for
consistency with the rest of the codebase.

No functional change.

Signed-off-by: Tomasz Leman <tomasz.m.leman@intel.com>
2026-06-26 13:01:30 -04:00
Anas Nashif
255e64bd22 midi2: zero-initialise UMP stream notification buffers
make_endpoint_info() and make_function_block_info() populate only the
first two words of the 128-bit UMP, leaving the remaining two words
uninitialised. They are sent verbatim, leaking 8 bytes of stack to any
UMP peer per request.

Zero-initialise the struct.

Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-06-24 13:56:19 -04:00
Etienne Carriere
355b57d2da lib: os: cbprintf: Fix inline comment typo is=>if
Fix typo replacing 'is' with 'if' in a cbprintf_packaged inline comment.

Signed-off-by: Etienne Carriere <etienne.carriere@st.com>
2026-06-24 07:40:41 -04:00
Nicolas Pitre
97fac4b782 kernel: mmu: remove LINKER_USE_PINNED_SECTION and __pinned_* tagging
CONFIG_LINKER_USE_PINNED_SECTION is the second half of the selective
kernel-pinning model removed in issue #108773. With the kernel image
now always resident at boot (previous commit), the __pinned_*
attribute family is a no-op: every page they would have segregated is
already pinned by z_mem_manage_init()'s whole-image loop, so the
tagging contract neither adds safety nor remains maintainable.

Drop it.

Mechanical removals:

* All ~219 in-tree uses of __pinned_text, __pinned_rodata,
  __pinned_data, __pinned_bss, __pinned_noinit, and __pinned_func
  across arch/x86, drivers/interrupt_controller, drivers/timer,
  arch/common, kernel, lib/libc, subsys/portability/posix, tests, and
  the syscall code generator (scripts/build/gen_syscalls.py).

* The assembly aliases PINNED_TEXT/RODATA/DATA/BSS/NOINIT used in
  arch/x86/core/ia32/*.S and drivers/interrupt_controller/
  intc_loapic_spurious.S become plain TEXT/RODATA/DATA/BSS/NOINIT.

* K_KERNEL_PINNED_STACK_DEFINE, K_KERNEL_PINNED_STACK_ARRAY_DEFINE,
  K_KERNEL_PINNED_STACK_ARRAY_DECLARE, K_THREAD_PINNED_STACK_DEFINE,
  and K_THREAD_PINNED_STACK_ARRAY_DEFINE are removed. The few
  in-tree callers (kernel/init.c, arch/arm/core/cortex_a_r/smp.c,
  arch/arm64/core/fatal.c, arch/rx/core/prep_c.c,
  arch/x86/core/prep_c.c, kernel/include/kernel_internal.h,
  tests/bluetooth/hci_uart_async) move to the corresponding
  non-pinned macros.

Machinery removals:

* Kconfig.zephyr drops CONFIG_LINKER_USE_PINNED_SECTION.
  qemu_x86_tiny and qemu_x86_atom_virt drop their =y overrides.

* include/zephyr/linker/section_tags.h drops the __pinned_* macro
  definitions (both arms). __isr collapses to an empty macro since
  its only purpose was to alias __pinned_func.

* include/zephyr/linker/sections.h drops PINNED_TEXT_SECTION_NAME,
  PINNED_BSS_SECTION_NAME, etc. and the bare PINNED_TEXT/RODATA/etc.
  forwarders, plus the _APP_SMEM_PINNED_SECTION_NAME constant.

* include/zephyr/linker/linker-defs.h drops the lnkr_pinned_*
  externs, the _app_smem_pinned_* externs, and the lnkr_is_pinned()
  / lnkr_is_region_pinned() inline helpers.

* include/zephyr/linker/utils.h drops the lnkr_pinned_rodata branch
  in linker_is_in_rodata().

* include/zephyr/linker/app_smem_pinned{,_aligned,_unaligned}.ld
  are deleted; cmake/linker/ld/target_configure.cmake stops
  configuring them.

* boards/qemu/x86/qemu_x86_tiny.ld and
  include/zephyr/arch/x86/ia32/linker.ld drop their pinned-section
  blocks and the now-redundant #ifndef CONFIG_LINKER_USE_PINNED_SECTION
  conditionals throughout the body. The
  LIB_KERNEL_IN_SECT / LIB_ARCH_X86_IN_SECT / LIB_ZEPHYR_IN_SECT /
  LIB_C_IN_SECT / LIB_DRIVERS_IN_SECT / LIB_SUBSYS_LOGGING_IN_SECT /
  LIB_ZEPHYR_OBJECT_FILE_IN_SECT / ZEPHYR_KERNEL_FUNCS_IN_SECT macros
  in qemu_x86_tiny.ld are deleted; they existed only to feed the
  pinned text/rodata/data/bss/noinit sections.

* kernel/mmu.c drops the mark_linker_section_pinned(lnkr_pinned_start,
  ...) call. The mark_linker_section_pinned() helper survives but is
  now gated only on CONFIG_LINKER_USE_BOOT_SECTION.

* arch/common/init.c and include/zephyr/arch/common/init.h drop
  arch_bss_zero_pinned(); arch/x86/core/ia32/crt0.S drops the call
  to it.

* arch/x86/core/userspace.c drops the eager k_mem_page_in() of the
  thread's privileged stack on user-mode entry. With the kernel
  image fully resident the stack is already mapped.

* arch/x86/gen_mmu.py drops map_region("lnkr_pinned") and the
  set_region_perms() calls for lnkr_pinned_text / lnkr_pinned_rodata.

* CMakeLists.txt drops the LINKER_USE_PINNED_SECTION block that
  generated APP_SMEM_PINNED_* variables and the
  pinned_partitions target property feeding gen_app_partitions.py.
  cmake/modules/extensions.cmake removes the PINNED_RODATA /
  PINNED_RAM_SECTIONS / PINNED_DATA_SECTIONS zephyr_linker_sources()
  location keywords and their snippet files.
  scripts/build/gen_app_partitions.py drops --pinoutput /
  --pinpartitions arguments and the pinned-output branch.
  subsys/testsuite/coverage/CMakeLists.txt drops its
  CONFIG_DEMAND_PAGING-conditional fork.

* scripts/build/gen_kobject_list.py drops the
  app_smem_pinned_start / _end fallback for kobject placement
  validation.

* tests/arch/x86/pagetables and tests/kernel/mem_protect/userspace
  drop their lnkr_pinned_text / lnkr_pinned_rodata branches.

* include/zephyr/arch/x86/ia32/arch.h folds IRQSTUBS_TEXT_SECTION
  to the unconditional ".text.irqstubs" form.

* tests/subsys/llext/src/syscalls_ext.c drops a stale comment about
  syscalls landing in .pinned_text.

Targeted retentions:

* arch/x86/core/bootargs.c keeps multiboot_cmdline and efi_bootargs
  in .noinit (was __pinned_noinit, which decayed to __noinit when
  LINKER_USE_PINNED_SECTION was unset). The multiboot and zefi loader
  paths write these buffers before Zephyr's BSS-zero step, so
  zeroing them at boot loses the cmdline.

* arch/x86/core/ia32/fatal.c keeps _df_esf and _df_stack in .noinit.
  They are scratch space written by the double-fault handler and have
  no zero-init requirement; keeping them in .noinit also preserves
  the historical post-noinit alignment that gen_mmu.py relies on
  (z_mapped_size is computed before CMake-injected iterable sections
  are appended to the linker script, so the post-noinit page padding
  is what keeps those sections within the mapped region).

* include/zephyr/arch/x86/ia32/syscall.h and
  include/zephyr/arch/x86/arch.h wrap the per-arch
  arch_syscall_invoke* / arch_is_user_context / arch_k_cycle_get_*
  implementations in @cond INTERNAL_HIDDEN. The public Doxygen
  contract lives on the prototypes in
  include/zephyr/arch/arch_interface.h; the per-arch implementations
  are internal. Without this, removing the __pinned_func attribute
  exposes the implementations to the doxygen-coverage delta check
  as 10 newly-undocumented APIs.

Documentation updates are deferred to a separate commit.

Issue: #108773

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2026-06-23 09:11:08 -04:00
Robert Lubos
731bcf72c7 lib: os: zvfs: Add additive eventfd count mechanism
Similarly to the existing CONFIG_ZVFS_OPEN_ADD_SIZE_* mechanism used to
size the file descriptor table, allow subsystems to declare their eventfd
count requirements via CONFIG_ZVFS_EVENTFD_ADD_SIZE_* Kconfig options.
These are summed up at build time and compared against
CONFIG_ZVFS_EVENTFD_MAX, with the larger of the two values used to size
the eventfd table, exposed as the ZVFS_EVENTFD_SIZE compile definition.

A new CONFIG_ZVFS_EVENTFD_IGNORE_MIN option allows to override the
calculated requirement and use CONFIG_ZVFS_EVENTFD_MAX as-is.

As each eventfd also consumes a file descriptor, the resulting eventfd
count is now reserved in the file descriptor table as well, replacing the
former CONFIG_ZVFS_OPEN_ADD_SIZE_EVENTFD option which only accounted for
CONFIG_ZVFS_EVENTFD_MAX.

The WPA supplicant requirement is moved from a CONFIG_ZVFS_EVENTFD_MAX
default into a dedicated
CONFIG_ZVFS_EVENTFD_ADD_SIZE_WIFI_NM_WPA_SUPPLICANT option.

Assisted-by: Cursor:Claude Opus 4.8
Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2026-06-17 11:59:43 -04:00
Peter Mitsis
8419b55701 cbprintf: prevent buffer overflow
Updates cbprintf_package_convert() to prevent a buffer overflows
when copying to local arrays.

Signed-off-by: Peter Mitsis <peter.mitsis@intel.com>
2026-06-17 08:01:09 +02:00
Nicolas Pitre
cf6d9d8fa8 kernel: wait_q: add z_unpend_first_thread_locked() and migrate callers
Replace z_unpend_first_thread() with z_unpend_first_thread_locked() and
migrate every caller across the kernel. The old function dropped the
scheduler spinlock before returning, exposing a race window between
its caller's "arch_thread_return_value_set + z_ready_thread" pair and
a still-in-flight timeout handler that could ready the thread first --
the woken thread might then run on another CPU and see an uninitialized
swap_retval. Pre-1b8c7a3 the dticks-cancel check made the handler bail;
here we fix it cleanly by requiring the caller to hold _sched_spinlock
across the entire wake, so the handler is blocked for the duration and
runs as a no-op afterwards.

z_unpend_first_thread_locked() requires the caller to be inside a
locked region and must be paired with z_sched_ready_locked() (and
whatever return-value setup is needed) under the same lock acquisition.

Sites migrated:

  Simple "set retval [+ swap_data] and ready" callers use the existing
  z_sched_wake() convenience wrapper, refactored to use the new
  helper internally:
    sem (give, reset), mem_slab (free), stack (push),
    condvar (signal, broadcast), msgq (purge),
    queue (cancel_wait, queue_insert, append_list),
    futex (wake).

  Sites that need additional setup on the woken thread use
  LOCK_SCHED_SPINLOCK + z_unpend_first_thread_locked() + custom wake:
    mutex (unlock -- needs the thread reference to track new owner),
    msgq put / get (needs memcpy into the receiver's swap_data
                    buffer before the return value is set).

The dticks-cancel check in z_thread_timeout() is left in place; it is
no longer load-bearing once z_abort_thread_timeout() has no callers,
and is removed in the next commit.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2026-06-15 18:35:49 -04:00
Adarsha Regmi
df81af44a3 lib: libc: picolibc: fix printf variant selection for non-GCC toolchains
Picolibc selects printf variants (minimal, integer, long-long, float)
via --defsym linker directives generated by GCC's picolibc.specs file.
Clang does not support specs files, so the -DPICOLIBC_*_PRINTF_SCANF
flags passed at link time were silently ignored, causing vfprintf to
always resolve to the full implementation regardless of configuration.

Signed-off-by: Adarsha Regmi <aregmi@qti.qualcomm.com>
2026-06-01 18:01:42 -05:00
Mohamed Moawad
73cf2b8507 lib: libc: arcmwdt: declare strsignal() in string.h wrapper
The MWDT toolchain's <string.h> does not declare strsignal(),
which is a POSIX XSI extension. Without a declaration the
compiler treats calls to strsignal() as implicit int-returning
functions, causing the return value to be passed as a pointer:

  error: incompatible integer to pointer conversion passing
  'int' to parameter of type 'const void *'

Add the declaration alongside the existing strnlen() declaration.
The implementation is already provided by Zephyr's POSIX
portability subsystem in subsys/portability/posix/options/signal.c.

Signed-off-by: Mohamed Moawad <moawad@synopsys.com>
2026-05-31 13:40:26 +02:00
Mohamed Moawad
865124768b lib: libc: arcmwdt: fix typedef redefinitions with MWDT toolchain
The MWDT toolchain defines clockid_t as int in its <time.h>, pid_t
as long and uid_t as long in its <sys/types.h>. Zephyr's POSIX
headers redefine these with different underlying types, causing:

  error: typedef redefinition with different types

Fix by including <sys/types.h> early in the arcmwdt <time.h> and
<signal.h> wrappers so that the MWDT type guard macros are set
before posix_time.h and posix_signal.h attempt to define those
types. Also set _PID_T_DECLARED in the arcmwdt <sys/types.h>
wrapper to suppress the conflicting Zephyr pid_t definition.

Signed-off-by: Mohamed Moawad <moawad@synopsys.com>
2026-05-31 13:40:26 +02:00
Marco Casaroli
e0305651f5 picolibc: POSIX device IO fixes
When CONFIG_POSIX_DEVICE_IO and CONFIG_PICOLIBC are enabled,

stdinout_write_vmeth will return 0, causing the write function to
busy-wait forever on file descriptor 1 (stdout).

This change makes the function work with Picolibc, so we can use
write with file descriptor 1 to output data to the stdout_hook of
picolibc.

Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-05-31 13:40:07 +02:00
Valerio Setti
c15cba4e7a modules: mbedtls: rename mbedTLS library and documentation usage
Having an interface library named "mbedTLS" and the real library named
"mbedtls" (as provided by the Mbed TLS module) is misleading.
This commit replaces:
- mbedTLS -> mbedtls_iface for the CMake library. "mbedTLS" is still
             available as alias to "mbedtls_iface" for backward
             compatibility, but this should be removed in the future.
- mbedTLS -> Mbed TLS in comments and documentation.

Signed-off-by: Valerio Setti <vsetti@baylibre.com>
2026-05-27 15:16:06 +01:00
Frank Li
f076de4951 lib: heap: canary check priority and missing poisoning on chunk merge
Fix two issues in heap canary check:

Correct double-free reporting: In sys_heap_free and inplace_realloc, the
basic chunk_used check (from SYS_HEAP_HARDENING_BASIC) was executing
before the canary check (SYS_HEAP_HARDENING_FULL). This caused
inaccurate error messages during double-free events. Reordered
verify_chunk_canary to run before chunk_used to ensure precise
reporting. Move the poison_chunk_canary to free_chunk for unified
poisoning.

Fix missing poisoning after merge: When free chunks were merged, the
pre-merge trailer location, which moves out from under chunk_trailer()
once set_chunk_size updates the size during merge. This led to
subsequent double-free events reading an incorrect canary, which was
misidentified as heap corruption. Therefore, poison the free chunk at
the end of the merge process.

Signed-off-by: Frank Li <lgl88911@163.com>
2026-05-25 13:38:47 +02:00
Nicolas Pitre
90d1963745 sys: util: move lowercase min/max/clamp to a new minmax.h
Since commit 37717b229f ("sys: util: rename Z_MIN Z_MAX Z_CLAMP to min
max and clamp"), <zephyr/sys/util.h> unconditionally defines function-
like macros named `min`, `max`, and `clamp` in the global namespace (in
C mode). util.h gets pulled in transitively by very broad headers,
including the POSIX layer's <pthread.h>, so any third-party C code that
uses these names as ordinary identifiers (e.g. XNNPACK's static `clamp`
helper and its public `clamp` struct field) fails to build as soon as
<pthread.h> is included.

Following the approach used by Linux, move the lowercase `min`, `max`,
`min3`, `max3`, and `clamp` macros (and their helpers) into a new
<zephyr/sys/minmax.h> header that has to be included explicitly by
source files that want them. util.h keeps the uppercase MIN/MAX/CLAMP,
so most code is unaffected; only the (much smaller) set of files that
actually use the lowercase variants needs to pick up the new include.

Fixes #107853.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2026-05-19 17:49:24 -04:00
Pieter De Gendt
7d963833f3 lib: uuid: Add uuid_is_nil
Add helper function to check whether a given UUID is the Nil/empty UUID.

Signed-off-by: Pieter De Gendt <pieter.degendt@basalte.be>
2026-05-18 15:21:10 +01:00
Henrik Brix Andersen
3244a59bbf Revert "os: boot_banner: remove selecting EARLY_CONSOLE"
This reverts commit 19d4060532.

Signed-off-by: Henrik Brix Andersen <hebad@vestas.com>
2026-05-14 19:41:20 +02:00
Fin Maaß
19d4060532 os: boot_banner: remove selecting EARLY_CONSOLE
the boot banner is printed at the end of
the init process with
``SYS_INIT(boot_banner, APPLICATION, 0);``
we don't need the early console for it.
When CONFIG_EARLY_CONSOLE is enabled,
the console will init with PRE_KERNEL_1, otherwise
with POST_KERNEL. Both are before APPLICATION.

Signed-off-by: Fin Maaß <f.maass@vogl-electronic.com>
2026-05-14 15:15:28 +02:00
Diego Solano
63fe39ee5d cbprintf: guard append_string against NULL string pointers
When cbvprintf_package() packages a %s argument, append_string()
eventually calls strlen(str) on the pointer. If the caller passed
NULL to %s, strlen() dereferences address 0. On MMU-less targets
this is undefined behavior; on TF-M targets the SPU fields a read
at address 0 as SECURE_FAULT, which aborts the whole image.

Passing NULL to %s is a caller bug. However, deferred/packaged
logging captures the argument now and dereferences it later,
disconnecting the crash site from the offending call site and
making triage significantly harder. Substitute "(null)" in place
of a NULL string, matching the behavior of glibc's printf family,
so the buggy caller shows up in the log output rather than the
log infrastructure crashing.

Signed-off-by: Diego Solano <diegosolano@gmail.com>
2026-05-13 13:41:39 +01:00
Tomi Fontanilles
e26b5545bb lib: uuid: fix prerequisites for CONFIG_UUID_V5
It should not depend on CONFIG_MBEDTLS nor CONFIG_MBEDTLS_PSA_CRYPTO_C
as a PSA Crypto provider other than Mbed TLS may be enabled.
In fact, it doesn't even need to depend on CONFIG_PSA_CRYPTO
because CONFIG_PSA_WANT_ALG_SHA_1 is already guarded behind
CONFIG_PSA_CRYPTO_CLIENT.

At the same time, replace all the `depends on UUID` by a single if
which is the standard way to do. Also turn CONFIG_UUID into a menuconfig
instead of creating a menu manually.

Signed-off-by: Tomi Fontanilles <tomi.fontanilles@nordicsemi.no>
2026-05-11 10:56:56 +02:00
Jamie McCrae
a036c6ab5b lib: Add support for dts RAM configuration
Allows using the chosen SRAM node for RAM configuration without
using Kconfig values

Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
2026-05-11 08:45:38 +02:00
Robert Lubos
b3d4e29e08 net: sockets: Remove deprecated CONFIG_NET_SOCKETS_POLL_MAX
The CONFIG_NET_SOCKETS_POLL_MAX Kconfig option was deprecated in
Zephyr 4.0.0, remove it and any leftover in-tree option use.

Signed-off-by: Robert Lubos <robert.lubos@nordicsemi.no>
2026-05-08 16:02:17 +01:00
Egill Sigurdur
16ac4a5b78 kernel: mem_slab: add K_MEM_SLAB_DEFINE_TYPE for automatic alignment
Introduces K_MEM_SLAB_DEFINE_TYPE() and K_MEM_SLAB_DEFINE_STATIC_TYPE()
helpers to allow the user to declare slabs for types without having to
manually ensure the alignment is correct.

Manual slab alignment was very error-prone and this change fixes several
instances of misalignment that would be trapped by the undefined
behavior sanitizer when running on 64-bit targets.

Signed-off-by: Egill Sigurdur <egill@egill.xyz>
2026-05-07 18:09:41 -05:00
Tomi Fontanilles
7d65b380e2 modules: mbedtls: link to mbedTLS only when CONFIG_MBEDTLS_BUILTIN
393350fd65 made it so that the `mbedTLS`
library is only created when `CONFIG_MBEDTLS_BUILTIN`.

Before this commit, users of Mbed TLS did the following:
`zephyr_library_link_libraries_ifdef(CONFIG_MBEDTLS mbedTLS)`

If the `mbedTLS` CMake library doesn't exist but is still linked to
(as is the case when `CONFIG_MBEDTLS && !CONFIG_MBEDTLS_BUILTIN`),
the linker command is populated with `-lmbedTLS` which makes the build
fail because there is no `libmbedTLS.a` in the build.

Make it so that users of Mbed TLS only link to the `mbedTLS` CMake
library when the builtin version is used.

Signed-off-by: Tomi Fontanilles <tomi.fontanilles@nordicsemi.no>
2026-05-07 09:11:36 +02:00
Daniel Leung
c91e5e1390 kernel: move atomic_c.c to lib/os
This moves the atomic_c.c from kernel to lib/os as atomic
functions are not exactly kernel features.

This also moves all the atomic kconfigs from kernel to lib/os
as the atomic headers are already under include/zephyr/sys/.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2026-05-01 11:17:27 -05:00
Daniel Leung
b45c82b69b libc: common: rename _k_neg_eagain to _errno_neg_eagain
Since errno is no longer grouped with kernel, we should not be
using kernel prefix.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2026-05-01 11:16:31 -05:00
Daniel Leung
cc61366283 kernel: move errno from kernel to lib/libc/common
errno is not exactly a kernel functionality but more of C
library feature. So move errno from kernel into lib/libc/common.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2026-05-01 11:16:31 -05:00
Pieter De Gendt
15eab8a440 lib: uuid: Add uuid_cmp
Add helper function to compare two UUIDs.

Signed-off-by: Pieter De Gendt <pieter.degendt@basalte.be>
2026-04-30 14:03:16 -04:00
Nicolas Pitre
9bb2878319 net_buf: make reference counts atomic
The two reference counts in the net_buf library -- the per-header
`buf->ref` and the per-data-block `*ref_count` byte at the start of
each variable-data allocation -- were manipulated with plain non-atomic
C operators (`++`, `--`, `if (--rc)`, `if (!rc)`).

The documented contract says otherwise. The Network Buffers chapter of
the Zephyr docs (`doc/services/net_buf/index.rst`) states:

    "The buffers have native support for being passed through k_fifo
     kernel objects. Use k_fifo_put and k_fifo_get to pass buffer from
     one thread to another."

    "The reference count can be incremented with net_buf_ref() or
     decremented with net_buf_unref(). When the count drops to zero the
     buffer is automatically placed back to the free buffers pool."

There is no requirement for callers to hold a higher-level lock around
ref/unref. The API is documented as self-synchronizing, and existing
users (notably zbus's msg-subscriber path) rely on exactly that:
a producer clones a buffer N times and hands the clones off to N
subscriber threads via their FIFOs, after which the N+1 holders
independently call `net_buf_unref()` with no surrounding lock.

With non-atomic decrement-and-test, two CPUs can concurrently observe
the same prior value (e.g. 1), both decrement, and both conclude they
were the last reference. Concrete failure modes:

  * `mem_pool_data_unref`: both CPUs call `k_heap_free(pool, ref_count)`
    on the same block. `k_heap_free` is internally serialized, so the
    duplicate free typically corrupts heap metadata silently.

  * `heap_data_unref`: both CPUs call `k_free(ref_count)` on the same
    block. `k_free` reads the owning `struct k_heap *` from the 8 bytes
    immediately preceding `ref_count`. The first call frees the block
    and the heap-hardening fill replaces those 8 bytes with the poison
    pattern (0xcfdfdfdfdfdfdfcf). The second call then dereferences a
    poisoned pointer and faults inside `k_spin_lock` (translation
    fault on the bogus heap address).

  * `net_buf_unref`: two CPUs racing the per-header decrement-and-test
    can both decide "I am the last reference," both proceed to
    `net_buf_destroy()`, and the buffer is returned to the pool's LIFO
    twice -- silently corrupting the free list.

Fix: use atomic operations on both reference counts.

The per-data-block refcount changes from `uint8_t` to `atomic_t`. This
fits inside the existing `GET_ALIGN(pool)` reservation (>= sizeof(void
*)) at no memory cost.

The per-header `buf->ref` is overlaid in a union with three small
adjacent uint8_t fields (`flags`, `pool_id`, `user_data_size`) and an
`atomic_t ref_word` view of the same storage:

    union {
        atomic_t ref_word;
        struct {
            uint8_t ref;
            uint8_t flags;
            uint8_t pool_id;
            uint8_t user_data_size;
        };
    };

(Byte order conditional on endianness so `ref` is always the LSB of
`ref_word`; on big-endian 64-bit, the byte struct is shifted by 4
bytes of padding for the same reason.)

Net_buf internals issue `atomic_inc(&buf->ref_word)` /
`atomic_dec(&buf->ref_word)` and narrow the returned word value to
`uint8_t` to extract the ref byte. Because the ref count is bounded
to 254 (already implicit in its uint8_t domain), atomic_inc/dec
adjusts only the LSB; the other three bytes are untouched. Plain
uint8_t reads of `buf->ref` from non-atomic call sites continue to
work, so the change is transparent to the dozens of consumers that
read it for diagnostics.

`flags`, `pool_id` and `user_data_size` are written exactly once at
allocation time on a single thread (or, for `flags`, from a context
that owns the buf exclusively such as bt_buf_make_view on a fresh
view), so there are no concurrent byte writes that could conflict
with the atomic word update. struct net_buf does not grow on either
32-bit or 64-bit: on 32-bit the four bytes are exactly `sizeof(long)`,
on 64-bit they fit in alignment padding the next field already
required.

A BUILD_ASSERT in lib/net_buf/buf.c documents the
`atomic_t == long` assumption that the conditional padding relies on.

In `net_buf_unref`, the per-header refcount and the fields needed for
the debug log (`buf->pool_id`) are captured into local variables
*before* the atomic decrement -- once the reference is dropped, another
CPU may immediately free the buffer, so the buffer must not be read
again. The post-decrement diagnostic log uses the value returned by
`atomic_dec` rather than re-reading `buf->ref`. The `pool->avail_count`
sanity check uses the value returned by `atomic_inc` to avoid a
follow-up `atomic_get` of memory another CPU may have changed.

`net_pkt_frag_unref()` previously had the racy
`if (frag->ref == 1U) alloc_del(); net_buf_unref();` pattern; it is
restructured to do the atomic decrement here and slot the tracker call
in atomically with the "I'm the last reference" decision, with
`net_pkt_frag_del()` routed through it.

This bug had been latent. On real SMP hardware the race window is very
small and the typical net_buf consumers (Bluetooth, networking) tend
to use fixed-data pools (`fixed_data_unref` is a no-op). The race
manifests reliably under FVP, where the FastModel's quantum-based
execution model can schedule N threads to all reach the unref point in
the same simulated moment. We discovered it through the zbus
`msg_subscriber_dynamic_isolated` sample, which exchanges shared data
buffers among 16+ subscribers running on 4 SMP cores.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
2026-04-30 07:52:34 +02:00
Daniel Leung
db7a5e80a4 kernel: move bootargs out of kernel into lib/os.
This moves boot arguments from kernel into the lib/os.
This is not strictly a kernel function so this change provides
a separation between core kernel functionalities and others.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2026-04-29 06:23:14 -05:00
Daniel Leung
9fe4cc20a2 kernel: move boot banner into lib/os
Boot banner is not exactly a kernel feature. It is more like
an OS feature so moving it into lib/os.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2026-04-29 06:23:14 -05:00
Anas Nashif
26967bb3a6 arch: common: move lib/acpi into arch/common
acpi is not really library code based on the new definition of what
should go into lib/. Move acpi into arch/common/ as it is cross arch
feature.

Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-04-29 06:16:43 -05:00
Anas Nashif
9b1c89a601 kernel: move gen_offset.h to arch
gen_offset.h is an architecture-specific header, not a kernel one.
Move it under the arch tree where it belongs.

Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-04-24 15:39:20 -04:00
Pieter De Gendt
63a422c537 lib: cobs: Make CONFIG_NET_BUF optional
COBS streaming works without net_buf instances, optionally enable the
encode/decode helper functions, and remove the select.

Signed-off-by: Pieter De Gendt <pieter.degendt@basalte.be>
2026-04-23 07:09:08 -04:00
Parthiban Nallathambi
d17595dea7 lib: libc: thrd: fix undefined behavior in thrd_create return value
The C11 thrd_create() was casting the user's thrd_start_t (returns int)
to a pthread function pointer (returns void *) and passing it directly
to pthread_create(). This is undefined behavior per C99 6.3.2.3 and
breaks on architectures with split data/address return registers.

On TriCore, int returns in d2 (data register) while void * returns in
a2 (address register). The cast caused pthread internals to read the
return value from a2 (garbage) instead of d2, making thrd_join() always
return wrong results.

Use the already-defined struct thrd_trampoline_arg with a proper
trampoline function that calls the user function as int-returning and
converts the result via INT_TO_POINTER. A semaphore ensures the
parent's stack-allocated trampoline arg stays alive until the child
has copied it.

Fixes: tests/lib/c_lib/thrd failures on all TriCore targets.

Signed-off-by: Parthiban Nallathambi <parthiban@linumiz.com>
2026-04-21 18:41:52 -04:00
Shuai Ma
f3d287cace lib: cbprintf: fix C23 incompatible function pointer types
The cbprintf_cb typedef used an empty parameter list () which in C23
is equivalent to (void), making it incompatible with any callback
function that takes parameters.

Fix by giving cbprintf_cb a proper prototype (int c, void *ctx),
removing the now-redundant cbprintf_cb_local typedef, and adding
explicit (cbprintf_cb) casts at call sites where the callback has a
different signature (fputc, sprintf_out).

Signed-off-by: Shuai Ma <Shuai.MA@cn.bosch.com>
2026-04-17 10:40:05 +02:00
Anas Nashif
243012c33c kernel: move thread_entry from lib/os to kernel
Not really library code, this a core component that is part of the core
os/kernel.

Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-04-14 22:31:16 -04:00
Anas Nashif
c60e0e9436 kernel: move userspace sem into kernel/sys
This is a kernel permitive for use with userspace, so move it under
kernel.

Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-04-14 22:31:16 -04:00
Anas Nashif
b572cb23fc kernel: userspace: move mutex/user_work to userspace
Move userspace code out of lib/os into userspace folder under kernel.

Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-04-14 22:31:16 -04:00
Christoph Busold
bd2d8a1d52 lib: heap: Make randomized canaries a dedicated option
This makes the dependency on a random number source explicit for
this option.

Signed-off-by: Christoph Busold <cbusold@qti.qualcomm.com>
2026-04-14 22:14:04 -04:00
Christoph Busold
b7b0403a26 lib: heap: Make canaries random and reduce their size
Randomize the base canary value at heap creation in order to make
it unpredictable to attackers and reduce their size to 4 bytes,
which should still give enough entropy but reduce overhead
especially on 32-bit targets.

This adds a dependency for heap hardening levels with canaries to
a random number generator.

Signed-off-by: Christoph Busold <cbusold@qti.qualcomm.com>
2026-04-14 22:14:04 -04:00
Alex Rodriguez
151ab82e0e lib: utils: json: Add support for polymorphic fields
Allow multiple descriptors with  the same field name to support
polymorphic JSON fields such as id: string | integer.

The parser now tries all descriptors matching a field name and only
returns an error if all the attempts fail. This preserves existing
error behavior for non-polymorphic fields.

Signed-off-by: Alex Rodriguez <alejandro.rodriguezlimon@nxp.com>
2026-04-14 22:07:30 -04:00
Anas Nashif
b474cfc2b6 posix: move posix to subsys/portability
Posix is not a library per the definition of libraries in Zephyr. It
always has been a portability layer and shall reside with other
portability layers under subsys/portability.

Addresses #99250

Signed-off-by: Anas Nashif <anas.nashif@intel.com>
2026-04-14 22:03:46 -04:00
Benjamin Cabé
044ee12b69 Revert "libc: use picolibc module with openrisc [REVERT ME]"
This reverts commit 1113abfb66.

Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
2026-03-31 13:56:17 -05:00
Ivan Iushkov
b9c4d724b4 lib: net_buf: inline several simple functions
This commit aims to slightly improve performance of
Zephyr-based applications by inlining often-used functions.

net_buf is used by different subsystems and applications so
performance of this library affects performance of many other
modules and it is important to keep its implementation efficient
and robust.

The following functions were moved from buf_simple.c to net_buf.h:
- net_buf_simple_headroom() - it was already used by some of inlined
functions which made inlining less efficient
- net_buf_simple_tailroom() and net_buf_simple_max_len() that do
very basic size calculations

Signed-off-by: Ivan Iushkov <ivan.iushkov@nordicsemi.no>
2026-03-31 10:27:20 -05:00