sunrpc: only free unix grouplist after RCU settles
[ Upstream commit 5085e41f9e83a1bec51da1f20b54f2ec3a13a3fe ]
While the unix_gid object is rcu-freed, the group_info list that it
contains is not. Ensure that we only put the group list reference once
we are really freeing the unix_gid object.
Reported-by: Zhi Li <yieli@redhat.com>
Link: https://bugzilla.redhat.com/show_bug.cgi?id=2183056
Signed-off-by: Jeff Layton <jlayton@kernel.org>
Fixes: fd5d2f7826
("SUNRPC: Make server side AUTH_UNIX use lockless lookups")
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
1627119153
commit
3686380d9d
@ -428,14 +428,23 @@ static int unix_gid_hash(kuid_t uid)
|
||||
return hash_long(from_kuid(&init_user_ns, uid), GID_HASHBITS);
|
||||
}
|
||||
|
||||
static void unix_gid_free(struct rcu_head *rcu)
|
||||
{
|
||||
struct unix_gid *ug = container_of(rcu, struct unix_gid, rcu);
|
||||
struct cache_head *item = &ug->h;
|
||||
|
||||
if (test_bit(CACHE_VALID, &item->flags) &&
|
||||
!test_bit(CACHE_NEGATIVE, &item->flags))
|
||||
put_group_info(ug->gi);
|
||||
kfree(ug);
|
||||
}
|
||||
|
||||
static void unix_gid_put(struct kref *kref)
|
||||
{
|
||||
struct cache_head *item = container_of(kref, struct cache_head, ref);
|
||||
struct unix_gid *ug = container_of(item, struct unix_gid, h);
|
||||
if (test_bit(CACHE_VALID, &item->flags) &&
|
||||
!test_bit(CACHE_NEGATIVE, &item->flags))
|
||||
put_group_info(ug->gi);
|
||||
kfree_rcu(ug, rcu);
|
||||
|
||||
call_rcu(&ug->rcu, unix_gid_free);
|
||||
}
|
||||
|
||||
static int unix_gid_match(struct cache_head *corig, struct cache_head *cnew)
|
||||
|
Loading…
Reference in New Issue
Block a user