Skip to contentSkip to conversation

nfsd: hold cl_lock in client_has_state()

PATCH In review Cen Zhang (Microsoft Security FORGE Labs) 4 participants 8 messages Aug 28 – Sep 4

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 nfsd: hold cl_lock in client_has_state()

client_has_openowners() walks clp->cl_openowners and reads so_stateids without clp->cl_lock. nfs4_put_stateowner() unhashes that openowner under cl_lock and then frees it, so a concurrent EXCHANGE_ID with mismatched creds can use-after-free the nfs4_openowner.

BUG: KASAN: slab-use-after-free in client_has_state+0x10a/0x140
  fs/nfsd/nfs4state.c:3718 client_has_openowners()
  nfsd4_exchange_id
  nfsd4_proc_compound
  nfsd_dispatch
  svc_process

Take clp->cl_lock while client_has_state() walks the openowner list.

Fixes 4eaea1342507 ("nfsd: improve client_has_state to check for unused openowners")
---
 fs/nfsd/nfs4state.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)
fs/nfsd/nfs4state.c +9 -3
index 18e17232cf94..8d7a4c2eadbe 100644
@@ -4216,12 +4216,18 @@ nfsd4_set_ex_flags(struct nfs4_client *new, struct nfsd4_exchange_id *clid)
 static bool client_has_openowners(struct nfs4_client *clp)
 {
 	struct nfs4_openowner *oo;
+	bool found = false;
 
+	spin_lock(&clp->cl_lock);
 	list_for_each_entry(oo, &clp->cl_openowners, oo_perclient) {
-		if (!list_empty(&oo->oo_owner.so_stateids))
-			return true;
+		if (!list_empty(&oo->oo_owner.so_stateids)) {
+			found = true;
+			break;
+		}
 	}
-	return false;
+	spin_unlock(&clp->cl_lock);
+
+	return found;
 }
 
 static bool client_has_state(struct nfs4_client *clp)

base-commit: 1b78070aaef63512688aebfbc82365ef9d6660f1

Signature · 1 line
2.55.0
maintainer
#1 lore raw
Quoted 12 lines · Cen Zhang (Microsoft Security FORGE Labs)

client_has_openowners() walks clp->cl_openowners and reads so_stateids without clp->cl_lock. nfs4_put_stateowner() unhashes that openowner under cl_lock and then frees it, so a concurrent EXCHANGE_ID with mismatched creds can use-after-free the nfs4_openowner.

BUG: KASAN: slab-use-after-free in client_has_state+0x10a/0x140
  fs/nfsd/nfs4state.c:3718 client_has_openowners()
  nfsd4_exchange_id
  nfsd4_proc_compound
  nfsd_dispatch
  svc_process
Quoted 7 lines

Take clp->cl_lock while client_has_state() walks the openowner list.

Fixes 4eaea1342507 ("nfsd: improve client_has_state to check for unused openowners")

Please use your microsoft.com email address, and not a random gmail.com address. It's kind of odd that Microsoft would have to rely on Google to send kernel patches :)

thanks,

greg k-h

#2 lore raw
Quoted 2 lines

Please use your microsoft.com email address, and not a random gmail.com address.

Sorry for making you raise this again. I will hold off on new patch submissions until my approved Microsoft email address is available, which should be soon.

Thanks,
Cen

maintainer
#3 lore raw
In reply to Greg KH
Quoted 22 lines · Greg KH
Quoted 12 lines · Cen Zhang (Microsoft Security FORGE Labs)

client_has_openowners() walks clp->cl_openowners and reads so_stateids without clp->cl_lock. nfs4_put_stateowner() unhashes that openowner under cl_lock and then frees it, so a concurrent EXCHANGE_ID with mismatched creds can use-after-free the nfs4_openowner.

BUG: KASAN: slab-use-after-free in client_has_state+0x10a/0x140
  fs/nfsd/nfs4state.c:3718 client_has_openowners()
  nfsd4_exchange_id
  nfsd4_proc_compound
  nfsd_dispatch
  svc_process
Quoted 7 lines

Take clp->cl_lock while client_has_state() walks the openowner list.

Fixes 4eaea1342507 ("nfsd: improve client_has_state to check for unused openowners")
Quoted 3 lines

Please use your microsoft.com email address, and not a random gmail.com address. It's kind of odd that Microsoft would have to rely on Google to send kernel patches :)

Greg, would you prefer that I hold off on applying this to nfsd-testing until Cen can post this one again?

Signature · 1 line
Chuck Lever
#4 lore raw
Quoted 25 lines · Chuck Lever
Quoted 22 lines · Greg KH
Quoted 19 lines · Cen Zhang (Microsoft Security FORGE Labs)

client_has_openowners() walks clp->cl_openowners and reads so_stateids without clp->cl_lock. nfs4_put_stateowner() unhashes that openowner under cl_lock and then frees it, so a concurrent EXCHANGE_ID with mismatched creds can use-after-free the nfs4_openowner.

BUG: KASAN: slab-use-after-free in client_has_state+0x10a/0x140
  fs/nfsd/nfs4state.c:3718 client_has_openowners()
  nfsd4_exchange_id
  nfsd4_proc_compound
  nfsd_dispatch
  svc_process

Take clp->cl_lock while client_has_state() walks the openowner list.

Fixes 4eaea1342507 ("nfsd: improve client_has_state to check for unused openowners")
Quoted 6 lines
Quoted 3 lines

Please use your microsoft.com email address, and not a random gmail.com address. It's kind of odd that Microsoft would have to rely on Google to send kernel patches :)

Greg, would you prefer that I hold off on applying this to nfsd-testing until Cen can post this one again?

That's your call.

#5 lore raw
In reply to Greg KH
Quoted 3 lines · Greg KH

Please use your microsoft.com email address, and not a random gmail.com address. It's kind of odd that Microsoft would have to rely on Google to send kernel patches :)

Thanks for pointing this out. I now have [email protected] set up and will use it for future kernel submissions.

Chuck, since the patch is already in nfsd-testing, please let me know if I should send a v2 from this address to update the author email.

Thanks,
Cen

maintainer
#6 lore raw
Quoted 10 lines · Cen Zhang (Microsoft Security FORGE Labs)
Quoted 3 lines · Greg KH

Please use your microsoft.com email address, and not a random gmail.com address. It's kind of odd that Microsoft would have to rely on Google to send kernel patches :)

Thanks for pointing this out. I now have [email protected] set up and will use it for future kernel submissions.

Chuck, since the patch is already in nfsd-testing, please let me know if I should send a v2 from this address to update the author email.

I don't see a need to resend, but I'm sure someone will explain it to me if I'm incorrect. :-)

Signature · 1 line
Chuck Lever (Come to NFS bake-a-thon! https://nfsv4bat.org)
maintainer
#7 lore raw
In reply to Cen Zhang (Microsoft Security FORGE Labs)
Quoted 5 lines · Cen Zhang (Microsoft Security FORGE Labs)

client_has_openowners() walks clp->cl_openowners and reads so_stateids without clp->cl_lock. nfs4_put_stateowner() unhashes that openowner under cl_lock and then frees it, so a concurrent EXCHANGE_ID with mismatched creds can use-after-free the nfs4_openowner.

Quoted 8 lines
BUG: KASAN: slab-use-after-free in client_has_state+0x10a/0x140
  fs/nfsd/nfs4state.c:3718 client_has_openowners()
  nfsd4_exchange_id
  nfsd4_proc_compound
  nfsd_dispatch
  svc_process

[...]

Applied to nfsd-testing, thanks!

[1/1] nfsd: hold cl_lock in client_has_state()

      commit: 6882aca9f9cabfaec5ea23d1512f345fbd288b65

--
Chuck Lever