Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sctp: Hold sock lock while iterating over address list

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>

authored by

Stefan Wiehler and committed by
Jakub Kicinski
f1fc2011 95aef86a

+10 -6
+10 -6
net/sctp/diag.c
··· 230 230 bool net_admin; 231 231 }; 232 232 233 - static size_t inet_assoc_attr_size(struct sctp_association *asoc) 233 + static size_t inet_assoc_attr_size(struct sock *sk, 234 + struct sctp_association *asoc) 234 235 { 235 236 int addrlen = sizeof(struct sockaddr_storage); 236 237 int addrcnt = 0; 237 238 struct sctp_sockaddr_entry *laddr; 238 239 239 240 list_for_each_entry_rcu(laddr, &asoc->base.bind_addr.address_list, 240 - list) 241 + list, lockdep_sock_is_held(sk)) 241 242 addrcnt++; 242 243 243 244 return nla_total_size(sizeof(struct sctp_info)) ··· 264 263 if (err) 265 264 return err; 266 265 267 - rep = nlmsg_new(inet_assoc_attr_size(assoc), GFP_KERNEL); 268 - if (!rep) 269 - return -ENOMEM; 270 - 271 266 lock_sock(sk); 267 + 268 + rep = nlmsg_new(inet_assoc_attr_size(sk, assoc), GFP_KERNEL); 269 + if (!rep) { 270 + release_sock(sk); 271 + return -ENOMEM; 272 + } 273 + 272 274 if (ep != assoc->ep) { 273 275 err = -EAGAIN; 274 276 goto out;