sbappendcontrol() needs to avoid clearing M_NOTREADY on data mbufs.
If LOCAL_CREDS is set on a unix socket and sendfile() is called, sendfile will call uipc_send(PRUS_NOTREADY), prepending a control message to the M_NOTREADY mbufs. uipc_send() then calls sbappendcontrol() instead of sbappend(), and sbappendcontrol() would erroneously clear M_NOTREADY. Pass send flags to sbappendcontrol(), like we do for sbappend(), to preserve M_READY when necessary. Reported by: syzkaller MFC after: 2 weeks Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D24333
This commit is contained in:
parent
a50b1900a0
commit
25f4ddfb2b
@ -1101,11 +1101,11 @@ sbappendaddr(struct sockbuf *sb, const struct sockaddr *asa,
|
||||
|
||||
void
|
||||
sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0,
|
||||
struct mbuf *control)
|
||||
struct mbuf *control, int flags)
|
||||
{
|
||||
struct mbuf *m, *mlast;
|
||||
|
||||
m_clrprotoflags(m0);
|
||||
sbm_clrprotoflags(m0, flags);
|
||||
m_last(control)->m_next = m0;
|
||||
|
||||
SBLASTRECORDCHK(sb);
|
||||
@ -1123,11 +1123,12 @@ sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0,
|
||||
}
|
||||
|
||||
void
|
||||
sbappendcontrol(struct sockbuf *sb, struct mbuf *m0, struct mbuf *control)
|
||||
sbappendcontrol(struct sockbuf *sb, struct mbuf *m0, struct mbuf *control,
|
||||
int flags)
|
||||
{
|
||||
|
||||
SOCKBUF_LOCK(sb);
|
||||
sbappendcontrol_locked(sb, m0, control);
|
||||
sbappendcontrol_locked(sb, m0, control, flags);
|
||||
SOCKBUF_UNLOCK(sb);
|
||||
}
|
||||
|
||||
|
@ -1192,7 +1192,7 @@ uipc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
|
||||
case SOCK_STREAM:
|
||||
if (control != NULL) {
|
||||
sbappendcontrol_locked(&so2->so_rcv, m,
|
||||
control);
|
||||
control, flags);
|
||||
control = NULL;
|
||||
} else
|
||||
sbappend_locked(&so2->so_rcv, m, flags);
|
||||
|
@ -145,9 +145,9 @@ int sbappendaddr_locked(struct sockbuf *sb, const struct sockaddr *asa,
|
||||
int sbappendaddr_nospacecheck_locked(struct sockbuf *sb,
|
||||
const struct sockaddr *asa, struct mbuf *m0, struct mbuf *control);
|
||||
void sbappendcontrol(struct sockbuf *sb, struct mbuf *m0,
|
||||
struct mbuf *control);
|
||||
struct mbuf *control, int flags);
|
||||
void sbappendcontrol_locked(struct sockbuf *sb, struct mbuf *m0,
|
||||
struct mbuf *control);
|
||||
struct mbuf *control, int flags);
|
||||
void sbappendrecord(struct sockbuf *sb, struct mbuf *m0);
|
||||
void sbappendrecord_locked(struct sockbuf *sb, struct mbuf *m0);
|
||||
void sbcompress(struct sockbuf *sb, struct mbuf *m, struct mbuf *n);
|
||||
|
Loading…
x
Reference in New Issue
Block a user