aboutsummaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorVlad Yasevich <vladislav.yasevich@hp.com>2007-09-16 19:02:12 -0400
committerDavid S. Miller <davem@davemloft.net>2007-09-16 19:02:12 -0400
commit293035479942400a7fe8e4f72465d4e4e466b91a (patch)
treeaf9890403a554b4cf8389a9116080a0d1aa187fb /include
parentddeee3ce7fbf0e800f2a26a76d6018b42b337cc2 (diff)
[SCTP]: Add RCU synchronization around sctp_localaddr_list
sctp_localaddr_list is modified dynamically via NETDEV_UP and NETDEV_DOWN events, but there is not synchronization between writer (even handler) and readers. As a result, the readers can access an entry that has been freed and crash the sytem. Signed-off-by: Vlad Yasevich <vladislav.yasevich@hp.com> Acked-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com> Acked-by: Sridhar Samdurala <sri@us.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include')
-rw-r--r--include/net/sctp/sctp.h1
-rw-r--r--include/net/sctp/structs.h6
2 files changed, 7 insertions, 0 deletions
diff --git a/include/net/sctp/sctp.h b/include/net/sctp/sctp.h
index d529045c1679..c9cc00c85782 100644
--- a/include/net/sctp/sctp.h
+++ b/include/net/sctp/sctp.h
@@ -123,6 +123,7 @@
123 * sctp/protocol.c 123 * sctp/protocol.c
124 */ 124 */
125extern struct sock *sctp_get_ctl_sock(void); 125extern struct sock *sctp_get_ctl_sock(void);
126extern void sctp_local_addr_free(struct rcu_head *head);
126extern int sctp_copy_local_addr_list(struct sctp_bind_addr *, 127extern int sctp_copy_local_addr_list(struct sctp_bind_addr *,
127 sctp_scope_t, gfp_t gfp, 128 sctp_scope_t, gfp_t gfp,
128 int flags); 129 int flags);
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index c0d5848c33dc..a89e36197afb 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -207,6 +207,9 @@ extern struct sctp_globals {
207 * It is a list of sctp_sockaddr_entry. 207 * It is a list of sctp_sockaddr_entry.
208 */ 208 */
209 struct list_head local_addr_list; 209 struct list_head local_addr_list;
210
211 /* Lock that protects the local_addr_list writers */
212 spinlock_t addr_list_lock;
210 213
211 /* Flag to indicate if addip is enabled. */ 214 /* Flag to indicate if addip is enabled. */
212 int addip_enable; 215 int addip_enable;
@@ -242,6 +245,7 @@ extern struct sctp_globals {
242#define sctp_port_alloc_lock (sctp_globals.port_alloc_lock) 245#define sctp_port_alloc_lock (sctp_globals.port_alloc_lock)
243#define sctp_port_hashtable (sctp_globals.port_hashtable) 246#define sctp_port_hashtable (sctp_globals.port_hashtable)
244#define sctp_local_addr_list (sctp_globals.local_addr_list) 247#define sctp_local_addr_list (sctp_globals.local_addr_list)
248#define sctp_local_addr_lock (sctp_globals.addr_list_lock)
245#define sctp_addip_enable (sctp_globals.addip_enable) 249#define sctp_addip_enable (sctp_globals.addip_enable)
246#define sctp_prsctp_enable (sctp_globals.prsctp_enable) 250#define sctp_prsctp_enable (sctp_globals.prsctp_enable)
247 251
@@ -737,8 +741,10 @@ const union sctp_addr *sctp_source(const struct sctp_chunk *chunk);
737/* This is a structure for holding either an IPv6 or an IPv4 address. */ 741/* This is a structure for holding either an IPv6 or an IPv4 address. */
738struct sctp_sockaddr_entry { 742struct sctp_sockaddr_entry {
739 struct list_head list; 743 struct list_head list;
744 struct rcu_head rcu;
740 union sctp_addr a; 745 union sctp_addr a;
741 __u8 use_as_src; 746 __u8 use_as_src;
747 __u8 valid;
742}; 748};
743 749
744typedef struct sctp_chunk *(sctp_packet_phandler_t)(struct sctp_association *); 750typedef struct sctp_chunk *(sctp_packet_phandler_t)(struct sctp_association *);