Skip site navigation (1)Skip section navigation (2)
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>