summaryrefslogtreecommitdiff
path: root/net/sctp
diff options
context:
space:
mode:
authorJakub Kicinski <kuba@kernel.org>2026-06-11 14:29:53 -0700
committerJakub Kicinski <kuba@kernel.org>2026-06-11 14:33:35 -0700
commitdad4d4b92a9b9f0edb8c66deda049da1b62f6089 (patch)
tree97101d61ab6bcfead33249c92b8d9b931758ae73 /net/sctp
parent518d8d0199538a4d6d5e51064044ece71e0c42e7 (diff)
parent22e2036479cb77df6281ebbd376ae6c330774790 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net
Cross-merge networking fixes after downstream PR (net-7.1-rc8). Conflicts: drivers/net/ethernet/wangxun/txgbe/txgbe_aml.c f67aead16e85 ("net: txgbe: rework service event handling") 57d39faed4c9 ("net: txgbe: improve functions of AML 40G devices") net/rds/info.c 512db8267b73 ("rds: mark snapshot pages dirty in rds_info_getsockopt()") 6e94eeb2a2a6 ("rds: convert to getsockopt_iter") Adjacent changes: include/net/sock.h 1ee90b77b727 ("net: guard timestamp cmsgs to real error queue skbs") f0de88303d5e ("net: make is_skb_wmem() available to modules") Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/sctp')
-rw-r--r--net/sctp/bind_addr.c11
-rw-r--r--net/sctp/input.c8
-rw-r--r--net/sctp/sm_make_chunk.c9
-rw-r--r--net/sctp/stream.c6
4 files changed, 30 insertions, 4 deletions
diff --git a/net/sctp/bind_addr.c b/net/sctp/bind_addr.c
index 75e3e61d494e..31737f144c7f 100644
--- a/net/sctp/bind_addr.c
+++ b/net/sctp/bind_addr.c
@@ -275,6 +275,16 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_addr_list,
param = (struct sctp_paramhdr *)raw_addr_list;
rawaddr = (union sctp_addr_param *)raw_addr_list;
+ if (addrs_len < sizeof(*param)) {
+ retval = -EINVAL;
+ goto out_err;
+ }
+ len = ntohs(param->length);
+ if (addrs_len < len) {
+ retval = -EINVAL;
+ goto out_err;
+ }
+
af = sctp_get_af_specific(param_type2af(param->type));
if (unlikely(!af) ||
!af->from_addr_param(&addr, rawaddr, htons(port), 0)) {
@@ -291,7 +301,6 @@ int sctp_raw_to_bind_addrs(struct sctp_bind_addr *bp, __u8 *raw_addr_list,
goto out_err;
next:
- len = ntohs(param->length);
addrs_len -= len;
raw_addr_list += len;
}
diff --git a/net/sctp/input.c b/net/sctp/input.c
index e119e460ccde..864741fae418 100644
--- a/net/sctp/input.c
+++ b/net/sctp/input.c
@@ -1204,6 +1204,14 @@ static struct sctp_association *__sctp_rcv_asconf_lookup(
/* Skip over the ADDIP header and find the Address parameter */
param = (union sctp_addr_param *)(asconf + 1);
+ /* The whole address parameter must lie within the chunk before
+ * af->from_addr_param() reads the variable-length address; otherwise a
+ * truncated trailing ASCONF chunk lets it read uninitialized bytes past
+ * the parameter.
+ */
+ if (sizeof(*asconf) + ntohs(param->p.length) > ntohs(ch->length))
+ return NULL;
+
af = sctp_get_af_specific(param_type2af(param->p.type));
if (unlikely(!af))
return NULL;
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 85264862fb6b..1741a9f33d8c 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1731,8 +1731,8 @@ struct sctp_association *sctp_unpack_cookie(
struct sk_buff *skb = chunk->skb;
struct sctp_cookie *bear_cookie;
struct sctp_chunkhdr *ch;
+ unsigned int len, chlen;
enum sctp_scope scope;
- unsigned int len;
ktime_t kt;
/* Header size is static data prior to the actual cookie, including
@@ -1761,7 +1761,12 @@ struct sctp_association *sctp_unpack_cookie(
bear_cookie = &cookie->c;
ch = (struct sctp_chunkhdr *)(bear_cookie + 1);
- if (ntohs(ch->length) > len - fixed_size)
+ chlen = ntohs(ch->length);
+ if (chlen < sizeof(struct sctp_init_chunk))
+ goto malformed;
+ if (chlen > len - fixed_size)
+ goto malformed;
+ if (bear_cookie->raw_addr_list_len > len - fixed_size - chlen)
goto malformed;
/* Verify the cookie's MAC, if cookie authentication is enabled. */
diff --git a/net/sctp/stream.c b/net/sctp/stream.c
index c2247793c88b..5c2fdedea088 100644
--- a/net/sctp/stream.c
+++ b/net/sctp/stream.c
@@ -1038,6 +1038,7 @@ struct sctp_chunk *sctp_process_strreset_resp(
stsn, rtsn, GFP_ATOMIC);
} else if (req->type == SCTP_PARAM_RESET_ADD_OUT_STREAMS) {
struct sctp_strreset_addstrm *addstrm;
+ const struct sctp_sched_ops *sched;
__u16 number;
addstrm = (struct sctp_strreset_addstrm *)req;
@@ -1048,7 +1049,10 @@ struct sctp_chunk *sctp_process_strreset_resp(
for (i = number; i < stream->outcnt; i++)
SCTP_SO(stream, i)->state = SCTP_STREAM_OPEN;
} else {
- sctp_stream_shrink_out(stream, number);
+ sched = sctp_sched_ops_from_stream(stream);
+ sched->unsched_all(stream);
+ sctp_stream_outq_migrate(stream, NULL, number);
+ sched->sched_all(stream);
stream->outcnt = number;
}