git: e187fa569047 - main - sctp: fix sctp_sendall() when an mbuf chain is provided
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 09 May 2024 14:49:51 UTC
The branch main has been updated by tuexen:
URL: https://cgit.FreeBSD.org/src/commit/?id=e187fa56904712cb4dac9e14c81c88821582aeb4
commit e187fa56904712cb4dac9e14c81c88821582aeb4
Author: Michael Tuexen <tuexen@FreeBSD.org>
AuthorDate: 2024-05-08 21:41:17 +0000
Commit: Michael Tuexen <tuexen@FreeBSD.org>
CommitDate: 2024-05-08 21:45:55 +0000
sctp: fix sctp_sendall() when an mbuf chain is provided
In this case uio is NULL, which needs to be checked and m must
be copied into the sctp_copy_all structure.
Reported by: Coverity Scan
CID: 1400449
MFC after: 3 days
---
sys/netinet/sctp_output.c | 31 ++++++++++++++++---------------
1 file changed, 16 insertions(+), 15 deletions(-)
diff --git a/sys/netinet/sctp_output.c b/sys/netinet/sctp_output.c
index e0106831f06a..c146bda95c7c 100644
--- a/sys/netinet/sctp_output.c
+++ b/sys/netinet/sctp_output.c
@@ -6911,10 +6911,20 @@ static int
sctp_sendall(struct sctp_inpcb *inp, struct uio *uio, struct mbuf *m,
struct sctp_nonpad_sndrcvinfo *srcv)
{
- int ret;
struct sctp_copy_all *ca;
+ struct mbuf *mat;
+ ssize_t sndlen;
+ int ret;
- if (uio->uio_resid > (ssize_t)SCTP_BASE_SYSCTL(sctp_sendall_limit)) {
+ if (uio != NULL) {
+ sndlen = uio->uio_resid;
+ } else {
+ sndlen = 0;
+ for (mat = m; mat; mat = SCTP_BUF_NEXT(mat)) {
+ sndlen += SCTP_BUF_LEN(mat);
+ }
+ }
+ if (sndlen > (ssize_t)SCTP_BASE_SYSCTL(sctp_sendall_limit)) {
/* You must not be larger than the limit! */
return (EMSGSIZE);
}
@@ -6926,12 +6936,10 @@ sctp_sendall(struct sctp_inpcb *inp, struct uio *uio, struct mbuf *m,
return (ENOMEM);
}
memset(ca, 0, sizeof(struct sctp_copy_all));
-
ca->inp = inp;
if (srcv != NULL) {
memcpy(&ca->sndrcv, srcv, sizeof(struct sctp_nonpad_sndrcvinfo));
}
-
/* Serialize. */
SCTP_INP_WLOCK(inp);
if ((inp->sctp_flags & SCTP_PCB_FLAGS_SND_ITERATOR_UP) != 0) {
@@ -6942,15 +6950,14 @@ sctp_sendall(struct sctp_inpcb *inp, struct uio *uio, struct mbuf *m,
}
inp->sctp_flags |= SCTP_PCB_FLAGS_SND_ITERATOR_UP;
SCTP_INP_WUNLOCK(inp);
-
/*
* take off the sendall flag, it would be bad if we failed to do
* this :-0
*/
ca->sndrcv.sinfo_flags &= ~SCTP_SENDALL;
/* get length and mbuf chain */
- if (uio) {
- ca->sndlen = uio->uio_resid;
+ ca->sndlen = sndlen;
+ if (uio != NULL) {
ca->m = sctp_copy_out_all(uio, ca->sndlen);
if (ca->m == NULL) {
SCTP_FREE(ca, SCTP_M_COPYAL);
@@ -6962,20 +6969,14 @@ sctp_sendall(struct sctp_inpcb *inp, struct uio *uio, struct mbuf *m,
return (ENOMEM);
}
} else {
- /* Gather the length of the send */
- struct mbuf *mat;
-
- ca->sndlen = 0;
- for (mat = m; mat; mat = SCTP_BUF_NEXT(mat)) {
- ca->sndlen += SCTP_BUF_LEN(mat);
- }
+ ca->m = m;
}
ret = sctp_initiate_iterator(NULL, sctp_sendall_iterator, NULL,
SCTP_PCB_ANY_FLAGS, SCTP_PCB_ANY_FEATURES,
SCTP_ASOC_ANY_STATE,
(void *)ca, 0,
sctp_sendall_completes, inp, 1);
- if (ret) {
+ if (ret != 0) {
SCTP_INP_WLOCK(inp);
inp->sctp_flags &= ~SCTP_PCB_FLAGS_SND_ITERATOR_UP;
SCTP_INP_WUNLOCK(inp);