aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGleb Smirnoff <glebius@FreeBSD.org>2022-05-17 17:10:42 +0000
committerGleb Smirnoff <glebius@FreeBSD.org>2022-05-17 17:10:42 +0000
commit6890b588141a8298fc8a63700aeeea4ba36ca3f9 (patch)
tree6f9eba382ca04d6f81f5e09e8286911683864b97
parentb46667c63eb7f126a56e23af1401d98d77b912e8 (diff)
downloadsrc-6890b588141a8298fc8a63700aeeea4ba36ca3f9.tar.gz
src-6890b588141a8298fc8a63700aeeea4ba36ca3f9.zip
sockbuf: improve sbcreatecontrol()
o Constify memory pointer. Make length unsigned. o Make it never fail with M_WAITOK and assert that length is sane.
-rw-r--r--sys/kern/uipc_sockbuf.c24
-rw-r--r--sys/netinet6/ip6_input.c4
-rw-r--r--sys/sys/sockbuf.h3
3 files changed, 19 insertions, 12 deletions
diff --git a/sys/kern/uipc_sockbuf.c b/sys/kern/uipc_sockbuf.c
index 884562510e61..e3a9f92d8da0 100644
--- a/sys/kern/uipc_sockbuf.c
+++ b/sys/kern/uipc_sockbuf.c
@@ -1760,29 +1760,35 @@ sbdroprecord(struct sockbuf *sb)
* type for presentation on a socket buffer.
*/
struct mbuf *
-sbcreatecontrol(void *p, int size, int type, int level, int wait)
+sbcreatecontrol(const void *p, u_int size, int type, int level, int wait)
{
struct cmsghdr *cp;
struct mbuf *m;
MBUF_CHECKSLEEP(wait);
- if (CMSG_SPACE((u_int)size) > MCLBYTES)
- return ((struct mbuf *) NULL);
- if (CMSG_SPACE((u_int)size) > MLEN)
+
+ if (wait == M_NOWAIT) {
+ if (CMSG_SPACE(size) > MCLBYTES)
+ return (NULL);
+ } else
+ KASSERT(size <= MCLBYTES, ("%s: passed size %u > MCLBYTES",
+ __func__, size));
+
+ if (CMSG_SPACE(size) > MLEN)
m = m_getcl(wait, MT_CONTROL, 0);
else
m = m_get(wait, MT_CONTROL);
if (m == NULL)
- return ((struct mbuf *) NULL);
- cp = mtod(m, struct cmsghdr *);
- m->m_len = 0;
- KASSERT(CMSG_SPACE((u_int)size) <= M_TRAILINGSPACE(m),
+ return (NULL);
+
+ KASSERT(CMSG_SPACE(size) <= M_TRAILINGSPACE(m),
("sbcreatecontrol: short mbuf"));
/*
* Don't leave the padding between the msg header and the
* cmsg data and the padding after the cmsg data un-initialized.
*/
- bzero(cp, CMSG_SPACE((u_int)size));
+ cp = mtod(m, struct cmsghdr *);
+ bzero(cp, CMSG_SPACE(size));
if (p != NULL)
(void)memcpy(CMSG_DATA(cp), p, size);
m->m_len = CMSG_SPACE(size);
diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c
index 9835dc495f09..a9bc05f0c19c 100644
--- a/sys/netinet6/ip6_input.c
+++ b/sys/netinet6/ip6_input.c
@@ -1413,7 +1413,7 @@ ip6_savecontrol(struct inpcb *inp, struct mbuf *m, struct mbuf **mp)
*/
if (ip6->ip6_nxt == IPPROTO_HOPOPTS) {
struct ip6_hbh *hbh;
- int hbhlen;
+ u_int hbhlen;
hbh = (struct ip6_hbh *)(ip6 + 1);
hbhlen = (hbh->ip6h_len + 1) << 3;
@@ -1445,7 +1445,7 @@ ip6_savecontrol(struct inpcb *inp, struct mbuf *m, struct mbuf **mp)
*/
while (1) { /* is explicit loop prevention necessary? */
struct ip6_ext *ip6e = NULL;
- int elen;
+ u_int elen;
/*
* if it is not an extension header, don't try to
diff --git a/sys/sys/sockbuf.h b/sys/sys/sockbuf.h
index efa87b1f2378..753ebd1fbf35 100644
--- a/sys/sys/sockbuf.h
+++ b/sys/sys/sockbuf.h
@@ -158,7 +158,8 @@ 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);
struct mbuf *
- sbcreatecontrol(void *p, int size, int type, int level, int wait);
+ sbcreatecontrol(const void *p, u_int size, int type, int level,
+ int wait);
void sbdestroy(struct socket *, sb_which);
void sbdrop(struct sockbuf *sb, int len);
void sbdrop_locked(struct sockbuf *sb, int len);