Netlink datagrams can be measured, credentials name their sender

Epiphany's main thread spun at 100% on GLib's network monitor. GLib
sizes each netlink datagram with recvmsg(MSG_PEEK|MSG_TRUNC) and no
buffer; that answered 0, GLib read 0 bytes, the answer stayed queued and
poll() said readable again, forever. recvmsg on netlink now peeks
without consuming and with MSG_TRUNC returns what is waiting. A drained
netlink socket also no longer reports hangup -- it has no peer, and
sock_hup took that for a closed one.

SCM_CREDENTIALS under SO_PASSCRED named the process that created the far
end, not the one that wrote to it. For a socketpair those differ: WebKit
makes the pair, hands one end to a child, and learns the child's pid
from the credentials on its first byte. Each end now records its last
writer.

LDLS: napi_consume_skb frees the skb. r8169 frees every sent frame with
it, and as a stub it leaked one per frame until the DMA heap ran out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
Nexoniarz 2026-10-25 14:58:14 +01:00
commit 3676036762
5 changed files with 120 additions and 2 deletions

View file

@ -839,6 +839,7 @@ static void *kpi_leds_list[2] = { kpi_leds_list, kpi_leds_list };
extern int kpi_queue_delayed_work_on(int cpu, void *q, void *dwork, unsigned long delay);
extern int kpi_cancel_work_sync(void *work);
extern void kpi_kfree_skb(void *skb);
const struct kpi_sym kpi_base_table[] = {
// printing, formatted
@ -945,6 +946,10 @@ const struct kpi_sym kpi_base_table[] = {
{ "crc32_le", (void *)kpi_crc32_le },
{ "get_random_bytes", (void *)kpi_get_random_bytes },
{ "__skb_pad", (void *)kpi_skb_pad },
// r8169 frees every transmitted skb this way; a stub leaked one per frame
// until the DMA heap ran out. The budget argument changes only which cache
// Linux returns it to.
{ "napi_consume_skb", (void *)kpi_kfree_skb },
// data
{ "link_mode_params", (void *)kpi_link_mode_params },