aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2026-07-06 12:51:11 +0000
committerMark Johnston <markj@FreeBSD.org>2026-07-06 12:51:11 +0000
commit38dd686b9336e2de5deadc5f8cb5e46a845b0dd9 (patch)
tree11ca1cad200a191065613b583d9c5d05d830bcd3
parent92dfe30ba254b50a74e14f33ad1d2a0c03393960 (diff)
jaildesc: Publish the new fd only after the jaildesc is initialized
jaildesc_alloc() finishes initializing the file structure only after it is made visible from the file descriptor table via finit(). In that window, other threads could try to perform operations on the descriptor and thus access an incompletely initialized jaildesc. Defer the finit() call until locks are initialized. While here, simplify the error path for falloc_caps(). Reported by: Yuxiang Yang, Yizhou Zhao, Ao Wang, Xuewei Feng, Qi Li, and Ke Xu from Tsinghua University using GLM-5.2 from Z.ai Reviewed by: jamie MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D58049
-rw-r--r--sys/kern/kern_jaildesc.c10
1 files changed, 4 insertions, 6 deletions
diff --git a/sys/kern/kern_jaildesc.c b/sys/kern/kern_jaildesc.c
index e2e3246ea92b..fdce321cb468 100644
--- a/sys/kern/kern_jaildesc.c
+++ b/sys/kern/kern_jaildesc.c
@@ -153,18 +153,16 @@ jaildesc_alloc(struct thread *td, struct file **fpp, int *fdp, int owning)
if (error != 0)
return (error);
}
- jd = malloc(sizeof(*jd), M_JAILDESC, M_WAITOK | M_ZERO);
error = falloc_caps(td, &fp, fdp, 0, NULL);
- if (error != 0) {
- free(jd, M_JAILDESC);
+ if (error != 0)
return (error);
- }
- finit(fp, priv_check_cred(fp->f_cred, PRIV_JAIL_SET) == 0 ?
- FREAD | FWRITE : FREAD, DTYPE_JAILDESC, jd, &jaildesc_ops);
+ jd = malloc(sizeof(*jd), M_JAILDESC, M_WAITOK | M_ZERO);
JAILDESC_LOCK_INIT(jd);
knlist_init_mtx(&jd->jd_selinfo.si_note, &jd->jd_lock);
if (owning)
jd->jd_flags |= JDF_OWNING;
+ finit(fp, priv_check_cred(fp->f_cred, PRIV_JAIL_SET) == 0 ?
+ FREAD | FWRITE : FREAD, DTYPE_JAILDESC, jd, &jaildesc_ops);
*fpp = fp;
return (0);
}