git: a2ddbe019d51 - main - unionfs: work around underlying FS failing to respect cn_namelen
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sun, 18 Feb 2024 15:20:02 UTC
The branch main has been updated by jah:
URL: https://cgit.FreeBSD.org/src/commit/?id=a2ddbe019d51b35f9da2cb5ddca8c69f0ee422da
commit a2ddbe019d51b35f9da2cb5ddca8c69f0ee422da
Author: Jason A. Harmening <jah@FreeBSD.org>
AuthorDate: 2023-12-24 04:48:19 +0000
Commit: Jason A. Harmening <jah@FreeBSD.org>
CommitDate: 2024-02-18 15:19:23 +0000
unionfs: work around underlying FS failing to respect cn_namelen
unionfs_mkshadowdir() may be invoked on a non-leaf pathname component
during lookup, in which case the NUL terminator of the pathname buffer
will be well beyond the end of the current component. cn_namelen in
this case will still (correctly) indicate the length of only the
current component, but ZFS in particular does not currently respect
cn_namelen, leading to the creation on inacessible files with slashes
in their names. Work around this behavior by temporarily NUL-
terminating the current pathname component for the call to VOP_MKDIR().
https://github.com/openzfs/zfs/issues/15705 has been filed to track
a proper upstream fix for the issue at hand.
PR: 275871
Reported by: Karlo Miličević <karlo98.m@gmail.com>
Tested by: Karlo Miličević <karlo98.m@gmail.com>
Reviewed by: kib, olce
MFC after: 2 weeks
Differential Revision: https://reviews.freebsd.org/D43818
---
sys/fs/unionfs/union_subr.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/sys/fs/unionfs/union_subr.c b/sys/fs/unionfs/union_subr.c
index b438131dc820..686043cc93de 100644
--- a/sys/fs/unionfs/union_subr.c
+++ b/sys/fs/unionfs/union_subr.c
@@ -916,7 +916,24 @@ unionfs_mkshadowdir(struct unionfs_mount *ump, struct vnode *udvp,
goto unionfs_mkshadowdir_abort;
unionfs_create_uppervattr_core(ump, &lva, &va, td);
+ /*
+ * Temporarily NUL-terminate the current pathname component.
+ * This function may be called during lookup operations in which
+ * the current pathname component is not the leaf, meaning that
+ * the NUL terminator is some distance beyond the end of the current
+ * component. This *should* be fine, as cn_namelen will still
+ * correctly indicate the length of only the current component,
+ * but ZFS in particular does not respect cn_namelen in its VOP_MKDIR
+ * implementation
+ * Note that this assumes nd.ni_cnd.cn_pnbuf was allocated by
+ * something like a local namei() operation and the temporary
+ * NUL-termination will not have an effect on other threads.
+ */
+ char *pathend = &nd.ni_cnd.cn_nameptr[nd.ni_cnd.cn_namelen];
+ char pathterm = *pathend;
+ *pathend = '\0';
error = VOP_MKDIR(udvp, &uvp, &nd.ni_cnd, &va);
+ *pathend = pathterm;
if (!error) {
unionfs_node_update(unp, uvp, td);