forked from mirrors/linux
		
	sctp: hold transport before we access t->asoc in sctp proc
Previously, before rhashtable, /proc assoc listing was done by read-locking the entire hash entry and dumping all assocs at once, so we were sure that the assoc wasn't freed because it wouldn't be possible to remove it from the hash meanwhile. Now we use rhashtable to list transports, and dump entries one by one. That is, now we have to check if the assoc is still a good one, as the transport we got may be being freed. Signed-off-by: Xin Long <lucien.xin@gmail.com> Reviewed-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									1eed677933
								
							
						
					
					
						commit
						fba4c330c5
					
				
					 1 changed files with 8 additions and 0 deletions
				
			
		|  | @ -380,6 +380,8 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	transport = (struct sctp_transport *)v; | 	transport = (struct sctp_transport *)v; | ||||||
|  | 	if (!sctp_transport_hold(transport)) | ||||||
|  | 		return 0; | ||||||
| 	assoc = transport->asoc; | 	assoc = transport->asoc; | ||||||
| 	epb = &assoc->base; | 	epb = &assoc->base; | ||||||
| 	sk = epb->sk; | 	sk = epb->sk; | ||||||
|  | @ -412,6 +414,8 @@ static int sctp_assocs_seq_show(struct seq_file *seq, void *v) | ||||||
| 		sk->sk_rcvbuf); | 		sk->sk_rcvbuf); | ||||||
| 	seq_printf(seq, "\n"); | 	seq_printf(seq, "\n"); | ||||||
| 
 | 
 | ||||||
|  | 	sctp_transport_put(transport); | ||||||
|  | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -489,6 +493,8 @@ static int sctp_remaddr_seq_show(struct seq_file *seq, void *v) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	tsp = (struct sctp_transport *)v; | 	tsp = (struct sctp_transport *)v; | ||||||
|  | 	if (!sctp_transport_hold(tsp)) | ||||||
|  | 		return 0; | ||||||
| 	assoc = tsp->asoc; | 	assoc = tsp->asoc; | ||||||
| 
 | 
 | ||||||
| 	list_for_each_entry_rcu(tsp, &assoc->peer.transport_addr_list, | 	list_for_each_entry_rcu(tsp, &assoc->peer.transport_addr_list, | ||||||
|  | @ -544,6 +550,8 @@ static int sctp_remaddr_seq_show(struct seq_file *seq, void *v) | ||||||
| 		seq_printf(seq, "\n"); | 		seq_printf(seq, "\n"); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	sctp_transport_put(tsp); | ||||||
|  | 
 | ||||||
| 	return 0; | 	return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Xin Long
						Xin Long