aboutsummaryrefslogtreecommitdiff
path: root/sys/kern/kern_descrip.c
diff options
context:
space:
mode:
authorMateusz Guzik <mjg@FreeBSD.org>2020-10-05 19:38:51 +0000
committerMateusz Guzik <mjg@FreeBSD.org>2020-10-05 19:38:51 +0000
commit4e2266100dbec41e02e4d5df61173a634394456b (patch)
tree4e348b9a8c3501456eb405f8be020edaa203c7a8 /sys/kern/kern_descrip.c
parent9e9be081d8a6a3ded373db51c8bd13189c979979 (diff)
downloadsrc-4e2266100dbec41e02e4d5df61173a634394456b.tar.gz
src-4e2266100dbec41e02e4d5df61173a634394456b.zip
cache: fix pwd use-after-free in setting up fallback
Since the code exits smr section prior to calling pwd_hold, the used pwd can be freed and a new one allocated with the same address, making the comparison erroneously true. Note it is very unlikely anyone ran into it.
Notes
Notes: svn path=/head/; revision=366462
Diffstat (limited to 'sys/kern/kern_descrip.c')
-rw-r--r--sys/kern/kern_descrip.c14
1 files changed, 12 insertions, 2 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 6d67f9ce2e51..c533e714ce52 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -3344,6 +3344,17 @@ pwd_hold_filedesc(struct filedesc *fdp)
return (pwd);
}
+bool
+pwd_hold_smr(struct pwd *pwd)
+{
+
+ MPASS(pwd != NULL);
+ if (__predict_true(refcount_acquire_if_not_zero(&pwd->pwd_refcount))) {
+ return (true);
+ }
+ return (false);
+}
+
struct pwd *
pwd_hold(struct thread *td)
{
@@ -3354,8 +3365,7 @@ pwd_hold(struct thread *td)
vfs_smr_enter();
pwd = vfs_smr_entered_load(&fdp->fd_pwd);
- MPASS(pwd != NULL);
- if (__predict_true(refcount_acquire_if_not_zero(&pwd->pwd_refcount))) {
+ if (pwd_hold_smr(pwd)) {
vfs_smr_exit();
return (pwd);
}