Skip to content

drivers: interrupt_controller: riscv: add support for APLIC direct mode - #1

Closed
onaffaa wants to merge 1 commit into
mainfrom
onaffaa/aplic-direct-mode
Closed

onaffaa wants to merge 1 commit into
mainfrom
onaffaa/aplic-direct-mode

Conversation

@onaffaa

@onaffaa onaffaa commented May 25, 2026

Copy link
Copy Markdown
Owner

Update APLIC driver to support APLIC direct mode by configuring registers for direct delivery mode, supporting per-source priority assignment, and specifying an irq handler if APLIC direct mode is enabled.

Note: direct mode is only enabled if APLIC is configured without the "msi-parent" attribute.

Update APLIC driver to support APLIC direct mode by configuring
registers for direct delivery mode, supporting per-source priority
assignment, and specifying an irq handler if APLIC direct mode is
enabled.

Note: direct mode is only enabled if APLIC is configured without the
"msi-parent" attribute.

Signed-off-by: Omar Naffaa <onaffaa@qti.qualcomm.com>
@onaffaa onaffaa closed this May 25, 2026
onaffaa pushed a commit that referenced this pull request Jul 8, 2026
struct bt_uuid was used for storage instead of struct bt_uuid_any
resulting in overflow when converting BTP UUID to bt_uuid.

==3608402==ERROR: AddressSanitizer: stack-buffer-overflow on address
    0xe02f5da2 at pc 0x0805a750 bp 0xe14e2048 sp 0xe14e2038
WRITE of size 2 at 0xe02f5da2 thread T7
    #0 0x805a74f in btp2bt_uuid zephyr/tests/bluetooth/tester/src/btp_gatt.c:212
    #1 0x805d31c in get_handle_from_uuid zephyr/tests/bluetooth/tester/src/btp_gatt.c:2149
    #2 0x804f12c in cmd_handler zephyr/tests/bluetooth/tester/src/btp.c:122
    #3 0x807c582 in z_thread_entry zephyr/kernel/sys/thread_entry.c:60
    zephyrproject-rtos#4 0x807cdd2 in posix_arch_thread_entry zephyr/arch/posix/core/thread.c:124
    zephyrproject-rtos#5 0x80ff2bd in nct_thread_starter zephyr/scripts/native_simulator//common/src/nct.c:291
    zephyrproject-rtos#6 0xeb1949a3 in asan_thread_start ../../../../../src/libsanitizer/asan/asan_interceptors.cpp:234
    zephyrproject-rtos#7 0xeaea5136  (/lib32/libc.so.6+0x8b136) (BuildId: 798ae816ef14b98dc77560340190445fb200634a)
    zephyrproject-rtos#8 0xeaf39de7  (/lib32/libc.so.6+0x11fde7) (BuildId: 798ae816ef14b98dc77560340190445fb200634a)

Signed-off-by: Szymon Janc <szymon.janc@codecoup.pl>
onaffaa pushed a commit that referenced this pull request Aug 19, 2026
z_arm64_sync_exc() demuxes SVC exceptions by the low 8 bits of the
SVC immediate (svc #1: IRQ offload, svc #2: runtime except, svc #3:
system call) without checking which exception level the SVC was
taken from. On ARM64, SVC from EL0 and EL1 both report ESR EC 0x15,
so hardware does not distinguish them.

With CONFIG_USERSPACE=y and CONFIG_IRQ_OFFLOAD=y, any user thread can
execute a raw svc #1 with x0/x1 pointing at an arbitrary kernel
function and argument; the handler then runs 'blr x1' at EL1, i.e.
privilege escalation / arbitrary code execution in kernel mode. The
RISC-V port avoids this class of bug by distinguishing ECALLU/ECALLM
via mcause.

Note that CONFIG_IRQ_OFFLOAD depends on TEST (arch/Kconfig), so this
is not reachable in a production build; only test builds that enable
irq_offload() are exposed. This distinction matters for backport
decisions.

Read the saved SPSR from the ESF and route any SVC taken from EL0 to
a user-only path that accepts just the system call and runtime-except
immediates. The runtime-except entry must stay reachable from EL0
because user threads raise stack-check failures and oopses through
it; z_arm64_do_kernel_oops() sanitizes the user-supplied reason, so
this is not a privilege boundary. All other EL0 SVCs raise a fatal
CPU exception. Kernel-mode SVCs keep their previous behavior, except
that svc #3 from EL1 is no longer dispatched to the syscall handler,
which kernel code never uses.

Fixes zephyrproject-rtos#116254

Signed-off-by: Hongquan Li <hongquan.li@processmission.com>
onaffaa pushed a commit that referenced this pull request Aug 19, 2026
Add a regression test for the EL0 SVC gating fix: a user thread
executes a raw svc #1 (the IRQ offload entry) with x0 pointing at a
kernel-only probe function. With the fix, the SVC raises a fatal CPU
exception and the thread is aborted; without it, the offload handler
branches to the attacker-controlled address at EL1 and the test fails
immediately on the probe check.

Covers tests/arch/arm64/svc_el0_gate on qemu_cortex_a53 (UP and SMP)
with CONFIG_USERSPACE=y and CONFIG_IRQ_OFFLOAD=y.

Signed-off-by: Hongquan Li <hongquan.li@processmission.com>
onaffaa pushed a commit that referenced this pull request Sep 8, 2026
Add coverage for observing a resource whose notification body is
transferred blockwise (RFC 7959), complementing the coap_client fix
that keeps the registration token matchable for the whole observation.

test_observe_blockwise:
- Deliver two server-pushed notifications, each as two Block2 blocks.
- Verify all callbacks fire and Block2 continuation GETs omit Observe
  (RFC 7959 Section 3.4).

test_observe_blockwise_async_notification:
- Push notification #2 (block 0, registration token T0) while block 1 of
  notification #1 is still outstanding.
- Verify the client does not RST the pushed notification and delivers
  the expected Observe sequence numbers.

test_observe_deregister_blockwise:
- After block 0 and the block-1 continuation GET, call
  coap_client_deregister_observe() while request_token holds the
  continuation token.
- Verify the unobserve GET uses the registration token.

test_observe_deregister_blockwise_in_callback:
- Complete one blockwise notification, then deregister from application
  logic triggered by the final-block callback (deferred on the system
  workqueue).
- Verify the unobserve GET still uses the registration token.

Signed-off-by: Juha Ylinen <juha.ylinen@nordicsemi.no>
onaffaa pushed a commit that referenced this pull request Sep 10, 2026
The HTTP parser hands its data callbacks a pointer and a length, and the
field it points at is not NUL terminated. print_header_field() passed
that pointer to a %s conversion:

	snprintk(output, len + 1, "%s", str);

The size argument bounds the destination, not how far the source is
walked. Both formatter implementations measure the whole string first,
cbprintf_complete.c with strlen() when no precision is given and
cbprintf_nano.c with strlen() unconditionally, so the read runs past the
end of the field and out of the receive buffer that holds it.

The in-tree tests/net/lib/http_client suite reproduces it on an ordinary
GET, no crafted response needed, once it is built with CONFIG_ASAN=y and
CONFIG_NET_HTTP_LOG_LEVEL_DBG=y:

	AddressSanitizer: global-buffer-overflow
	READ of size 48 at 0x08117480
	    #1 in z_cbvprintf_impl lib/os/cbprintf_complete.c:1627
	    zephyrproject-rtos#5 in print_header_field subsys/net/lib/http/http_client.c:172
	0x08117480 is located 0 bytes after global variable 'recv_buf'
	  (0x8117440) of size 64

Copy the bytes the parser actually offered and terminate them, rather
than reaching for a precision. A precision only bounds the read in
cbprintf_complete.c; with CONFIG_CBPRINTF_NANO=y the source is still
measured in full before the precision is applied.

Assisted-by: Claude:claude-opus-5
Signed-off-by: Jukka Rissanen <jukka.rissanen@nordicsemi.no>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant