nd6: keep foreign-CPU neighbors off the timer and purge list
Route requests create neighbor entries on each network CPU, but timers
and purge run on CPU 0. Purging a foreign-CPU entry deletes the matching
local route and can follow its freed neighbor entry. Link only CPU 0
entries into the list and unlink only linked entries; keep other CPUs
route-local neighbor data.
Bug: https://bugs.dragonflybsd.org/issues/3439
pf.conf.5: describe IPv6 fragment filtering without reassembly
IPv6 fragments are filtered as the Fragment header protocol, not blocked
unconditionally. State that port/type rules cannot pass them and that a
broad pass rule does not enforce those restrictions.
Bug: https://bugs.dragonflybsd.org/issues/3438
netinet: fix ARP resolution during the first second of uptime
A cloned route created while time_uptime is zero passes a zero expiry
to its neighbors. Zero denotes a permanent entry, so unresolved dynamic
neighbors never send ARP requests.
Add the arp_expire_unresolved (= time_uptime + 1) to keep dynamic expiry
nonzero and track the last request time separately, using la_asked to
indicate whether that time is valid. This preserves same-second rate
limiting and permanent-entry semantics without changing the routing ABI.
While there, fix the code to add arpt_down to rt_expire only when it's a
cloned route.
Co-authored-by: Aaron LI <aly at aaronly.me>
GitHub-PR: https://github.com/DragonFlyBSD/DragonFlyBSD/pull/58
dsynth - Do not cross mount boundaries when making template's /etc
* When making the template's /etc, do not cross mount boundaries.
* This is a bit of a hack but /etc/namedb sometimes has a "dev"
subdirectory for its chroot area that mounts devfs. This kinda
implodes when we later try to tmpfs it.
dsynth - Apply the "debug" directive to ports-mgmt/pkg
The debug directive was not being applied to ports-mgmt/pkg,
so we couldn't retain the mounts for debugging purposes when
explicitly building that target.
Adjust the (s4) string to recognize multiple flags, since fixing
this requires two flags to be passed in.
Reported-by: aly
kernel - Fix I/O stalls caused by TRIM ops
* I/O can stall out in physstr when TRIM ops are delpoyed. The
cause is that the da_softc->outstanding_cmds_rd tracker used by
the I/O balancer was decrementing the field on TRIM completions.
* Fix by ensuring that the tracker only applies to READ commands.
* Refactor scheduling checks in dastart(). The checks were a bit broken
but worked due to a catch-all in dadone(). Refactor so they work properly.
* Refactor conditional/block syntax a bit for readability.
Reported-by: myself and numerous others
kern: avoid reading a disk label while dumping
Checking an unlabelled dump slice can trigger a disk-label read through
normal buffered I/O. During a crash dump, that read can wait indefinitely
before the dump writer reaches its polled I/O path.
Skip the label read while dumping and use the slice bounds already held
in memory, keeping the normal label probe outside the dump path.
Bug: https://bugs.dragonflybsd.org/issues/3441
kern: skip module shutdown handlers on panic
module_shutdown() is a shutdown_post_sync handler, so it also runs on the
panic path after the panicking CPU has stopped the other CPUs. Some
MOD_SHUTDOWN handlers block on kernel threads that cannot run once their
CPU is stopped: vn calls disk_destroy(), and disk_msg_send_sync() then
waits forever for the disk_msg_core thread. The machine hangs after
"Dump complete" and never reboots.
Skip the module shutdown handlers on a panic, as resettodr_on_shutdown()
and shutdown_kproc() already do. The dump is already written when this
handler runs.
Reproduced in a QEMU/NVMM guest: panic + dump with
hw.acpi.handle_reboot=1 hangs at "Dump complete" on SMP and reboots on a
single CPU. With this change the guest reboots with
hw.acpi.handle_reboot 1 and 0, with and without a dump.
Bug: https://bugs.dragonflybsd.org/issues/3450
dsynth - Fix improper deletions with "prepare-system"
* Don't delete "obsolete" packages for "prepare-system"
* Obsolete packages can only be properly deleted when
a full scan is done. "prepare-system" only does a
partial scan so it winds up deleting stuff it
should not delete.
pf: fix IPv6 fragment length checks
ip6_plen excludes the IPv6 header, but off includes it. Check packet and
fragment-header bounds, use matching length units, and reject misaligned
non-final fragments. Include pre-fragment extension headers in the
reassembled payload limit.
Bug: https://bugs.dragonflybsd.org/issues/3437
ndp(8): avoid deleting covering routes and report socket errors
RTM_GET can return a covering route for an absent neighbor. Require the
requested address and an NDP route before deletion. Return failure for
routing-socket write, read and reply errors, and pass deletion failure
to the exit status.
Bug: https://bugs.dragonflybsd.org/issues/3436
libkvm(3): clear failed lookups and report lookup errors
Clear requested symbol results before lookup. Keep the live failure
count and continue looking up later entries. Report lookup errors
without relying on the last errno, and preserve table errors in internal
callers.
Bug: https://bugs.dragonflybsd.org/issues/3444
asr(4): Fix bug of DPT_4_BYTES being wrongly defined as long (8 bytes)
Caught by GCC 12.5 with the following '-Warray-bounds' warnings:
```
In file included from /usr/src/sys/dev/raid/asr/asr.c:148:
/usr/src/sys/dev/raid/asr/asr.c: In function 'ASR_getStatus':
/usr/src/sys/dev/raid/asr/dptalign.h:277:26: warning: array subscript 'long unsigned int[4]' is partly outside array bounds of 'I2O_EXEC_STATUS_GET_MESSAGE[1]' {aka 'struct _I2O_EXEC_STATUS_GET_MESSAGE[1]'} [-Warray-bounds]
277 | *((unsigned DPT_4_BYTES __FAR__ *)getUP1(x,y)) \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/src/sys/dev/raid/asr/i2odep.h:492:17: note: in expansion of macro 'setLU4'
492 | setLU4((&(x)->ReplyBufferLength),0,y)
| ^~~~~~
/usr/src/sys/dev/raid/asr/asr.c:614:9: note: in expansion of macro 'I2O_EXEC_STATUS_GET_MESSAGE_setReplyBufferLength'
614 | I2O_EXEC_STATUS_GET_MESSAGE_setReplyBufferLength(Message_Ptr,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/src/sys/dev/raid/asr/asr.c:599:41: note: at offset 32 into object 'Message' of size 36
599 | I2O_EXEC_STATUS_GET_MESSAGE Message;
| ^~~~~~~
[17 lines not shown]
ena(4): Fix possible NULL deref in ena_com_create_and_store_tx_meta_desc()
get_sq_desc() may return NULL, so passing the return value to memset()
would cause a NULL deref. GCC 12.5 caught this and gave a
-Warray-bounds warning:
```
In file included from /usr/src/sys/dev/virtual/amazon/ena/ena-com/ena_plat.h:40,
from /usr/src/sys/dev/virtual/amazon/ena/ena-com/ena_com.h:38,
from /usr/src/sys/dev/virtual/amazon/ena/ena-com/ena_eth_com.h:40,
from /usr/src/sys/dev/virtual/amazon/ena/ena-com/ena_eth_com.c:34:
In function 'ena_com_create_and_store_tx_meta_desc',
inlined from 'ena_com_prepare_tx' at /usr/src/sys/dev/virtual/amazon/ena/ena-com/ena_eth_com.c:409:3:
dragonfly/sys/systm.h:268:9: warning: '__builtin_memset' offset [0, 11] is out of the bounds [0, 0] [-Warray-bounds]
268 | __builtin_memset(__DEQUALIFY(void *, (ptr)), (c), (len))
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/src/sys/dev/virtual/amazon/ena/ena-com/ena_eth_com.c:295:9: note: in expansion of macro 'memset'
295 | memset(meta_desc, 0x0, sizeof(struct ena_eth_io_tx_meta_desc));
| ^~~~~~
[3 lines not shown]
wlan: Fix NULL deref bug in hwmp_discover()
The 'ni' is explicitly NULL, but IEEE80211_NOTE() expands to
ieee80211_note_mac() that would access 'ni->ni_macaddr', causing a NULL
deref. Fix it by porting the FreeBSD's fix: replacing IEEE80211_NOTE()
with IEEE80211_DPRINTF() without accessing 'ni'.
Caught by GCC 12.5 warning:
```
In file included from /usr/src/sys/netproto/802_11/wlan/ieee80211_hwmp.c:63:
/usr/src/sys/netproto/802_11/wlan/ieee80211_hwmp.c: In function 'hwmp_discover':
dragonfly/netproto/802_11/ieee80211_var.h:963:17: warning: 'ieee80211_note_mac' reading 6 bytes from a region of size 0 [-Wstringop-overread]
963 | ieee80211_note_mac(_vap, (_ni)->ni_macaddr, _fmt, __VA_ARGS__);\
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/src/sys/netproto/802_11/wlan/ieee80211_hwmp.c:2137:33: note: in expansion of macro 'IEEE80211_NOTE'
2137 | IEEE80211_NOTE(vap, IEEE80211_MSG_HWMP,
| ^~~~~~~~~~~~~~
dragonfly/netproto/802_11/ieee80211_var.h:963:17: note: referencing argument 2 of type 'const uint8_t[6]' {aka 'const unsigned char[6]'}
[9 lines not shown]
hammer2: Fix a NULL deref in hammer2_chain_lastdrop()
That is the no-parent case, i.e., parent is NULL, so it was an error
to access 'parent->core.spin'. Simply remove the hammer2_spin_unex()
call to fix the bug.
This bug was caught by the GCC 12.5 warning:
```
In file included from include/machine/atomic.h:7,
from /usr/src/sys/sys/systm.h:49,
from /usr/src/sys/vfs/hammer2/hammer2_chain.c:57:
In function 'atomic_add_int',
inlined from 'spin_unlock_quick' at /usr/src/sys/sys/spinlock2.h:170:2,
inlined from 'spin_unlock' at /usr/src/sys/sys/spinlock2.h:183:2,
inlined from 'hammer2_chain_lastdrop' at /usr/src/sys/vfs/hammer2/hammer2_chain.c:654:4,
inlined from 'hammer2_chain_drop' at /usr/src/sys/vfs/hammer2/hammer2_chain.c:359:13,
inlined from 'hammer2_chain_drop' at /usr/src/sys/vfs/hammer2/hammer2_chain.c:346:1:
./cpu/atomic.h:91:9: warning: array subscript 0 is outside array bounds of 'int[0]' [-Warray-bounds]
[12 lines not shown]
setutxdb(3): Support UTX_DB_LASTLOGX to read last login records
Before this fix, setutxdb(3) returned EINVAL for choosing
UTX_DB_LASTLOGX, so getutxuser() was unable to get last login records
from the lastlogx(5) database. This exact problem caused sshd(8)
failing to print the 'Last login' message on login.
Fix setutxdb(3) to support UTX_DB_LASTLOGX. Note that the lastlogx(5)
database is a Berkeley DB hash keyed by uid and uses the 'lastlogx'
struct.
Assisted-by: DeepSeek-v4.1-flash (with Pi Coding Agent)
pututxline(3): Initialize the lastlogx struct for updlastlogx()
This doesn't fix a real bug, because the uninitialized fields in 'struct
lastlogx' are currently unused by updlastlogx(). Fix it to be
future-proof.
stand/cd9660: handle padding after advancing the record pointer
cd9660_open() walks a CD9660 directory by moving dp to the next record
and then adding the record length to the byte counter off. dp has
already moved, so off gets the next record's length, not the current
one. At the end of a directory this can leave off block-aligned after
the last real record, so the loop reads one sector past the directory
extent before it can observe the zero padding. The following sector can
be the start of another file; parsing its bytes as a directory record
can make the Rock Ridge/SUSP scanner loop without making progress and
hang the loader before the kernel.
Follow the FreeBSD fix from D8101 and handle padding immediately after
the advance: if the new record has zero length it is padding, so resync
off to the block boundary and continue. Otherwise add the new record
length.
Obtained-from: FreeBSD (review: https://reviews.freebsd.org/D8101)
Bug: https://bugs.dragonflybsd.org/issues/3446
hammer(8): Fix check_period() to handle DST for daily period
Converting rounded local midnights with mktime() can leave only 23 hours
between consecutive dates when daylight saving time starts. Fix it by
using timegm() that ignores DST offsets.
Reported-by: pavalos
Bug: https://bugs.dragonflybsd.org/issues/2526
catopen(3): align returned errors with POSIX.1-2024
Return ENOENT instead of EFTYPE for invalid/empty names, non-existent
catalogue files, and bad catalogue headers. Require the complete header
and reject sizes that exceed mmap() limit.
Also save the errno in handling the open() failure.
Derived-from: FreeBSD (commit 1176390d2d2bbb1e207c840d1f7a66a6ac1096ff)
Reported-by: pmjdebruijn
Bug: https://bugs.dragonflybsd.org/issues/3393
socket: Implement getsockopt(SO_ACCEPTCONN)
SO_ACCEPTCONN is defined in <sys/socket.h>, but sogetopt() did not
handle it, so getsockopt(2) returned ENOPROTOOPT. FreeBSD, OpenBSD
and NetBSD all report it among the SOL_SOCKET options.
TigerVNC and similar servers probe this option to tell whether
their standard input is a connected socket or a listening socket
inherited from inetd "wait" mode. Without it, TigerVNC treats the
listening socket as connected, getpeername() fails with ENOTCONN,
and inetd respawns the server in a loop.
Add SO_ACCEPTCONN to the integer SOL_SOCKET option group, matching
FreeBSD (see commit dcb5fef5dbd4ca8488deff7a9074850d851bdc08).
Reported-by: Adrian Kieß
Bug: https://bugs.dragonflybsd.org/issues/3300
catopen(3): Fix race condition
The current code uses a rwlock to protect the cached list, which
in turn holds a list of catentry objects, and increments reference
count while holding only read lock. Fix this by converting the
reference counter to use atomic operations.
Also improve the cleanups of memory allocations.
Obtained-from: FreeBSD (commit 4188ba1a3b65b4a55fc938b71d9091fafb57967d)
Reported-by: pmjdebruijn
Bug: https://bugs.dragonflybsd.org/issues/3393
kdmsg: protect connection-state publication and ownership
Autoinitiate can create a connection transaction after the writer has
stopped. The state can survive into the next connection, where replacing
conn_state loses its held reference. An old close callback can also drop
the replacement state's reference instead of its own.
Hold msglk across creation, publication and queuing, and do not initiate
a connection once EXITNOACC is set. Use a locked allocator helper for
this call path so the allocator does not need recursive lock acquisition.
Release the previous conn_state reference before replacing it. On DELETE,
clear and release the slot only when it still points to the callback's
state, independently of whether a closing reply is needed.
Dropping the previous conn_state reference is now only needed when two
autoinitiates race on a live connection; otherwise the old transaction is
cleaned up through the state tree.
Bug: https://bugs.dragonflybsd.org/issues/3435
kdmsg: shut down the transport while waiting for reconnect workers
KILLRX and a wakeup on msg_ctl do not interrupt a reader blocked in
fp_read() on a quiet connection. Reconnect can then wait indefinitely
for the reader and writer to exit. HAMMER2's recluster ioctl holds the
root vnode during this wait, blocking other filesystem operations.
Shut down msg_fp before sleeping in the worker-wait loop. This wakes
blocked transport I/O and leaves the existing state cleanup and file
reference handling in place.
Keep the shutdown inside the loop: lksleep() releases msglk, so another
reconnect may replace the connection while this caller is asleep. A
one-time shutdown before the loop can leave this caller waiting on the
replacement workers.
Bug: https://bugs.dragonflybsd.org/issues/3434
bpf: add XOR and modulo instructions
libpcap can generate XOR and modulo instructions, but the kernel
interpreter and validator do not support them.
Add constant and register operands for both operations. Reject constant
modulo by zero and return zero for a register zero divisor, as for DIV.
Update the manual to match.
Patch-by: guy
Bug: https://bugs.dragonflybsd.org/issues/3387