Date: Fri, 20 Jul 2018 21:26:00 +0000 From: bugzilla-noreply@freebsd.org To: net@FreeBSD.org Subject: [Bug 181741] [kernel] [patch] Packet loss when 'control' messages are present with large data (sendmsg(2)) Message-ID: <bug-181741-7501-FLTd6dDBku@https.bugs.freebsd.org/bugzilla/> In-Reply-To: <bug-181741-7501@https.bugs.freebsd.org/bugzilla/> References: <bug-181741-7501@https.bugs.freebsd.org/bugzilla/>
next in thread | previous in thread | raw e-mail | index | archive | help
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=3D181741 Jilles Tjoelker <jilles@FreeBSD.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jilles@FreeBSD.org --- Comment #15 from Jilles Tjoelker <jilles@FreeBSD.org> --- I consider the issue brought up in comments 11 and 12 a blocker. The patch "[PATCH 3/4] uipc_finalizecontrol: read-lock the unp link" introd= uces a change not mentioned in the commit message: datagram sockets always behav= e as if the LOCAL_CREDS socket option (UNP_WANTCRED flag in the kernel) is set on them. That change seems a bad idea to me. Apart from the general problems with sending unsolicited control messages (full buffers, code that examines only= the first control message if only one is expected), the specifics of SCM_CREDS = make this even more dangerous. A strange thing about SCM_CREDS is that there are= two flavours of it: one containing a struct cmsgcred, generated when the sender explicitly attaches an SCM_CREDS message, and one containing a struct sockc= red, generated under certain conditions when the receiver has enabled the LOCAL_CREDS socket option. If a struct sockcred is attached, a struct cmsgc= red (if any) is removed. The two flavours have incompatible fields, but are not reliably distinguishable in the general case (if the application programmer even knows about this problem). Therefore, behaving as if LOCAL_CREDS is set when it is not may cause applications to receive a struct sockcred and interpret it as a struct cmsgcred. For example, an application trying to read cmcred_uid for the real UID will get the effective UID from sc_euid. This is likely to allow an easy attack since a plain write(2) from a setuid root program (such as an error message) will have the struct sockcred attached to it. The patchset does seem to fix the bug that adding a struct sockcred for LOCAL_CREDS silently does nothing if m_get() or m_getcl() with M_NOWAIT fai= ls, possibly leaving a struct cmsgcred from the sender. The patch "[PATCH 3/4] uipc_finalizecontrol: read-lock the unp link" also a= dds a comment about a bug that UNP_WANTCRED may be cleared by a failing send, so that no struct sockcred is ever sent on the connection. Since this only aff= ects stream and seqpacket sockets, I think it is best fixed on the application s= ide, by using getpeereid(3) or LOCAL_PEERCRED instead of LOCAL_CREDS; this also simplifies the application code and makes the credentials more reliable (si= nce they are from connect(2)/listen(2) time instead of from the write). Related, if UNP_WANTCRED is cleared then struct cmsgcred from the sender wi= ll get through, which might lead to a struct cmsgcred being interpreted as a struct sockcred. --=20 You are receiving this mail because: You are the assignee for the bug.=
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?bug-181741-7501-FLTd6dDBku>