diff options
author | Gleb Smirnoff <glebius@FreeBSD.org> | 2022-05-17 17:10:42 +0000 |
---|---|---|
committer | Gleb Smirnoff <glebius@FreeBSD.org> | 2022-05-17 17:10:42 +0000 |
commit | 6890b588141a8298fc8a63700aeeea4ba36ca3f9 (patch) | |
tree | 6f9eba382ca04d6f81f5e09e8286911683864b97 | |
parent | b46667c63eb7f126a56e23af1401d98d77b912e8 (diff) | |
download | src-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.c | 24 | ||||
-rw-r--r-- | sys/netinet6/ip6_input.c | 4 | ||||
-rw-r--r-- | sys/sys/sockbuf.h | 3 |
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); |