The help of NET_BUF_WARN_ALLOC_INTERVAL says that 0 prints a warning
only once per allocation, but the time the allocation was blocked is
also printed when it gets a buffer. The help of NET_BUF_POOL_USAGE does
not mention the maximum number of buffers in use, which is what
net_buf_get_max_used() returns, and the help of NET_BUF_HARDENING
mentions only the operations that return NULL when they are rejected.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Johan Hedberg <johan.hedberg@silabs.com>
Provide the packet socket address header so that applications and
modules can include <netpacket/packet.h> as they do on other systems.
The Zephyr header pulls in the native packet socket definitions from
<zephyr/net/net_ip.h>, and the newlib and picolibc shims forward to it
since neither C library ships this header.
Signed-off-by: Chris Friedt <chris@fr4.co>
Since commit 9bb2878319 ("net_buf: make reference counts atomic"),
net_buf_unref() decrements ref_word before its double free check. At a
zero reference count the decrement borrows from the other bytes of
ref_word: from flags, and from pool_id if flags is zero, so a buffer
that has already been freed can end up with the wrong pool id. With
assertions disabled, this undoes commit 9d0d3ef076 ("net_buf: buf:
return on double free").
Decrement with a compare-and-swap that leaves a zero count alone, also
when a double free races with the last unref. On Cortex-M33 and
Cortex-M4F this costs 2 to 16 cycles per unref.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Johan Hedberg <johan.hedberg@silabs.com>
Give ump_stream_responder.h C linkage so C++ code can link against it.
Tested by building a C++ app using it on native_sim.
Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Up until now offloaded sockets bind their local port inside the
offload engine, outside the net_context list, so
net_context_port_in_use() cannot see them.
This commit adds recording of each offloaded socket's local
binding in the socket layer and adds net_socket_port_in_use()
which consults both the socket and the context layer for
in use ports.
Signed-off-by: Carlo Kirchmeier <carlo.kirchmeier.ext@siemens.com>
When the malloc arena uses the RAM left after the image, a
nearly full image can leave less space than a heap needs. With
assertions disabled, the heap was still set up on that space
and allocations corrupted the memory past it.
Treat such an arena as empty, including when its size wraps or
its mapping fails, so allocations fail with ENOMEM, and log a
warning. Since the malloc partition is then empty, ztest no
longer adds it to the default memory domain.
Assisted-by: Claude:opus-5
Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
Statically defined sys_mem_blocks allocators and the socket object table
are permanent storage, so they are enumerated in place as the permanent
range of their object type instead of each taking a registry entry. The
section of allocator pointers is registered as an indirect range. Socket
objects that were never initialized do not carry the type tag and are
not reported.
Assisted-by: Claude:claude-fable-5-1
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
A kernel object embedded in a k_malloc()ed or slab-allocated structure
ends its life with the block that holds it, and nothing calls the object
core API when that block is released. Its registry entry then stays
until the storage is reused by an object of another type.
Add a hidden SYS_HEAP_RELEASE_HOOK that the heap calls with the released
memory while it is still valid, from sys_heap_free() and from the tail an
in-place shrink gives up, and have k_mem_slab_free() report the released
block the same way. Object cores provide the hook under
OBJ_CORE_EVICT_ON_FREE, default on, and drop every entry located in the
released range. User mode frees are ignored: the registry is kernel
data and user mode never holds registered objects.
Assisted-by: Claude:claude-fable-5-1
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
Replace scripts/kconfig/hardened.csv with a distributed YAML database.
The CSV format could not carry any explanation for its recommendations,
had no validation (a malformed line was silently dropped), no notion of
profiles, no ownership story, and no way to extend it out of tree.
The database now lives where the code lives: the central
scripts/kconfig/hardening.yaml defines the hardening profiles (plus
rules for top-level Kconfig symbols), and per-subsystem hardening.yaml
fragments next to the relevant Kconfig files carry the rules, so each
rule is reviewed by the maintainers of the code it hardens. Every rule
has a required rationale and optional references, supports exact-value
and integer min/max recommendations (STACK_POINTER_RANDOM is now
'>=100' instead of '==100'), and belongs to a profile: 'base' (memory
protection and inherently insecure features) or 'strict' (extends base
with debug/observability feature removal). The default profile is
'strict', matching the rule set the CSV checked.
hardenconfig is restructured around a serializable HardeningReport
model so results can be consumed programmatically, and gains:
- a Rationale column in the report
- profile selection:
west build -t hardenconfig -- -DHARDENCONFIG_PROFILE=base
- HARDENCONFIG_SHOW_ALL to also list PASS/NA results
- HARDENCONFIG_STRICT to exit non-zero on failures, for CI use
- HARDENCONFIG_JSON to write machine-readable results, including which
database file each rule came from
- HARDENCONFIG_EXTRA_SOURCES to layer out-of-tree database files that
may add profiles/rules and override in-tree ones
The EXPERIMENTAL/DEPRECATED/NOT_SECURE marker symbol detection is
preserved unchanged.
Three CSV entries are intentionally not carried over because they were
redundant: BT_CONN_DISABLE_SECURITY and BT_OOB_DATA_FIXED can only be
enabled together with BT_TESTING, and TIMER_RANDOM_GENERATOR together
with TEST_RANDOM_GENERATOR, all of which the database already
recommends disabling for the same profiles.
Behavioral fix: the CSV's DEBUG_COREDUMP line used '=' instead of ','
and was silently ignored, so CONFIG_DEBUG_COREDUMP was never actually
checked; it now is.
Also add tabulate to requirements-base.txt: hardenconfig has always
imported it, but it was only pulled in via other requirements files.
Assisted-by: Claude:fable-5
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Add sys_heap_get_largest_free_block() to report the size of the
largest contiguous free block currently available in a sys_heap.
The value is computed on demand from the current heap state by
scanning the highest-indexed non-empty bucket. This avoids adding
overhead to the allocation and free paths while preserving the
public API behavior.
Signed-off-by: Deepak Mokili <dmokili@qti.qualcomm.com>
The shared multi-heap is a single global pool, but none of its
operations were locked and sys_heap is not internally
synchronized. Callers in different threads, such as the
Espressif Wi-Fi driver with its heap in PSRAM, corrupted the
heap on concurrent alloc and free.
Protect the allocation functions and the publication of a new
region with a spinlock, as mem_attr_heap and k_heap already do.
The region itself is initialized outside the lock, like
k_heap_init() does, and the interface documentation now states
which functions are safe to call from any thread and from ISRs.
shared_multi_heap_alloc() now reuses the aligned variant with no
alignment requirement, which is what sys_multi_heap_alloc()
does.
Assisted-by: Claude:opus-5
Signed-off-by: Sylvio Alves <sylvio.alves@espressif.com>
Introduce ZASSERT, a self-contained assertion facility configured per
source file through a named module rather than the single global
CONFIG_ASSERT switch.
A file selects its module with ZASSERT_MODULE(); the level is resolved
from CONFIG_ASSERT_MODULE_<MODULE>_LEVEL and may be overridden per file.
Modules are defined with the Kconfig.template.assert template, which takes
module/module-str inputs following the logging template convention.
The four levels are:
- Off (compiled out)
- Terse (check only)
- On (check + location only)
- Verbose (Check, location, condition and message)
Since the level is known at compile time, disabled assertions are folded
away by the compiler, and below Verbose the optional message and its
arguments are as well.
zassert provides a set of __weak overridable hooks:
- zassert_fail() - called when an assertion fails
- zassert_vprint() - called to print the assertion failure message
- zassert_post_action() - the terminal action after an assertion failure
CONFIG_ASSERT remains the master switch. The assert Kconfig moves from
subsys/debug to lib/os/zassert, the legacy CONFIG_ASSERT_* symbols are kept
but deprecated (mapped onto the DEFAULT module), and lib/os/assert.c is
removed. The __ASSERT() family is preserved as a thin compatibility shim
over the DEFAULT module, so existing call sites keep working unchanged.
Signed-off-by: Måns Ansgariusson <mansgariusson@gmail.com>
As part of the transition from C99 to C17 as the minimum supported C
standard version, remove the workarounds in the formatted output
subsystem to maintain compatibility with toolchains that do not support
the _Generic keyword.
Signed-off-by: Carles Cufi <carles.cufi@nordicsemi.no>
Fixes various issues with Kconfigs, including:
- Redundent `default n` on bools
- Not select deprecated on supposed deprecated symbols
- Using the wrong indentation
- Not having [DEPRECATED] in the prompt, or not having it at the
end
Signed-off-by: Jamie McCrae <jamie.mccrae@nordicsemi.no>
Add a small OS helper for validating and copying a boot firmware device
tree blob into caller-owned storage.
The helper checks the FDT magic and total-size fields, verifies that
the caller-provided destination is large enough, copies the blob, and
returns 0 or a negative errno value. It does not own the destination
buffer or make policy decisions about which firmware argument contains
an FDT.
Add optional Xen support for preserving the boot device tree blob from
the first firmware argument when running on xenvm. The Xen driver code
owns the storage and policy, then exposes the copied data through
xen_fdt_get().
Signed-off-by: Vladyslav Goncharuk <vladyslav_goncharuk@epam.com>
Assisted-by: Codex:gpt-5
Add TriCore architecture port supporting TC1.6P and TC1.8P core
variants used in Infineon AURIX TC3x and TC4x SoC families.
Includes context switching using TriCore upper/lower context save
areas (CSA), interrupt management, trap and exception handling,
syscall interface, reset vector and linker script.
Supports cooperative and preemptive threading, nested interrupt
handling with priority-based preemption.
Signed-off-by: Christoph Seitz <christoph.seitz@infineon.com>
Signed-off-by: Parthiban Nallathambi <parthiban@linumiz.com>
The new implementation provides a full SPSC ring buffer API, reducing the
size of the ring_buffer struct to 12 bytes(on a 32-bit arch), and increases
the throughput of the ring buffers hot path by ~30% (measured on nRF5340).
The default variant drops the claim/finish and item APIs functionality to
reduce the struct size. During the deprecation period, the old APIs are
still reachable through the CONFIG_RING_BUFFER Kconfig option.
Signed-off-by: Måns Ansgariusson <mansgariusson@gmail.com>
I can't find any trace of support for these outside of the Kconfig
file; they "can't" have ever worked.
Signed-off-by: Keith Packard <keithp@keithp.com>
sys_heap_aligned_alloc() called heap_sanitizer_on_alloc() twice for
the same allocation, unpoisoning the region redundantly. Remove the
duplicate call, which was unintended change.
Signed-off-by: Deepak Mokili <dmokili@qti.qualcomm.com>
Drop unrelated formatting changes in Kconfig and heap.h, fix tags
list syntax and drop the redundant filter expression already
guaranteed true by prj.conf in tests.yaml.
Signed-off-by: Deepak Mokili <dmokili@qti.qualcomm.com>
heap_constants.c includes heap.h
directly without including zephyr/sys/sys_heap.h first, so the
z_heap_stats_on_*() prototypes taking struct sys_heap * left the
type undeclared in that translation unit, triggering error
Signed-off-by: Deepak Mokili <dmokili@qti.qualcomm.com>
Key the stats pool by struct sys_heap * identity in a parallel
registration table (z_heap_stats_heaps) instead of reading h->stats
from the caller's buffer. h->stats is now always assigned explicitly
by on_init and never read before being set.
Signed-off-by: Deepak Mokili <dmokili@qti.qualcomm.com>
- Decouple chunk trailer from SYS_HEAP_CANARIES; gate on
CANARIES || THREAD_STATS || CALLER_POINTER independently
- Move all stats logic to heap_stats.c; call via thin hooks
using IF_ENABLED() following the sanitizer hook pattern
- Remove atomics; model is caller-serialised matching sys_heap
contract; document in Kconfig
- Reuse pool slot on re-init instead of consuming a new one
- Serialise threads in overflow test; no concurrent raw sys_heap
Signed-off-by: Deepak Mokili <dmokili@qti.qualcomm.com>
Add CONFIG_SYS_HEAP_STATS_LOGGING to enable a heap statistics
framework. CONFIG_SYS_HEAP_THREAD_STATS tracks outstanding allocation
bytes per thread per heap, with ISR/boot/overflow aggregate counters
and sys_heap_stats_log() to print them. CONFIG_SYS_HEAP_CALLER_POINTER
stores the allocation call-site address in the chunk trailer, readable
via sys_heap_get_caller(). Both features store metadata in the
per-chunk trailer and auto-select SYS_HEAP_CANARIES.
Includes a ztest suite under tests/lib/heap_stats_log.
Signed-off-by: Deepak Mokili <dmokili@qti.qualcomm.com>
MISRA C:2012 Rule 8.2 requires every parameter in a function type to be
named, including the parameters of function pointer parameters.
The stdout hook install helper is defined once per C library and only the
minimal and picolibc versions named the hook's character argument. The
minimal stdlib.h and the newlib string.h overrides also declared their
parameters with bare types.
Name them after the arguments the documentation or the
definitions already use. No functional change.
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
net_buf_append_bytes() links every newly allocated fragment with
net_buf_frag_add(), which walks the whole chain from the head to find
the tail. That tail is already known: it is the fragment the loop has
just filled. A single append spanning n fragments therefore costs
O(n^2) fragment traversals, and a caller that appends one segment at a
time onto a growing chain walks that chain twice per call instead of
once.
The second shape is the common one in tree. The Bluetooth host appends
one received segment per call when reassembling LE L2CAP SDUs in
l2cap_chan_le_recv_seg() and BR/EDR segments in bt_l2cap_br_recv_seg(),
and the hl7800 and wncm14a2a modem receive paths append one UART read
per call. The GATT call sites build a single outgoing ATT PDU and pass
no allocator, so they normally stay within one buffer.
Keep the tail in a local variable and link the new fragment behind it
with net_buf_frag_insert(). For a non-NULL head net_buf_frag_add() does
exactly that on the tail, and the function already requires a non-NULL
buffer, so the fragment reference is still consumed and the resulting
chain order is unchanged. The tail is re-derived from the returned
fragment so an allocator handing back a chain keeps its old behaviour.
The allocation-failure path still returns before any linking.
Measured on native_sim/native/64 with an instrumented
net_buf_frag_last(). Appending 4096 bytes over 32 128-byte fragments in
one call drops from 465 to 0 traversal steps. Building the same
32-fragment chain one fragment per call, which is the reassembly shape
above, drops from 930 to 465; the remainder is the entry walk that the
head-pointer argument requires and that this change does not address.
Add a regression test that builds a ten-fragment chain over two calls
and checks the fragment count, that every fragment is filled, the
payload order across the join, and that a failed allocation leaves the
chain untouched.
Signed-off-by: Magnus Strømme <magnus.henrik@hotmail.com>
Assisted-by: Claude:claude-opus-5
The %s conversion computed the string length with strlen() and clamped
it to the precision afterwards. A precision is meant to let callers pass
a buffer that is not NUL-terminated, but strlen() still scans for the
terminator and reads past the end of such a buffer.
Bound the length scan by the precision with strnlen() when a precision
is given, as cbprintf_complete.c already does, and keep strlen() when
there is none. Define _POSIX_C_SOURCE for the strnlen() declaration,
matching cbprintf_complete.c.
The out-of-bounds read was reproduced and the fix verified with
AddressSanitizer on the host, and with twister on qemu_cortex_m3
(tests/lib/sprintf and tests/lib/cbprintf_package, including the
CONFIG_CBPRINTF_NANO and MINIMAL_LIBC variants), all passing.
Fixes: #117791
Signed-off-by: Rithwik Reddy Eedula <rithwikreddy.eedula@sjsu.edu>
MISRA C:2012 Rule 8.2 requires every parameter in a function type to be
named, including the parameters of function pointer parameters.
The C++ ABI __cxa_atexit() stub, its local prototype in the ARM
__aeabi_atexit() wrapper and that wrapper itself left the destructor's
parameter unnamed.
Name them after the arguments the documentation or the
definitions already use. No functional change.
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
Remove remaining uses of the internal __ASSERT_ON macro. Let __ASSERT()
handle disabled assertions, mark assert-only values as unused where needed,
and use CONFIG_ASSERT for assertion-only state.
Signed-off-by: Måns Ansgariusson <mansgariusson@gmail.com>
sys_hash32_murmur3() is declared in <zephyr/sys/hash_function.h> as
taking a `const void *`, but is defined taking a `const char *`. The
mismatch goes unnoticed because the implementation does not include the
header declaring the function, so the two declarations are never seen in
the same translation unit.
Include the header and match the declared prototype.
Signed-off-by: Benjamin Cabé <benjamin@zephyrproject.org>
Assisted-by: Claude:opus-5
k_sleep() and k_usleep() resolve to an out of line implementation living in
another translation unit, a system call under CONFIG_USERSPACE and a plain
call otherwise. Either way the compiler sees neither whether the requested
duration is a constant nor whether the caller cares about the returned
value, so it always emits the tick to millisecond and microsecond
conversions. Those conversions are the only thing that drags the 64 bit
division helper into many small builds: CONFIG_SYS_CLOCK_TICKS_PER_SEC
defaults to 10000 on tickless platforms, which lands in the integer
division path and divides a 64 bit value by ten, something GCC will not
strength reduce on a 32 bit target.
Promote the former z_tick_sleep() helper to a k_sleep_ticks() system call
that reports the remaining time in ticks, and rebuild k_sleep() and
k_usleep() as inlines on top of it. The conversions now live at the call
site where the compiler can fold or discard them. Nearly every caller
discards them: of the 4036 sleep call sites in the tree, exactly six use
the returned value, and only three of those are outside of tests.
What this removes is best seen in the two out of line entry points that
disappear, which on a nucleo_f030r8 (Cortex-M0, 10000 ticks/s) were the
only two callers of the 64 bit division helper in the whole image:
08002594 <z_impl_k_sleep>:
bl 8001... <z_tick_sleep>
...
movs r0, #9 /* the ceil() bias, 10 - 1 */
adds r0, r0, r2
adcs r1, r3
movs r2, #10 /* ticks / 10 -> milliseconds */
bl 8000180 <__aeabi_uldivmod>
080025c0 <z_impl_k_usleep>:
movs r0, #99 /* the ceil() bias, 100 - 1 */
...
movs r2, #100 /* microseconds / 100 -> ticks */
bl 8000180 <__aeabi_uldivmod>
bl 8001... <z_tick_sleep>
Both are gone, and so are __aeabi_uldivmod and __udivmoddi4, which are no
longer referenced anywhere. A k_usleep(250) call site now passes the
literal 3 ticks the compiler worked out on its own, where it used to pass
250 microseconds to a helper that divided by 100 at runtime. For a loop
calling k_msleep(100), k_sleep(K_SECONDS(1)) and k_usleep(250) without
using the results, FLASH drops from 11028 to 10600 bytes.
No trace point is emitted here. The existing sleep hooks take a duration
in milliseconds or microseconds, which no longer describes what this
function is handed, and tracing cannot live in the inlines either: every
tracing backend header includes kernel.h, so a translation unit reaching a
backend header first would expand SYS_PORT_TRACING_* before those macros
exist. The following commit gives k_sleep_ticks() a hook of its own.
The duration goes through Z_TIMEOUT_US() rather than an open coded
conversion. That clamps a negative argument to zero, which k_usleep()
never did: it used to truncate the 64 bit conversion into an int32_t
first, which hid the worst of it, and passing it through whole would turn a
negative duration into a sleep of roughly 1.8e17 ticks rather than a bogus
absolute deadline. The macro also carries the cast to k_ticks_t that C++
needs, since Z_TIMEOUT_TICKS_INIT() is a braced initializer there and an
unsigned to signed conversion inside one is a narrowing error.
This also removes a potential link error. k_usleep() had no
implementation at all with CONFIG_MULTITHREADING=n, since nothread.c only
ever provided z_impl_k_sleep(), so any caller failed to link. Nothing in
the tree happens to call it in that configuration, which is presumably why
it went unnoticed; a single z_impl_k_sleep_ticks() now serves both.
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
vprintk_unlocked() formats straight to the character output hook, which
lives in kernel memory and cannot be reached from a user thread. Since
assert_print() uses it, an assert taken in user mode faults instead of
printing. tests/ztest/error_hook times out on qemu_arc/qemu_arc_em and
dies on qemu_x86.
Use the same buffered path vprintk() already uses for user threads,
handing the result to the kernel through k_str_out(), and route
printk_unlocked() through vprintk_unlocked() so both variants agree.
The lock free property is kept: k_str_out() skips the lock once
printk_panic() has been called.
Introduced by commit 0ecb6caf0f ("lib: os: assert: print the
assertion message unlocked").
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
printk_unlocked() serves callers that know they cannot lock, not the ones
that find out too late. A fault taken inside printk() leaves the spinlock
held by a context about to die, so every later printk() blocks and the
crash report is lost along with everything after it. CONFIG_SPIN_VALIDATE
makes it louder rather than better: validation fails, the assertion is
reported through printk, and the system spins there repeating itself.
That happens on a uniprocessor too, where the lock is uncontended but
still recorded as held.
Converting call sites cannot fix it, because code reached after the
failure does not know it is in a crash. So make printk() itself aware:
printk_panic() switches it to the unlocked path and the reporting paths
call it before emitting anything.
The switch is one way. Clearing it would also require releasing the
orphaned lock, and telling "orphaned" from "held by a CPU that is still
running" needs the owner, which only CONFIG_SPIN_VALIDATE records. So a
system that has reported a fatal error keeps unserialized output for the
rest of its life, which costs interleaving and no content.
Linux does the same: bust_spinlocks(), called from its oops and panic
paths, raises oops_in_progress so printk skips console locking. This
mechanism is narrower, printk simply stops locking, but the reasoning is
identical.
Because it cannot be undone, it must only be thrown once the fault is
terminal, which rules out the architecture entry points: several return.
z_arm64_fatal_error() resumes once demand paging has serviced the fault,
so switching there would cost a paging system its printk locking on the
first page fault. EXCEPTION_DUMP() runs only after the recoverable cases
are ruled out and also covers arch-specific dumps such as the Cortex-M
one behind PR_FAULT_INFO, and z_fatal_error() covers reports with no
dump, like k_panic() from a failed assertion. OpenRISC switches at entry
because it reports with LOG_ERR(), which is safe there since its handler
never returns.
k_str_out() shares the lock and honours the switch, so crashes reported
through printf() or puts() are covered too.
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
An assertion can fire from inside printk()'s own locked region, where
reporting through vprintk() takes a spinlock this CPU already holds. The
lock is not recursive, so the message never appears and the CPU hangs
where it was supposed to say what went wrong. CONFIG_SPIN_VALIDATE makes
that worse: the validation failure is itself reported through
assert_print(), so it recurses until the stack is gone. The lock may
equally be held by another CPU that cannot release it, which is the
situation an assertion is likely reporting.
Use vprintk_unlocked() so the message goes out regardless.
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
printk() is unusable where its spinlock cannot be taken, and Zephyr has
no answer for any of the three cases. A fatal error or failed assertion
may happen with the lock held, by the failing context itself or by a CPU
that will never release it, so reporting hangs instead of printing. An
assertion firing mid-message deadlocks on the same non-recursive lock.
And on some architectures the atomics a spinlock is built from do not
work until the MMU is on, so an early printk() faults.
Add printk_unlocked() and vprintk_unlocked(). They never take the lock,
and bypass the logging subsystem and the user mode buffer because those
have locks of their own, going straight to the platform's character
output hook. Output may interleave with a concurrent printk(), which
beats deadlocking or losing it.
Formatting is factored into vprintk_core() and shared with printk(), so
both produce identical text and only the locking differs. Nothing changes
for existing callers.
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
Add prompt to CBPRINTF_CONVERT_CHECK_PTR and extend the description.
Runtime string validation takes ~500 bytes of code (on riscv32) and
additional time when creating a log message so there are cases where
user would like to disable it.
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
Refactor function to gain code space. Function takes significant
amount of code due to suboptimal implemention. Refactor to
reduce code (1200->800 on riscv32).
Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
User code should not re-define prototypes defined in C library headers,
but, for prototypes of extensions (like strnlen()) should reuqest them
by setting the appropriate feature test macro.
So, instead of defining the strnlen() prototype in the user code, let's
set the appropriate SOURCE macro and get the prototype from its header
(string.h).
Signed-off-by: Alberto Escolar Piedras <alberto.escolar.piedras@nordicsemi.no>
The commented out CHECK() definition is an instruction to whoever
debugs the rbtree code, not code that is meant to be restored as is,
and MISRA C:2012 Directive 4.4 does not allow commented out code.
Fold it into the surrounding comment as a sentence. The empty CHECK()
definition that is actually compiled is unchanged.
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
k_sleep() and k_usleep() resolve to an out of line implementation living in
another translation unit, a system call under CONFIG_USERSPACE and a plain
call otherwise. Either way the compiler sees neither whether the requested
duration is a constant nor whether the caller cares about the returned
value, so it always emits the tick to millisecond and microsecond
conversions. Those conversions are the only thing that drags the 64 bit
division helper into many small builds: CONFIG_SYS_CLOCK_TICKS_PER_SEC
defaults to 10000 on tickless platforms, which lands in the integer
division path and divides a 64 bit value by ten, something GCC will not
strength reduce on a 32 bit target.
Promote the former z_tick_sleep() helper to a k_sleep_ticks() system call
that reports the remaining time in ticks, and rebuild k_sleep() and
k_usleep() as inlines on top of it. The conversions now live at the call
site where the compiler can fold or discard them. Nearly every caller
discards them: of the 4036 sleep call sites in the tree, exactly six use
the returned value, and only three of those are outside of tests.
What this removes is best seen in the two out of line entry points that
disappear, which on a nucleo_f030r8 (Cortex-M0, 10000 ticks/s) were the
only two callers of the 64 bit division helper in the whole image:
08002594 <z_impl_k_sleep>:
bl 8001... <z_tick_sleep>
...
movs r0, #9 /* the ceil() bias, 10 - 1 */
adds r0, r0, r2
adcs r1, r3
movs r2, #10 /* ticks / 10 -> milliseconds */
bl 8000180 <__aeabi_uldivmod>
080025c0 <z_impl_k_usleep>:
movs r0, #99 /* the ceil() bias, 100 - 1 */
...
movs r2, #100 /* microseconds / 100 -> ticks */
bl 8000180 <__aeabi_uldivmod>
bl 8001... <z_tick_sleep>
Both are gone, and so are __aeabi_uldivmod and __udivmoddi4, which are no
longer referenced anywhere. A k_usleep(250) call site now passes the
literal 3 ticks the compiler worked out on its own, where it used to pass
250 microseconds to a helper that divided by 100 at runtime. For a loop
calling k_msleep(100), k_sleep(K_SECONDS(1)) and k_usleep(250) without
using the results, FLASH drops from 11028 to 10600 bytes.
Tracing stays in the out of line implementation. It cannot move into the
inlines because every tracing backend header includes kernel.h, so a
translation unit that reaches a backend header first would expand
SYS_PORT_TRACING_* before those macros exist. A consequence is that the
sleep_exit hook now reports ticks rather than milliseconds and the usleep
hook is no longer emitted; both are covered in a following commit.
The microsecond duration is clamped to zero the way Z_TIMEOUT_US() already
does. k_usleep() never did that, but it used to truncate the 64 bit
conversion into an int32_t before handing it over, which hid the worst of
it.
Passing the conversion through whole would turn a negative duration into a
sleep of roughly 1.8e17 ticks rather than a bogus absolute deadline.
This also removes a potential link error. k_usleep() had no
implementation at all with CONFIG_MULTITHREADING=n, since nothread.c only
ever provided z_impl_k_sleep(), so any caller failed to link. Nothing in
the tree happens to call it in that configuration, which is presumably why
it went unnoticed; a single z_impl_k_sleep_ticks() now serves both.
Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
MISRA C:2012 Rule 8.2 requires every parameter in a function type to
be named, including the parameters of function pointer parameters.
The object core walk callbacks, fnmatch() and the stdout hook were
declared with unnamed parameters.
Name them after the arguments the documentation already describes.
Declarations only, no functional change.
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
'time' is reserved by the C standard for any use, so the locals in
timeutil_timegm64() and timeutil_timegm() violate MISRA C:2012
Rule 21.2 and shadow the <time.h> function.
Rename both to 'secs', which says what they hold. Pure rename.
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
'round' is a standard library identifier reserved for any use, so
naming a local after it violates MISRA C:2012 Rule 21.2.
Rename it to 'rounding', which also reads better next to the comment
about rounding to the last printed digit. Pure rename.
Signed-off-by: Anas Nashif <anas.nashif@intel.com>
The previous commit made the raw net_buf_simple add/push/pull/remove_mem
primitives fail-closed (return NULL) under CONFIG_NET_BUF_HARDENING, but
the typed scalar accessors that build on them still dereferenced the
returned pointer unconditionally: net_buf_simple_add_*/push_* store via
sys_put_*() into the add()/push() result, net_buf_simple_remove_* read
through the remove_mem() result, and net_buf_simple_pull_* read buf->data
before calling pull() (so pull()'s own guard came too late). On a
corrupted or overflowing buffer these turned the fail-closed NULL into a
NULL write/read (or, for pull_*, an out-of-bounds read), leaving a hole in
the hardening guarantee.
Route every typed accessor through the guard: add_*/push_* skip the store,
remove_*/pull_* return 0, and the pull_* helpers now read via the already
checked pull_mem() instead of touching buf->data first. Two small helper
macros keep the change mechanical and expand to the bare pointer when
hardening is disabled, so the non-hardened fast path is unchanged.
The fragmented net_buf_*_u8/le*/be* helpers only wrap the net_buf_simple_*
versions, so they inherit the protection with no further changes.
Add unit tests covering the add/pull/remove scalar accessors under a
corrupted length.
Assisted-by: Claude:opus-4.8
Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
Add CONFIG_NET_BUF_HARDENING, an opt-in (default off) set of always-on
integrity checks on the net_buf_simple length/pointer fields, evaluated
before a buffer is mutated. If a buffer's metadata has been corrupted so
that it no longer fits within its own storage -- for example len wrapped
to a large value, or data moved outside __buf..__buf+size -- the mutating
primitive is rejected fail-closed and returns NULL instead of reading or
writing out of bounds.
This turns a would-be out-of-bounds access (in particular the
tailroom-underflow that lets net_buf_add() overrun the buffer once len is
corrupt) into a controlled failure. net_buf_simple_is_valid() /
net_buf_is_valid() expose the check, and net_buf_simple_add()/add_mem()/
remove_mem()/push()/push_mem()/pull()/pull_mem() consult it. When the
option is disabled the fast path keeps the previous assert-only behaviour.
Add unit tests covering the validator (in-bounds, len boundary, wrapped
len, out-of-range data pointer) plus a hardening scenario that exercises
the fail-closed add/add_mem/pull paths.
Assisted-by: Claude:opus-4.8
Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
Add json_obj_separate_parse_init() and json_obj_next_key_value() to
walk a JSON object's top-level members without a compile-time
descriptor, returning each value as a raw span (scalars as their text,
objects and arrays as the whole balanced {...} / [...]). This serves
callers that dispatch each member to a handler chosen at run time,
where no single descriptor for the whole object exists. Built over the
existing object lexer; existing APIs unchanged.
Signed-off-by: Paulo Santos <pauloxrms@gmail.com>