mirror of
https://github.com/opnsense/src.git
synced 2026-06-04 14:26:03 -04:00
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
This commit is contained in:
parent
2656fc29be
commit
a2ddbe019d
1 changed files with 17 additions and 0 deletions
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue