Skip to content

Commit cc4dfb7

Browse files
congwangdavem330
authored andcommitted
rds: fix two RCU related problems
When a rds sock is bound, it is inserted into the bind_hash_table which is protected by RCU. But when releasing rds sock, after it is removed from this hash table, it is freed immediately without respecting RCU grace period. This could cause some use-after-free as reported by syzbot. Mark the rds sock with SOCK_RCU_FREE before inserting it into the bind_hash_table, so that it would be always freed after a RCU grace period. The other problem is in rds_find_bound(), the rds sock could be freed in between rhashtable_lookup_fast() and rds_sock_addref(), so we need to extend RCU read lock protection in rds_find_bound() to close this race condition. Reported-and-tested-by: [email protected] Reported-by: [email protected] Cc: Sowmini Varadhan <[email protected]> Cc: Santosh Shilimkar <[email protected]> Cc: [email protected] Signed-off-by: Cong Wang <[email protected]> Acked-by: Santosh Shilimkar <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 6ad5690 commit cc4dfb7

File tree

1 file changed

+4
-1
lines changed

1 file changed

+4
-1
lines changed

net/rds/bind.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,13 @@ struct rds_sock *rds_find_bound(const struct in6_addr *addr, __be16 port,
7676
struct rds_sock *rs;
7777

7878
__rds_create_bind_key(key, addr, port, scope_id);
79-
rs = rhashtable_lookup_fast(&bind_hash_table, key, ht_parms);
79+
rcu_read_lock();
80+
rs = rhashtable_lookup(&bind_hash_table, key, ht_parms);
8081
if (rs && !sock_flag(rds_rs_to_sk(rs), SOCK_DEAD))
8182
rds_sock_addref(rs);
8283
else
8384
rs = NULL;
85+
rcu_read_unlock();
8486

8587
rdsdebug("returning rs %p for %pI6c:%u\n", rs, addr,
8688
ntohs(port));
@@ -235,6 +237,7 @@ int rds_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
235237
goto out;
236238
}
237239

240+
sock_set_flag(sk, SOCK_RCU_FREE);
238241
ret = rds_add_bound(rs, binding_addr, &port, scope_id);
239242
if (ret)
240243
goto out;

0 commit comments

Comments
 (0)