Author: tuexen
Date: Wed May  6 22:05:29 2020
New Revision: 360707
URL: https://svnweb.freebsd.org/changeset/base/360707

Log:
  MFC r349999: Honor MSG_EOR and MSG_EOF in sendmsg() for SCTP sockets
  
  Add support for MSG_EOR and MSG_EOF in sendmsg() for SCTP.
  This is an FreeBSD extension, not covered by Posix.
  This issue was found by running syzkaller.

Modified:
  stable/11/sys/netinet/sctp_output.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/netinet/sctp_output.c
==============================================================================
--- stable/11/sys/netinet/sctp_output.c Wed May  6 22:02:01 2020        
(r360706)
+++ stable/11/sys/netinet/sctp_output.c Wed May  6 22:05:29 2020        
(r360707)
@@ -12644,6 +12644,12 @@ sctp_lower_sosend(struct socket *so,
                sinfo_flags = inp->def_send.sinfo_flags;
                sinfo_assoc_id = inp->def_send.sinfo_assoc_id;
        }
+       if (flags & MSG_EOR) {
+               sinfo_flags |= SCTP_EOR;
+       }
+       if (flags & MSG_EOF) {
+               sinfo_flags |= SCTP_EOF;
+       }
        if (sinfo_flags & SCTP_SENDALL) {
                /* its a sendall */
                error = sctp_sendall(inp, uio, top, srcv);
@@ -12809,9 +12815,17 @@ sctp_lower_sosend(struct socket *so,
                }
        } else
                asoc = &stcb->asoc;
-       if (srcv == NULL)
+       if (srcv == NULL) {
                srcv = (struct sctp_sndrcvinfo *)&asoc->def_send;
-       if (srcv->sinfo_flags & SCTP_ADDR_OVER) {
+               sinfo_flags = srcv->sinfo_flags;
+               if (flags & MSG_EOR) {
+                       sinfo_flags |= SCTP_EOR;
+               }
+               if (flags & MSG_EOF) {
+                       sinfo_flags |= SCTP_EOF;
+               }
+       }
+       if (sinfo_flags & SCTP_ADDR_OVER) {
                if (addr)
                        net = sctp_findnet(stcb, addr);
                else
@@ -12918,7 +12932,7 @@ sctp_lower_sosend(struct socket *so,
            (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_RECEIVED) ||
            (SCTP_GET_STATE(stcb) == SCTP_STATE_SHUTDOWN_ACK_SENT) ||
            (asoc->state & SCTP_STATE_SHUTDOWN_PENDING)) {
-               if (srcv->sinfo_flags & SCTP_ABORT) {
+               if (sinfo_flags & SCTP_ABORT) {
                        ;
                } else {
                        SCTP_LTRACE_ERR_RET(NULL, stcb, NULL, 
SCTP_FROM_SCTP_OUTPUT, ECONNRESET);
@@ -12931,7 +12945,7 @@ sctp_lower_sosend(struct socket *so,
                p->td_ru.ru_msgsnd++;
        }
        /* Are we aborting? */
-       if (srcv->sinfo_flags & SCTP_ABORT) {
+       if (sinfo_flags & SCTP_ABORT) {
                struct mbuf *mm;
                ssize_t tot_demand, tot_out = 0, max_out;
 
@@ -13135,7 +13149,7 @@ skip_preblock:
         * case NOTE: uio will be null when top/mbuf is passed
         */
        if (sndlen == 0) {
-               if (srcv->sinfo_flags & SCTP_EOF) {
+               if (sinfo_flags & SCTP_EOF) {
                        got_all_of_the_send = 1;
                        goto dataless_eof;
                } else {
@@ -13184,7 +13198,7 @@ skip_preblock:
                        }
                        sctp_snd_sb_alloc(stcb, sp->length);
                        atomic_add_int(&asoc->stream_queue_cnt, 1);
-                       if (srcv->sinfo_flags & SCTP_UNORDERED) {
+                       if (sinfo_flags & SCTP_UNORDERED) {
                                SCTP_STAT_INCR(sctps_sends_with_unord);
                        }
                        TAILQ_INSERT_TAIL(&strm->outqueue, sp, next);
@@ -13259,15 +13273,15 @@ skip_preblock:
                                sctp_snd_sb_alloc(stcb, sndout);
                                atomic_add_int(&sp->length, sndout);
                                len += sndout;
-                               if (srcv->sinfo_flags & SCTP_SACK_IMMEDIATELY) {
+                               if (sinfo_flags & SCTP_SACK_IMMEDIATELY) {
                                        sp->sinfo_flags |= 
SCTP_SACK_IMMEDIATELY;
                                }
 
                                /* Did we reach EOR? */
                                if ((uio->uio_resid == 0) &&
                                    ((user_marks_eor == 0) ||
-                                   (srcv->sinfo_flags & SCTP_EOF) ||
-                                   (user_marks_eor && (srcv->sinfo_flags & 
SCTP_EOR)))) {
+                                   (sinfo_flags & SCTP_EOF) ||
+                                   (user_marks_eor && (sinfo_flags & 
SCTP_EOR)))) {
                                        sp->msg_is_complete = 1;
                                } else {
                                        sp->msg_is_complete = 0;
@@ -13469,7 +13483,7 @@ skip_preblock:
                /* We send in a 0, since we do NOT have any locks */
                error = sctp_msg_append(stcb, net, top, srcv, 0);
                top = NULL;
-               if (srcv->sinfo_flags & SCTP_EOF) {
+               if (sinfo_flags & SCTP_EOF) {
                        /*
                         * This should only happen for Panda for the mbuf
                         * send case, which does NOT yet support EEOR mode.
@@ -13484,7 +13498,7 @@ skip_preblock:
        }
 dataless_eof:
        /* EOF thing ? */
-       if ((srcv->sinfo_flags & SCTP_EOF) &&
+       if ((sinfo_flags & SCTP_EOF) &&
            (got_all_of_the_send == 1)) {
                SCTP_STAT_INCR(sctps_sends_with_eof);
                error = 0;
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to