A text cursor in the tty; LDLS sets net_device.priv_len

The virtual terminals never drew a cursor. Each now paints a steady
block (the cell with its colours swapped), erased before and redrawn
after every output byte, redrawn by a repaint, and hidden by
ESC [ ? 25 l as curses programs ask.

r8169 under LDLS on the TUF A15 got through probe and died in ndo_open
on __fortify_panic. netdev_priv() is `dev->priv` now, a flexible array
counted by net_device.priv_len, and rtl_open's memset of its ring
bookkeeping is bounds-checked against it. The allocator left priv_len
zero, so the driver saw an area of no bytes. It is set from BTF when the
kernel has the member. __fortify_panic also says which check, how many
bytes it had and wanted, and where from.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_015f73FesGZGYPkmDvUcj6QX
This commit is contained in:
Nexoniarz 2026-10-25 18:25:30 +01:00
commit 96389ada8f
7 changed files with 86 additions and 5 deletions

View file

@ -136,10 +136,19 @@ kpi_memcpy_toio(void *dst, const void *s, unsigned long n)
// they detect an overflow. Reaching it means the driver found a bug in itself,
// and the honest thing is to say so rather than return.
void
kpi_fortify_panic(void)
kpi_fortify_panic(unsigned int reason, unsigned long avail, unsigned long size)
{
kpi_log("kpi: the driver called __fortify_panic -- it detected an "
"overflow in itself\n");
// Which check, how much it thought it had, how much it wanted, and where
// from -- the address is in the driver's own text, so subtract the load
// address logged for it and look the offset up with nm. This took a
// hardware round trip to find the last time it said nothing.
kpi_log(" reason "); kpi_lognum(reason);
kpi_log(", available "); kpi_lognum((long long)avail);
kpi_log(", wanted "); kpi_lognum((long long)size);
kpi_log(", from 0x"); kpi_loghex((unsigned long)__builtin_return_address(0), 16);
kpi_log("\n");
for (;;)
;
}