mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 18:51:56 -04:00
sctp: fix ASCONF list handling
->auto_asconf_splist is per namespace and mangled by functions like
sctp_setsockopt_auto_asconf() which doesn't guarantee any serialization.
Also, the call to inet_sk_copy_descendant() was backuping
->auto_asconf_list through the copy but was not honoring
->do_auto_asconf, which could lead to list corruption if it was
different between both sockets.
This commit thus fixes the list handling by using ->addr_wq_lock
spinlock to protect the list. A special handling is done upon socket
creation and destruction for that. Error handlig on sctp_init_sock()
will never return an error after having initialized asconf, so
sctp_destroy_sock() can be called without addrq_wq_lock. The lock now
will be take on sctp_close_sock(), before locking the socket, so we
don't do it in inverse order compared to sctp_addr_wq_timeout_handler().
Instead of taking the lock on sctp_sock_migrate() for copying and
restoring the list values, it's preferred to avoid rewritting it by
implementing sctp_copy_descendant().
Issue was found with a test application that kept flipping sysctl
default_auto_asconf on and off, but one could trigger it by issuing
simultaneous setsockopt() calls on multiple sockets or by
creating/destroying sockets fast enough. This is only triggerable
locally.
Fixes: 9f7d653b67 ("sctp: Add Auto-ASCONF support (core).")
Reported-by: Ji Jianwen <[email protected]>
Suggested-by: Neil Horman <[email protected]>
Suggested-by: Hannes Frederic Sowa <[email protected]>
Acked-by: Hannes Frederic Sowa <[email protected]>
Signed-off-by: Marcelo Ricardo Leitner <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
This commit is contained in:
parent
c8d17b451a
commit
2d45a02d01
3 changed files with 37 additions and 11 deletions
|
|
@ -31,6 +31,7 @@ struct netns_sctp {
|
|||
struct list_head addr_waitq;
|
||||
struct timer_list addr_wq_timer;
|
||||
struct list_head auto_asconf_splist;
|
||||
/* Lock that protects both addr_waitq and auto_asconf_splist */
|
||||
spinlock_t addr_wq_lock;
|
||||
|
||||
/* Lock that protects the local_addr_list writers */
|
||||
|
|
|
|||
|
|
@ -223,6 +223,10 @@ struct sctp_sock {
|
|||
atomic_t pd_mode;
|
||||
/* Receive to here while partial delivery is in effect. */
|
||||
struct sk_buff_head pd_lobby;
|
||||
|
||||
/* These must be the last fields, as they will skipped on copies,
|
||||
* like on accept and peeloff operations
|
||||
*/
|
||||
struct list_head auto_asconf_list;
|
||||
int do_auto_asconf;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue