Commit graph

7573 commits

Author SHA1 Message Date
Xiang Xiao
db9531fe96 drivers/serial: add job-control TTY ioctls and libc wrappers
NuttX has no real session/process-group abstraction, so the TTY layer
collapses the foreground process group onto the single dev->pid field
(pgrp == pid, one member per group).  Extend the controlling-terminal
support so portable software (e.g. dropbear, socat) that relies on
job-control primitives works without losing the existing NuttX-specific
behaviour.

Driver (serial.c, pty.c):
- TIOCSCTTY now accepts a flag: arg > 0 keeps the historical "target
  PID in arg" semantics (NSH registers the foreground command it just
  spawned), while arg == 0 selects the calling task via
  nxsched_getpid(), matching the POSIX flag convention used by
  dropbear/socat/apue.  This preserves all existing callers and makes
  the previously-dead arg==0 path deliver SIGINT correctly.
- Add TIOCGPGRP/TIOCGSID (return dev->pid) and TIOCSPGRP (set it).
- pty.c gains the same handlers against pd_pid and includes
  nuttx/sched.h for nxsched_getpid().

ioctl numbers (tioctl.h): TIOCGPGRP/TIOCSPGRP/TIOCGSID at 0x37-0x39.

libc wrappers:
- termios: tcgetpgrp(), tcsetpgrp(), tcgetsid() over the new ioctls.
- unistd: setsid()/getsid()/setpgid() stubs consistent with the
  existing getpgrp()/getpgid() single-session model (sid == pgid ==
  pid; setpgid only succeeds for pgid == pid).

Declare the new prototypes in unistd.h (tcgetsid was already in
termios.h) and register all sources in the Make.defs/CMakeLists.

Group-broadcast signalling (kill(-pgrp)) remains unsupported, so
tty signals still target the single dev->pid; a real session/process
group model is left as a follow-up.

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2026-08-06 17:48:04 +08:00
shichunma
5a0ce87654 drivers/usbdev/rndis: Fix reported MTU OID sizes
RNDIS reports Ethernet packet sizing to the host through NDIS OIDs.
OID_GEN_MAXIMUM_FRAME_SIZE is the MTU-style value and excludes the
link-layer header, while CONFIG_NET_ETH_PKTSIZE includes the Ethernet
header.

Report the frame size as CONFIG_NET_ETH_PKTSIZE - ETH_HDRLEN, and
report OID_GEN_MAXIMUM_TOTAL_SIZE as CONFIG_NET_ETH_PKTSIZE instead of
a hardcoded 2048.

Assisted-by: OpenAI Codex:GPT-5
Signed-off-by: shichunma <shichunma@bestechnic.com>
2026-08-05 15:56:50 +08:00
Jukka Laitinen
084400f200 drivers/mmcsd/mmcsd_sdio.c: Fix finfo print modifier
Use PRIx32 to print uint32_t type argument to fix compilation error on
64 bit platforms.

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-08-05 02:08:27 +08:00
Matteo Golin
f992bf68a8 drivers/i2s/i2schar: Fix return types
This commit fixes the incorrect casting of signed types to unsigned
types in the I2S character driver.

NOTE: the I2S character driver IOCTLs retain their original argument
types. This is fine, because errors are reported through errno by the
ioctl call. The returned value in the 'arg' parameter is to be ignored
when the call results in an error. Outside of error codes, all i2s
interfaces return unsigned values.

Signed-off-by: Matteo Golin <matteo.golin@gmail.com>
2026-08-04 09:35:36 +08:00
Ricard Rosson
a2b3cbe9bc drivers/usbdev: re-assert soft connect in cdcecm/cdcncm disconnect()
The USB device controller drivers invoke CLASS_DISCONNECT() on every
USB bus reset, and a bus reset is the first step of normal host
enumeration.  Every other class driver (cdcacm, usbmsc, rndis)
re-asserts DEV_CONNECT() at the end of its disconnect() handler so
that the device remains attached; cdcecm and cdcncm did not, so on
controllers that soft-disconnect around bus reset (e.g. rp2040, which
drops the pull-up in its bus-reset handler) a standalone CDC-ECM or
CDC-NCM device is left soft-disconnected by the first bus reset and
never enumerates on the host.

Mirror the cdcacm behavior and perform the soft connect in the
disconnect() methods, unless part of a composite device (composite.c
already re-connects in its own disconnect handler).

Fixes the standalone CDC-ECM case of issue #15880.

Validated on raspberrypi-pico (RP2040): with this change a standalone
CONFIG_NET_CDCECM device that previously never appeared on the host
enumerates via cdc_ether and pings with 0% loss.  cdcncm has the
identical defect and receives the identical fix.

Signed-off-by: Ricard Rosson <ricard@groundbits.com>
Co-authored-by: Xiang Xiao <xiaoxiang781216@gmail.com>
Assisted-by: Claude (Anthropic Claude Code)
2026-08-04 09:35:20 +08:00
Jiri Vlasak
3901176758 gpio: Fix GPIO expanders warnings
- ISO1H812G is *output* only expander, not input.
- Warning make sense when we try to set the expander the wrong way.

Signed-off-by: Jiri Vlasak <jvlasak@elektroline.cz>
2026-08-04 09:34:52 +08:00
Pavel Pisa
0a5477396c drivers/input: partial fix of indistinguishable ASCII and special keycodes
As analyzed, the NuttX initial keyboard API design uses event
type KBD_SPECPRESS/KBD_SPECREL to deliver special keys
and KBD_PRESS/KBD_RELEASE to deliver ASCII codes.

But it seems that this design choice has not been followed
in virtio-input, goldfish_events and sim_keyboard designs
and result is that external keyboard special keys events
are mapped to KEYCODE_xxx values which start from 0 and
overlaps with ASCII keys.

The issue is tracked under #19527 number.

This set of changes correct events reporting for mentioned
keyboards to report right event type for special keys.

The solution is only partial at this phase.

Virtual and more complex keyboards usually deliver
key pressures as scancodes (key position on keyboard)
and mapping to ASCII for keys which corresponds to letter
and other similar keys lacks mapping of national alphabets,
second row symbols and switch to capital letter according
to modifiers.

Signed-off-by: Pavel Pisa <pisa@fel.cvut.cz>
2026-08-04 09:33:53 +08:00
Michal Lenc
1e4e454357 drivers/ioexpander/iso1i813t.c: fix error startup condition
The reference manual (section 3.2.1) states the user has to
read GLERR and INTERR registers to clear their bits and release
ERR pin after the startup sequence. Error bits are set to 1 after
the startup if external power supply is used.

Not clearing the bits leads to subsequent read call errors if VBB
errors are checked.

Signed-off-by: Michal Lenc <michallenc@seznam.cz>
2026-08-04 00:36:38 +08:00
Alan Carvalho de Assis
76faae16b2 tools: fix stale archive members surviving a Kconfig-driven CSRCS change
During the Toybox port to NuttX, Claude noticed that changes in the
menuconfig weren't taking affect. This issue exists for a long time on
NuttX, in fact BayLibre's presentation from 2017 make jokes about our
building system not been reliable:
https://www.youtube.com/watch?v=XUJK2htXxKw&t=320s

Stale archive members from $(AR)'s additive-only behavior can linger
after Kconfig toggles change which files provide a symbol, causing dead
weight or "multiple definition" link errors on incremental builds.
Fixed by splitting ARCHIVE into two macros: ARCHIVE keeps the original
additive behavior for apps/libapps.a, which many independent
subdirectories contribute to across a build, while the new
ARCHIVE_REBUILD deletes then archives for the far more common case
of a single Makefile building its own self-contained $(OBJS)
- all 39 such call sites now use it.

Assisted-By: Claude Sonnet 5
Signed-off-by: Alan C. Assis <acassis@gmail.com>
2026-08-04 00:36:32 +08:00
Marco Casaroli
d4f523e9f3 drivers/syslog: fix syslog_write() returning -EIO on every write
syslog_write_foreach() compares an unsigned count against a signed
accumulator:

  size_t  nwritten     = 0;
  ssize_t nwritten_max = -EIO;
  ...
  if (nwritten > nwritten_max)
    {
      nwritten_max = nwritten;
    }
  return nwritten_max;

The usual arithmetic conversions promote nwritten_max to size_t, so -EIO
becomes 4294967291 on a 32-bit target, and the comparison is never true.
nwritten_max keeps its initial value and the function returns -EIO no
matter how many bytes actually went out.  Observed under gdb on a running
target: nwritten == 64, nwritten_max == -5, (nwritten > nwritten_max) == 0.

Most callers discard the result -- syslog() itself returns void -- so this
is normally invisible.  It becomes fatal when /dev/console is backed by
syslog_console_write(), because then stdio acts on it.
lib_fflush_unlocked() sees a negative return, sets __FS_FLAG_ERROR and
returns early, before resetting fs_bufpos.  The bytes have already been
emitted, but the buffer is never cleared, so every subsequent stdio call
re-flushes the same CONFIG_STDIO_BUFFER_SIZE bytes.  The console fills
with one repeated fragment and the system makes no further progress.

Reaching that state needs CONFIG_CONSOLE_SYSLOG=y together with no driver
claiming /dev/console ahead of syslog_console_init().  Three in-tree
defconfigs qualify: x86/qemu-i486:ostest, renesas/skp16c26:ostest and
x86_64/qemu-intel64:earlyfb.  The other 56 CONSOLE_SYSLOG configurations
have a serial console that registers /dev/console first, which is why this
has gone unnoticed.

Introduced by 1685e8ff7b ("syslog: avoid an infinite loop if one channel
fails"), which changed nwritten_max from size_t to ssize_t = -EIO so that
an all-channels-failed case could be reported.  Give nwritten the same type
so the comparison is signed, which preserves that intent: nwritten_max
stays -EIO only when no channel wrote anything.  nwritten is never negative,
so the remaining comparisons against buflen are unaffected.

Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 00:36:09 +08:00
Filipe Cavalcanti
670d39673b drivers/video: zero message on MIPI DSI driver
Use memset to clear the msg struct before using on mipi_dsi_dcs_write_buffer.

Signed-off-by: Filipe Cavalcanti <filipe.cavalcanti@espressif.com>
2026-08-03 23:16:13 +08:00
DuoYuWang
ec9891c03a drivers/mmcsd: fix eMMC bus width switch sequencing
Two sequencing problems in the MMC wide bus path break eMMC 4-bit
operation on hosts that program the bus width in the SDIO widebus /
clock callbacks (e.g. STM32H7):

1. The SWITCH command (CMD6) is issued before the host has switched
   to wide bus operation.  When the card completes the switch while
   the host is still in 1-bit mode the switch never takes effect and
   every following data transfer times out.  Switch the host to wide
   bus operation before issuing CMD6.

2. The transfer clock is selected only at the end of mmcsd_widebus(),
   so the whole switch sequence runs at ID-mode clock and, on the
   affected hosts, the final clock update does not take effect either,
   leaving the bus at ~400 kHz.  Select the MMC transfer clock before
   calling mmcsd_widebus(), and pick CLOCK_MMC_TRANSFER_4BIT when wide
   bus operation is active (mirroring the SD card path) so a later
   clock selection cannot revert the host to 1-bit.

No behavior change for SD cards, and no change on hosts whose widebus
callback only records the requested state.

Tested on a custom STM32H743 board with eMMC: sd_bench sequential
write ~4.1 MB/s, sequential read ~6.3 MB/s (previously all data
transfers timed out).

Signed-off-by: DuoYuWang <thirteenking.wang@gmail.com>
2026-08-03 22:20:52 +08:00
Ricard Rosson
8541b57e16 drivers/usbdev/cdcncm: fix TX corruption/wedge under write buffers
Two related defects corrupt CDC-NCM transmit once TCP write buffers make TX
bursty (a single txavail poll drains many queued segments back-to-back through
cdcncm_send):

1. Buffer-reuse race. cdcncm coalesces datagrams into the single pre-allocated
   wrreq->buf that the USB controller transmits directly from, but cdcncm_send
   formatted a new NTB batch into it (cdcncm_transmit_format) without first
   waiting for the previous transfer to complete -- the wrreq_idle wait happened
   only later, in cdcncm_transmit_work. A new batch started while the previous
   NTB was still in flight overwrote the in-flight buffer, so the host dropped
   the corrupted NTB and TX could wedge (wrreq_idle never reposted).
   Fix: acquire wrreq_idle in cdcncm_send when starting a new batch
   (dgramcount == 0), before formatting; drop the now-redundant wait in
   cdcncm_transmit_work (a second wait on the init-to-1 semaphore would deadlock).

2. Concurrent transmit_work. cdcncm_send runs under the recursive netdev_lock and
   calls cdcncm_transmit_work() synchronously in the buffer-full branch, while a
   scheduled delaywork instance runs cdcncm_transmit_work() on ETHWORK -- two
   different threads. Two EP_SUBMITs of the one wrreq corrupt the IN request
   queue and leave the IN buffer prepared-but-unarmed (controller idle,
   wrreq_idle never reposted).
   Fix: wrap cdcncm_transmit_work in netdev_lock (the synchronous caller already
   holds this recursive nxrmutex; a delaywork instance blocks until the drain
   releases it), and add an empty-batch guard (dgramcount == 0 -> return) so a
   delaywork that runs after a synchronous flush emptied the batch does not seal
   an empty NTB and double-submit the in-flight wrreq.

Validated on RP2350 (Pico 2 W) with CONFIG_NET_TCP_WRITE_BUFFERS=y as part of the
complete fix set: 144 dense/concurrent HTTP downloads, zero wedges, ~486 KB/s
(previously transmit hung within a few requests). On RP2350 full stability under
maximal TX density additionally requires a memory barrier between the BUFF_STATUS
clear and the AVAILABLE re-arm in the Cortex-M33 USB device driver (a separate
change); these cdcncm defects are real and the fixes correct independent of it.

Signed-off-by: Ricard Rosson <ricard@groundbits.com>
Assisted-by: Claude (Anthropic Claude Code)
Signed-off-by: Ricard Rosson <ricard@groundbits.com>
2026-08-03 21:00:19 +08:00
Ricard Rosson
cfcfa6b085 usbmsc: fix composite-mode class requests and Hi>Di stall behavior
Three defects that together prevented macOS from ever mounting a
composite USBMSC function (Linux was mostly unaffected because its
probe sequence and recovery timing never exercised these paths):

1. usbmsc_setup() compared the class-request wIndex against the
   compile-time constant USBMSC_INTERFACEID (= CONFIG_USBMSC_IFNOBASE,
   i.e. 0) instead of the composite-assigned priv->devinfo.ifnobase.
   In composite mode the MSC interface number is nonzero, so
   GET MAX LUN, Bulk-Only Mass Storage Reset, and GET/SET INTERFACE
   all failed the index check and stalled EP0.  Standalone MSC is
   unaffected (ifnobase == 0), which is why this went unnoticed.

2. usbmsc_deferredresponse() has its entire body inside
   #ifndef CONFIG_USBMSC_COMPOSITE, so the deferred EP0 status stage
   for MSRESET/SETINTERFACE was never sent in composite mode and the
   host's Bulk-Only reset timed out.  (Unreachable before fix 1 --
   MSRESET used to stall at the wrong-interface check.)  Compile the
   body in composite mode too, but suppress the worker's deferred
   response for SETCONFIGURATION there: the composite driver answers
   that request itself, and a duplicate zero-length packet corrupts
   the EP0 state.

3. usbmsc_cmdfinishstate() stalled the bulk IN endpoint whenever a
   device-to-host command left a residue, even when the response had
   already been sent and terminated by a short packet (or ZLP).  The
   stall is BOT-legal (USB MSC BOT 6.7.2) but gratuitous: the short
   packet already ended the data phase and the residue is reported in
   dCSWDataResidue.  Hosts such as macOS answer any bulk-IN halt during
   device probing with a full Bulk-Only reset sequence, which costs
   seconds per command or aborts the probe entirely (macOS probes
   MODE SENSE(6) with allocation lengths that exceed the response;
   Linux's probe does not).  Only halt the endpoint when nothing
   terminated the data phase.

Root-cause analysis and host traces in apache/nuttx#19435.

Validated on RP2350 silicon (Raspberry Pi Pico 2 W, composite
CDC-ACM + CDC-NCM + USBMSC): GET MAX LUN answers 1 LUN (previously
EP0 stall and a garbage LUN count on macOS), MSRESET completes 10/10
(previously ETIMEDOUT), MODE SENSE(6) alloc=0xC0 returns short data
plus a CSW with dCSWDataResidue and zero bulk-IN stalls across the
exact-length suite, and macOS now mounts the volume (together with the
companion DCD fixes).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Ricard Rosson <ricard@groundbits.com>
2026-08-03 20:59:08 +08:00
Ansh Rai
5b3b4f355c libs/libc: Fix divide-by-zero in stat() with large filesystem block sizes
blksize_t is currently defined as int16_t, which overflows when a
filesystem reports a block size larger than 32767 bytes. This causes
st_blksize to become zero, leading to an integer divide-by-zero when
st_blocks is calculated in stat().

Widen blksize_t to int32_t to support larger filesystem block sizes.

Update nuttx_blksize_t in include/nuttx/fs/hostfs.h to keep it
consistent with include/sys/types.h.

struct geometry.geo_sectorsize (include/nuttx/fs/ioctl.h) is also
typed blksize_t, so every debug print of that field using a 16-bit
format specifier is updated to PRId32 to match the new width:
drivers/misc/ramdisk.c, drivers/mmcsd/mmcsd_spi.c, drivers/mtd/ftl.c,
fs/driver/fs_blockmerge.c, drivers/mtd/smart.c,
drivers/usbhost/usbhost_storage.c, drivers/mmcsd/mmcsd_sdio.c,
arch/arm/src/s32k1xx/s32k1xx_eeeprom.c,
arch/arm/src/lc823450/lc823450_mmcl.c.

Signed-off-by: Ansh Rai <anshrai331@gmail.com>
Signed-off-by: root <root@LAPTOP-9C7LKDC5.localdomain>
2026-08-03 20:58:39 +08:00
Catalin Visinescu
bc8212df09 drivers/: Multiple Drivers Are Registered With World Writable Part 3
Summary

Permissions (Part 3)

Description:

In kernel builds, any unprivileged process running on the NuttX device can
open /dev/efuse and attempt to read/write fuse content. Reading the fuses
may provide valuable information to an attacker controlling the user process.
The write operation, in extreme cases where the fuse blocks are not locked,
may brick the device.

DISCLAIMER: I tried to be strict with the settings, better to relax them
later if it's needed.

This is part of https://github.com/apache/nuttx/issues/19410

Impact

See https://github.com/apache/nuttx/issues/19410

Testing

Compiles ok.

Signed-off-by: Catalin Visinescu <catalin_visinescu@yahoo.com>
2026-08-03 17:23:22 +08:00
Catalin Visinescu
677740e7a8 drivers/: Multiple Drivers Are Registered With World Writable - Part 2
Permissions (Part 2)

Description:

In kernel builds, any unprivileged process running on the NuttX
device can open /dev/efuse and attempt to read/write fuse content.
Reading the fuses may provide valuable information to an attacker
controlling the user process. The write operation, in extreme cases
where the fuse blocks are not locked, may brick the device.

DISCLAIMER: I tried to be strict with the settings, better to relax them
later if it's needed.

This is part of https://github.com/apache/nuttx/issues/19410

See https://github.com/apache/nuttx/issues/19410

Compiles ok.

Signed-off-by: Catalin Visinescu <catalin_visinescu@yahoo.com>
2026-08-03 17:23:22 +08:00
Catalin Visinescu
bb1bdda1c4 drivers/efuse/efuse: Drivers Registered With World Write Permissions(Part 1)
Description:

In kernel builds, any unprivileged process running on the NuttX device
can open /dev/efuse and attempt to read/write fuse content. Reading the
fuses may provide valuable information to an attacker controlling the user
process. The write operation, in extreme cases where the fuse blocks are
not locked, may brick the device.

This is part of https://github.com/apache/nuttx/issues/19410

Compiles ok.

Signed-off-by: Catalin Visinescu <catalin_visinescu@yahoo.com>
2026-08-03 17:23:22 +08:00
Felipe Moura
3d059ad1d5 drivers/crypto: add Microchip RNG90 driver
Add Microchip RNG90 TRNG driver with board integration for esp32c3 and rng90 defconfig support.

Signed-off-by: Felipe Moura <moura.fmo@gmail.com>
2026-08-03 17:23:22 +08:00
hanzhijian
00968f1861 drivers/contactless: fix uninitialized uid leak in mfrc522_read
Fix security issue where uninitialized kernel stack contents could be
leaked to userspace when mfrc522_picc_select() fails.

In mfrc522_read(), the local variable 'uid' was not initialized before
being passed to mfrc522_picc_select(). If the function fails (e.g., due
to bad data on the SPI bus), the uninitialized uid.sak value could pass
the PICC_TYPE_NOT_COMPLETE check, causing snprintf() to copy
uninitialized kernel stack data to the userspace buffer.

Fixes #19417

Signed-off-by: hanzhijian <hanzhijian@zepp.com>
Author: hanzhijian <hanzhijian@zepp.com>
2026-08-03 17:23:16 +08:00
hanzhijian
68bac99057 drivers/watchdog: fix capture automonitor notifier context
Provide per-instance capture automonitor lookup for watchdog lower halves
that pass callback context, and avoid selecting an unrelated watchdog when
legacy lower halves provide no context. Update STM32 WWDG lower halves to pass
their instance context so multiple watchdog devices remain distinguishable.

Signed-off-by: hanzhijian <hanzhijian@zepp.com>
Assisted-by: OpenAI Codex
2026-08-03 17:22:37 +08:00
hanzhijian
20072dc5e6 drivers/net/w5500: fix wrong variable and d_private assignment
Fix two latent defects in the W5500 Ethernet driver:

1. NETDEV_RXERRORS() references non-existent variables (line 1351):
   In w5500_receive(), the error path uses &priv->dev but the function
   parameter is named self and the device field is w_dev. This compiles
   only because NETDEV_RXERRORS() expands to nothing without
   CONFIG_NETDEV_STATISTICS; enabling statistics breaks the build.

2. d_private set to the device array instead of the instance (line 2069):
   In w5500_initialize(), d_private was set to g_w5500 (the global array)
   instead of self (the current instance). This is harmless for device 0
   (g_w5500 == &g_w5500[0]) but wrong for any devno > 0 — every callback
   that recovers the driver state via dev->d_private would operate on
   device 0's state.

Fixes #19306

Signed-off-by: hanzhijian <hanzhijian@zepp.com>
Author: hanzhijian <hanzhijian@zepp.com>
2026-08-03 17:17:11 +08:00
yi chen
b7c3b392a9 drivers/spi/ice40: fix operator precedence in final clock cycle count
ice40_endwrite() computes how many dummy SPI bytes to clock out after
the bitstream to finish FPGA configuration with:

    for (size_t i = 0; i < ICE40_SPI_FINAL_CLK_CYCLES + 7 / 8; i++)

`/` binds tighter than `+` in C, so this parses as
ICE40_SPI_FINAL_CLK_CYCLES + (7 / 8) = 160 + 0 = 160, i.e. the "+ 7 / 8"
is a silent no-op. The macro name and the classic `(n + 7) / 8`
ceiling-division idiom (used elsewhere in embedded code to convert a
bit/cycle count into a byte count) make clear the intent was to send
ceil(ICE40_SPI_FINAL_CLK_CYCLES / 8) = 20 bytes (160 SPI clock cycles,
matching the macro name). Instead the unmodified code sends 160 bytes,
i.e. 1280 clock cycles - 8x more than intended.

Fix by parenthesizing the ceiling-division: (ICE40_SPI_FINAL_CLK_CYCLES
+ 7) / 8, which evaluates to 20, restoring the intended 160-clock-cycle
finalization sequence.

Fixes #19367

Assisted-by: Claude Code:claude-sonnet-5
Signed-off-by: yi chen <94xhn1@gmail.com>
2026-08-03 17:17:01 +08:00
yi chen
db90bd8c4b drivers/serial: hold xmit.lock around echo in uart_readv()
uart_putxmitchar() manipulates dev->xmit.head/buffer directly with
no internal locking - every other caller (uart_write()) takes
dev->xmit.lock first. uart_readv()'s ECHO handling (both the
backspace/delete erase sequence and the normal character echo)
calls uart_putxmitchar() without taking that lock, so a concurrent
uart_write() and a local echo can race on the same circular buffer
state, corrupting it.

Take dev->xmit.lock around each echo's uart_putxmitchar() calls,
matching what uart_write() already does. uart_readv() holds
dev->recv.lock for its own duration, but no other code path ever
acquires recv.lock while holding xmit.lock, so nesting xmit.lock
inside the existing recv.lock scope here doesn't introduce a new
lock-ordering cycle.

Fixes #14845

Signed-off-by: yi chen <94xhn1@gmail.com>
2026-08-03 17:16:48 +08:00
raiden00pl
d566ce17f5 drivers/i2c: I2C_SLAVE_DRIVER depends on I2C_SLAVE
I2C_SLAVE_DRIVER depends on I2C_SLAVE

Signed-off-by: raiden00pl <raiden00@railab.me>
2026-08-03 17:16:04 +08:00
Old-Ding
8c8fc40c61 drivers: wireless: bound GS2200M sscanf fields
GS2200M response parsing copies device-provided text fields into fixed-size local buffers.

Add field widths to the sscanf string conversions so the parsed address, port, and command fields stay within their destination arrays.

Signed-off-by: Old-Ding <35417409+Old-Ding@users.noreply.github.com>
2026-07-06 19:57:58 +08:00
aineoae86-sys
08240daf61 drivers: leds: Fix LP503X bank mode LED bounds
PWMIOC_ENABLE_LED_BANK_MODE uses the provided LED number to index the LP503X led_mode array. Reject values outside the RGB LED range before writing that array.

Generated-by: OpenAI Codex
Signed-off-by: aineoae86-sys <ai.neo.ae86@gmail.com>
2026-07-06 19:57:17 +08:00
Old-Ding
3c05de7273 drivers: pci: Fix EPF debug assertions
pci_epf_device_register() and pci_epf_unregister_driver() used || in DEBUGASSERT expressions that validate a pointer and a required field or callback. If the pointer is NULL, the right-hand side dereferences it; if the pointer is valid but the required member is NULL, the assertion passes.

Require both conditions in each assertion so the debug checks match the preconditions used later in the functions.

Generated-by: OpenAI Codex
Signed-off-by: Old-Ding <35417409+Old-Ding@users.noreply.github.com>
2026-07-06 19:56:58 +08:00
Old-Ding
6989e89ede drivers/usbdev: rndis: Reject truncated responses
When several RNDIS responses are queued, the control request handler sends one complete response if the host wLength is smaller than the whole queue. If the first queued response is also larger than wLength, copying hdr->msglen bytes would overrun the requested transfer and the completion path would consume a partial message.

Return EMSGSIZE before copying in that case so the queued response remains intact for a retry with a large enough wLength.

Signed-off-by: Old-Ding <35417409+Old-Ding@users.noreply.github.com>
2026-07-06 19:56:11 +08:00
Old-Ding
1d7d5d3f13 drivers: pci: Fix EPC MSI IRQ map validation
pci_epc_map_msi_irq() used && when checking the EPC pointer and map_msi_irq callback. If epc is NULL, the right-hand side dereferences it; if the callback is NULL on a valid EPC, the guard does not reject it before the call.

Match the surrounding EPC wrappers by rejecting a NULL EPC, an out-of-range function number, or a missing map_msi_irq callback before taking the lock and invoking the operation.

Generated-by: OpenAI Codex
Signed-off-by: Old-Ding <35417409+Old-Ding@users.noreply.github.com>
2026-07-06 19:56:02 +08:00
aineoae86-sys
bc764dc9bd drivers: 1wire: Fix DS2XXX device type bounds
EEPROM_DS_COUNT is the number of supported DS2XXX device types and is used as the size of the EEPROM geometry tables. Reject it before storing the device type for later table indexing.

Generated-by: OpenAI Codex
Signed-off-by: aineoae86-sys <ai.neo.ae86@gmail.com>
2026-07-06 19:55:05 +08:00
Ilikara
071a358f77 drivers: Fix comment typos — 'Pubic' → 'Public' across drivers and headers.
Fix spelling error in section header comments:
  'Pubic Function Prototypes' → 'Public Function Prototypes'
  'Pubic Functions' → 'Public Functions'

Affected files (12 files, 12 occurrences):
  arch/arm/src/at32/at32_tim.c
  arch/arm/src/common/stm32/stm32_tim_m3m4_v1v2v3.c
  arch/arm/src/stm32l4/stm32l4_tim.c
  arch/arm/src/stm32l5/stm32l5_tim.c
  arch/arm/src/stm32u5/stm32_tim.c
  arch/arm/src/stm32wb/stm32wb_tim.c
  arch/arm/src/stm32wl5/stm32wl5_tim.c
  arch/mips/src/pic32mz/pic32mz_timer.c
  arch/sparc/src/bm3803/bm3803_tim.c
  arch/sparc/src/s698pm/s698pm_tim.c
  drivers/video/vnc/vnc_server.c
  include/nuttx/wdog.h

These are all comment-only changes with no functional impact.

Signed-off-by: Ilikara <3435193369@qq.com>
2026-07-04 02:00:24 +08:00
hanzhijian
502feadb3d stdlib/rand: replace weak LCG with xorshift32 PRNG
The existing first-order LCG (seed = 470001 * seed % 999563) has several
quality problems:
- Output range limited to [1, 999562] (~20 bits) instead of full 32-bit
- Lower bits have very short periods (8-bit period = 1, 16-bit = 105)
- Overall period only ~1M, far too short for many applications
- Causes mbedtls_rsa_gen_key to loop forever when rand() consumption
  aligns with the cycle length (issue #16760)

Replace the entire order-based LCG implementation (CONFIG_LIBC_RAND_ORDER
0-3) with Marsaglia's xorshift32:
- Full 32-bit output range
- Period 2^32 - 1 (~4.29 billion)
- Fast: just three XOR/shift operations
- No floating-point math needed
- No CONFIG_LIBC_RAND_ORDER configuration required

Remove the CONFIG_LIBC_RAND_ORDER Kconfig option and clean up all
defconfig references (12 boards) and related comments.

Signed-off-by: hanzhijian <hanzhijian@zepp.com>
2026-07-04 01:59:35 +08:00
Catalin Visinescu
140ad8b305 arch/arm/src/at32/at32_can: Division by Zero in CAN Bit Timing Commands
An unchecked integer assignment in the CAN driver may result in a division-by-zero which would result in a kernel crash (denial of service).

Tested locally, builds fine.

An unchecked integer assignment in the CAN driver may result in a division-by-zero which would result in a kernel crash (denial of service).

The CAN driver `can_ioctl` function, shown below (drivers/can/can.c), receives commands from user processes. Its received arguments `cmd` and content of `arg` are under attacker's control. In the CAN driver, some `ioctl` commands are hardware specific and are processed by calling `dev_ioctl()`. Subsequently, depending on the hardware (STM32 or AT32), this function calls `fdcan_ioctl` or `at32can_ioctl`, as shown in the snippets that follow.

```c

static int can_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
{
  FAR struct inode        *inode  = filep->f_inode;
  FAR struct can_dev_s    *dev    = inode->i_private;
  FAR struct can_reader_s *reader = filep->f_priv;
...
  flags = enter_critical_section();

  /* Handle built-in ioctl commands */
  switch (cmd)
    {
...
      /* Not a "built-in" ioctl command.. perhaps it is unique to this
       * lower-half, device driver. */
      default:
        {
          ret = dev_ioctl(dev, cmd, arg);
        }
        break;
    }

  leave_critical_section(flags);
  return ret;
}
```

There are a few instances where the user can trigger a kernel crash, caused by a division by zero on `CANIOC_SET_BITTIMING` command. On STM32 platforms (arch/arm/src/stm32/stm32_fdcan.c), while there is a `DEBUGASSERT` assertion for `bt->bt_baud`, the check does not cover value `0`.

```c
static const struct can_ops_s g_fdcanops =
{
...
  .co_ioctl         = fdcan_ioctl,
...
};

static int fdcan_ioctl(struct can_dev_s *dev, int cmd, unsigned long arg)
{
...
  switch (cmd)
    {
...
      case CANIOC_SET_BITTIMING:
        {
          const struct canioc_bittiming_s *bt = (const struct canioc_bittiming_s *)arg;
          uint32_t nbrp;
          uint32_t ntseg1;
          uint32_t ntseg2;
          uint32_t nsjw;
          uint32_t ie;
          uint8_t state;

          DEBUGASSERT(bt != NULL);
          DEBUGASSERT(bt->bt_baud < STM32_FDCANCLK_FREQUENCY); // <- not valid
          DEBUGASSERT(bt->bt_sjw > 0 && bt->bt_sjw <= 16);
          DEBUGASSERT(bt->bt_tseg1 > 1 && bt->bt_tseg1 <= 64);
          DEBUGASSERT(bt->bt_tseg2 > 0 && bt->bt_tseg2 <= 16);

          /* Extract bit timing data */
          ntseg1 = bt->bt_tseg1 - 1;
          ntseg2 = bt->bt_tseg2 - 1;
          nsjw   = bt->bt_sjw   - 1;

          nbrp = (uint32_t)
            (  ((float) STM32_FDCANCLK_FREQUENCY /
               ((float)(ntseg1 + ntseg2 + 3) * (float)bt->bt_baud)) - 1 ); // <- div by 0
```

Similarly, another division by zero was found in Artery Technology AT32 (arch/arm/src/stm32/stm32_can.c) driver:

```c
static const struct can_ops_s g_canops =
{
...
  .co_ioctl         = at32can_ioctl,
...
};

static int at32can_ioctl(struct can_dev_s *dev, int cmd, unsigned long arg)
{
...
  /* Handle the command */
  switch (cmd)
    {
...
      case CANIOC_SET_BITTIMING:
        {
          const struct canioc_bittiming_s *bt = (const struct canioc_bittiming_s *)arg;
...
          uint32_t tmp;
          uint32_t regval;

          DEBUGASSERT(bt != NULL);
          DEBUGASSERT(bt->bt_baud < AT32_PCLK1_FREQUENCY); // <- not valid
          DEBUGASSERT(bt->bt_sjw > 0 && bt->bt_sjw <= 4);
          DEBUGASSERT(bt->bt_tseg1 > 0 && bt->bt_tseg1 <= 16);
          DEBUGASSERT(bt->bt_tseg2 > 0 && bt->bt_tseg2 <=  8);

          regval = at32can_getreg(priv, AT32_CAN_BTMG_OFFSET);

          /* Extract bit timing data tmp is in clocks per bit time */
          tmp = AT32_PCLK1_FREQUENCY / bt->bt_baud; // <- div by 0
```

Instances found are listed in the *Location* section below. They are not shown in detail to reduce the length of the issue.

Ensure the attacker-controlled data is properly validated before use, to stop division by zero situations. For instance:

```c
DEBUGASSERT(bt->bt_baud > 0 && bt->bt_baud < AT32_PCLK1_FREQUENCY);
```

* arch/arm/src/stm32/stm32_fdcan.c
* arch/arm/src/stm32/stm32_can.c
* arch/arm/src/sama5/sam_mcan.c
* arch/arm/src/at32/at32_can.c
* arch/arm/src/samv7/sam_mcan.c
* arch/arm/src/stm32f0l0g0/stm32_fdcan.c
* arch/arm/src/stm32f7/stm32_can.c
* arch/arm/src/stm32h5/stm32_fdcan.c
* arch/arm/src/stm32l4/stm32l4_can.c
* arch/arm/src/tiva/common/tiva_can.c
* drivers/can/mcp2515.c

Signed-off-by: Catalin Visinescu <catalin_visinescu@yahoo.com>
2026-07-04 01:56:16 +08:00
Xiang Xiao
a0357b3a65 !include/fcntl.h: align open flags with Linux values
Align the NuttX open(2) flag constants with the Linux asm-generic
values so that the FUSE wire protocol and other cross-platform
interfaces work without conversion.

All code that used '(flags & O_RDONLY)' as a bitmask check (always 0
now that O_RDONLY=0) has been updated to use '(flags & O_ACCMODE)'
comparisons.

The NUTTX_O_* constants in include/nuttx/fs/hostfs.h are updated to
match, and the sim hostfs open flag mapping is fixed.

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2026-07-03 10:33:47 +08:00
Xiang Xiao
c790612159 include/fcntl.h: remove O_RDOK/O_WROK aliases
O_RDOK and O_WROK are non-standard aliases for O_RDONLY and O_WRONLY
respectively.  Having two names for the same flag creates confusion,
especially when aligning the flag values with Linux.  Remove the
aliases and replace all uses with the standard O_RDONLY/O_WRONLY.

No functional change — O_RDOK was defined as O_RDONLY and O_WROK as
O_WRONLY, so the replacement is a pure text substitution.

Signed-off-by: Xiang Xiao <xiaoxiang@xiaomi.com>
2026-07-03 10:33:47 +08:00
Catalin Visinescu
ae07c68d9e drivers/contactless/mfrc522: Contactless Driver Is Not Robust
An attacker can specify an arbitrary page address when reading MIFARE tags.
Without validation, this could read beyond intended memory regions on the
tag, potentially causing a crash.

The mfrc522_mifare_read() command is also not robust and does not check
that the page address is valid. From section 7.6.5 of the *MIFARE Ultralight
contactless single-ticket IC
(https://www.nxp.com/docs/en/data-sheet/MF0ICU1.pdf) document:

>> The READ command needs the page address as a parameter. Only addresses
00h to 0Fh are decoded.

Testing: Builds fine.

Signed-off-by: Catalin Visinescu <catalin_visinescu@yahoo.com>
2026-07-03 10:33:41 +08:00
Sammy Tran
961fd8f7ca drivers/mtd/gd25: add QSPI support
Add QSPI mode to the GD25 MTD driver alongside the existing SPI path.
When CONFIG_GD25_QSPI is selected, sector erase, chip erase, byte read,
page write, and byte write all use the QSPI command/memory interfaces
instead of SPI. Reads use the quad I/O fast-read command (1-4-4) and
writes use the quad page-program command (1-1-4) via QSPIMEM_QUADDATA.
A new Kconfig option enables the QE bit in SR2 at initialisation so the
quad I/O pins are active.

Signed-off-by: Sammy Tran <sammytran@geotab.com>
2026-07-03 10:32:41 +08:00
Catalin Visinescu
2f1da092f2 nuttx/drivers/crypto/pnt/pnt_se05x_api: Minor Overflow in Secure Element Driver May Cause a DoS
Invalid data is passed to the NXP Plug & Trust Nano Package used by the
NuttX secure element driver. If the NXP code is not handling the malformed
data, a corruption can occur. Alternatively, if the attacker is able to
point create_signature_args->algorithm in memory at an address that is not
accessible, a crash can occur.

Applicable to:
* `signature_algorithm_mapping[create_signature_args->algorithm]`
* `signature_algorithm_mapping[verify_signature_args->algorithm]`

Signed-off-by: Catalin Visinescu <catalin_visinescu@yahoo.com>
2026-07-03 10:30:52 +08:00
Alan Carvalho de Assis
e001138731 drivers/audio: Fix audio tone generator
The audio tone generator stopped working with the 'echo' command
since https://github.com/apache/nuttx-apps/pull/1559

Before that PR:

nsh> echo "t120o1l16b9n0baan0bn0bn0baaan0b9n0baan0b" > /dev/tone0
tone_write: Received 41 bytes
nsh>

After that PR:

nsh> echo "t120o1l16b9n0baan0bn0bn0baaan0b9n0baan0b" > /dev/tone0
tone_write: Received 40 bytes
tone_write: Received 1 bytes
nsh>

Unfortunately the Audio Tone was not block new write attempts even
when it was already playing a melody.

This commit fix it and avoids the issue caused by that PR.

Signed-off-by: Alan C. Assis <acassis@gmail.com>
2026-07-02 08:59:54 -03:00
Catalin Visinescu
63c095ffef drivers/can/ctucanfd_pci: Fix Malformed CAN Data Msg (address off-by-one)
PR https://github.com/apache/nuttx/pull/19139 addresses the issue, but there
is one minor problem. In the for loop the element `i+1` is written which
means there can still be an overflow by one element (uint32_t or 4 bytes).

Addressing here with this PR.

Tested locally, builds fine.

Signed-off-by: Catalin Visinescu <catalin_visinescu@yahoo.com>
2026-06-26 10:52:07 +08:00
Michal Lenc
eb21f59f2f syslog: avoid an infinite loop if one channel fails
The current implementation exits syslog_write_foreach function
if write to one channel fails, causing other channels not being written
and returning negated errno. libc syslog functions then stay in
an infinite loop, because error is returned and the same bytes
are still passed to syslograwstream_flush and syslog_write_foreach.

The channel write may fail for many reasons - disconnected USB if
CDC ACM syslog is enabled, lost networking if telnet syslog is enabled,
error on NOR flash etc. This shouldn't lead to an ininite loop in the
code though.

The solution ensures all channels in syslog_write_foreach are tried,
therefore the user get the output to the working channels even if
the first one is broken. It also updates syslograwstream_addchar and
syslograwstream_addstring to skip the bytes if all channels fails. This
ensures syslog call won't result in an infinite loop, but the user may
lost the debugging output.

Co-authored-by: Martin Krasula <mkrasula@elektroline.cz>
Signed-off-by: Michal Lenc <michallenc@seznam.cz>
2026-06-24 09:46:34 +08:00
Catalin Visinescu
0076f35401 drivers/eeprom/i2c_xx24xx: Integer Overflow in I2C EEPROM ee24xx_seek()
The function seek which allows the user to move the cursor to a particular
offset in order to read and write from EEPROM storage does not validate the
offset is valid. Later, this can cause an out-of-bounds reads or writes.
Note that newpos may store a large value, larger than the size of the EEPROM.

Similar change in the SPI driver.

Tested locally, builds fine.

Signed-off-by: Catalin Visinescu <catalin_visinescu@yahoo.com>
2026-06-23 10:02:10 +08:00
hanzhijian
687471c0d9 drivers/clk: fix conflicting types in clk_register_* definitions
Update the function definitions in all 6 clk implementation files to
match the uintptr_t parameter type already declared in clk_provider.h.

Fixes CI error:
  error: conflicting types for 'clk_register_divider'

Signed-off-by: hanzhijian <hanzhijian@zepp.com>
2026-06-23 09:46:33 +08:00
hanzhijian
b0e8926eb6 drivers/clk: use uintptr_t for register addresses
Change the 'reg' field type from uint32_t to uintptr_t in all clock
provider structs (clk_gate_s, clk_divider_s, clk_phase_s,
clk_fractional_divider_s, clk_multiplier_s, clk_mux_s) and their
corresponding clk_register_*() function prototypes.

Also update clk_write() and clk_read() inline functions to take
uintptr_t parameter and remove the now-redundant (uintptr_t) cast.

On 32-bit embedded platforms uintptr_t equals uint32_t so there is
no functional change. On 64-bit targets (e.g. sim) this fixes
-Wint-to-pointer-cast warnings that GCC15 promotes to errors.

Fixes: #16896
Signed-off-by: hanzhijian <hanzhijian@zepp.com>
2026-06-23 09:46:33 +08:00
Jukka Laitinen
d4a5db49c2 drivers/mtd: Make compile time check for sane mtd isbad/markbad configuration
This removes the DEBUGASSERT in ftl_initialize_by_path. Instead, check
compile time that FTL is enabled in case some of the drivers implement
the isbad and markbad functions.

Also select the FTL_BBM for those drivers as they require it.

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-06-17 23:14:58 +08:00
Catalin Visinescu
d33e20fa1c drivers/contactless/pn532: Fix Stack Overflow in PN532 Contactless Driver
When calling Set RF Configuration command, a compromised user
process can trigger memory corruption in the kernel. This can
lead to a system crash or potentially arbitrary code execution
in the kernel.

It addresses an earlier incomplete fix.

Tested locally.

Signed-off-by: Your Name <catalin_visinescu@yahoo.com>
2026-06-17 17:13:32 +08:00
Catalin Visinescu
269cc0dc15 drivers/can/ctucanfd_pci: Stack Overflow When Malformed CAN Data Is Received
A malformed packet can trigger memory corruption in the kernel leading to a
system crash or potentially arbitrary code execution in the kernel.

The CAN driver for the CTU CAN FD IP Core connected to the NuttX device
via a PCI / PCI Express (PCIe) bus shows a lack of consideration for
malformed data, assuming the CAN frames are always correct.

Ensure `frame->fmt.rwcnt` is 21 or less before it is used in the `for` loop.

A similar change was done in ctucanfd_sock_recv().

Tested locally, builds fine.

Signed-off-by: Catalin Visinescu <catalin_visinescu@yahoo.com>
2026-06-17 17:12:22 +08:00
yushuailong
fb4ffa4ae7 drivers/timers: Fix non-atomic clock read in up_timer_gettime.
up_timer_gettime() computed tv_sec and tv_nsec from two separate calls
to current_usec(), which returns a free-running microsecond counter.
The counter advances between the two calls, so a read that straddles a
second boundary yields an inconsistent (possibly backwards) timespec.

Read current_usec() once into a local variable and derive both fields
from that single snapshot.

Signed-off-by: yushuailong <yyyusl@qq.com>
2026-06-17 17:12:04 +08:00
Jukka Laitinen
8c1ac9c093 drivers/input/button_upper.c: Fix compilation with CONFIG_DISABLE_ALL_SIGNALS
The optional signal delivery should be disabled when signals support is
disabled for the board.

Signed-off-by: Jukka Laitinen <jukka.laitinen@tii.ae>
2026-06-17 17:11:26 +08:00