]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
sctp: Hold sock lock while iterating over address list
authorStefan Wiehler <stefan.wiehler@nokia.com>
Tue, 28 Oct 2025 16:12:28 +0000 (17:12 +0100)
committerJakub Kicinski <kuba@kernel.org>
Tue, 4 Nov 2025 01:09:36 +0000 (17:09 -0800)
Move address list traversal in inet_assoc_attr_size() under the sock
lock to avoid holding the RCU read lock.

Suggested-by: Xin Long <lucien.xin@gmail.com>
Fixes: 8f840e47f190 ("sctp: add the sctp_diag.c file")
Signed-off-by: Stefan Wiehler <stefan.wiehler@nokia.com>
Acked-by: Xin Long <lucien.xin@gmail.com>
Link: https://patch.msgid.link/20251028161506.3294376-4-stefan.wiehler@nokia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/sctp/diag.c

index 5d64dd99ca9a36554c57c5d6a932193e757eb45b..2afb376299fe47c214216476f5a99adbe98cc158 100644 (file)
@@ -230,14 +230,15 @@ struct sctp_comm_param {
        bool net_admin;
 };
 
-static size_t inet_assoc_attr_size(struct sctp_association *asoc)
+static size_t inet_assoc_attr_size(struct sock *sk,
+                                  struct sctp_association *asoc)
 {
        int addrlen = sizeof(struct sockaddr_storage);
        int addrcnt = 0;
        struct sctp_sockaddr_entry *laddr;
 
        list_for_each_entry_rcu(laddr, &asoc->base.bind_addr.address_list,
-                               list)
+                               list, lockdep_sock_is_held(sk))
                addrcnt++;
 
        return    nla_total_size(sizeof(struct sctp_info))
@@ -263,11 +264,14 @@ static int sctp_sock_dump_one(struct sctp_endpoint *ep, struct sctp_transport *t
        if (err)
                return err;
 
-       rep = nlmsg_new(inet_assoc_attr_size(assoc), GFP_KERNEL);
-       if (!rep)
+       lock_sock(sk);
+
+       rep = nlmsg_new(inet_assoc_attr_size(sk, assoc), GFP_KERNEL);
+       if (!rep) {
+               release_sock(sk);
                return -ENOMEM;
+       }
 
-       lock_sock(sk);
        if (ep != assoc->ep) {
                err = -EAGAIN;
                goto out;