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:
parent
4ad49ed5f2
commit
3676036762
5 changed files with 120 additions and 2 deletions
|
|
@ -533,6 +533,10 @@ int sockname_inet(struct socket*, int peer, uint *addr, ushort *port
|
|||
#define SOCK_ABSTRACT_DEV 0xFFFFFFFFu // no filesystem has it; see unix.c
|
||||
int sockreadable(struct socket*);
|
||||
int sock_hup(struct socket*);
|
||||
uint socknl_pending(struct socket*);
|
||||
int sock_sendercred(struct socket*, int*, uint*, uint*);
|
||||
int socknl_copy(struct socket*, uint, char*, int);
|
||||
void socknl_take(struct socket*, uint);
|
||||
int sock_shutdown(struct socket*, int how);
|
||||
int sockpair(struct socket **a, struct socket **b);
|
||||
const char* sockname(struct socket*);
|
||||
|
|
|
|||
|
|
@ -362,6 +362,13 @@ struct socket {
|
|||
// the listener -- which is what Linux records too.
|
||||
int cred_pid;
|
||||
uint cred_uid, cred_gid;
|
||||
|
||||
// Who last wrote at this end, for SCM_CREDENTIALS on the other. Not the
|
||||
// same thing as cred_*: one end of a socketpair is made by the parent and
|
||||
// written by the child it is handed to, and WebKit learns its children's
|
||||
// pids from exactly that. 0 until the first write.
|
||||
int tx_pid;
|
||||
uint tx_uid, tx_gid;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in a new issue