From: Amir Goldstein Date: Thu, 5 Jun 2025 10:15:30 +0000 (+0200) Subject: ovl: fix regression caused by lookup helpers API changes X-Git-Tag: v6.16-rc3~42^2~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=714d02b41939d2720379e11ef25227aec4e5bec9;p=thirdparty%2Fkernel%2Flinux.git ovl: fix regression caused by lookup helpers API changes The lookup helpers API was changed by merge of vfs-6.16-rc1.async.dir to pass a non-const qstr pointer argument to lookup_one*() helpers. All of the callers of this API were changed to pass a pointer to temp copy of qstr, except overlays that was passing a const pointer to dentry->d_name that was changed to pass a non-const copy instead when doing a lookup in lower layer which is not the fs of said dentry. This wrong use of the API caused a regression in fstest overlay/012. Fix the regression by making a non-const copy of dentry->d_name prior to calling the lookup API, but the API should be fixed to not allow this class of bugs. Cc: NeilBrown Fixes: 5741909697a3 ("VFS: improve interface for lookup_one functions") Fixes: 390e34bc1490 ("VFS: change lookup_one_common and lookup_noperm_common to take a qstr") Signed-off-by: Amir Goldstein Link: https://lore.kernel.org/20250605101530.2336320-1-amir73il@gmail.com Signed-off-by: Christian Brauner --- diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c index bf722daf19a95..f75c49ceb460d 100644 --- a/fs/overlayfs/namei.c +++ b/fs/overlayfs/namei.c @@ -1371,7 +1371,7 @@ out: bool ovl_lower_positive(struct dentry *dentry) { struct ovl_entry *poe = OVL_E(dentry->d_parent); - struct qstr *name = &dentry->d_name; + const struct qstr *name = &dentry->d_name; const struct cred *old_cred; unsigned int i; bool positive = false; @@ -1394,9 +1394,15 @@ bool ovl_lower_positive(struct dentry *dentry) struct dentry *this; struct ovl_path *parentpath = &ovl_lowerstack(poe)[i]; + /* + * We need to make a non-const copy of dentry->d_name, + * because lookup_one_positive_unlocked() will hash name + * with parentpath base, which is on another (lower fs). + */ this = lookup_one_positive_unlocked( mnt_idmap(parentpath->layer->mnt), - name, parentpath->dentry); + &QSTR_LEN(name->name, name->len), + parentpath->dentry); if (IS_ERR(this)) { switch (PTR_ERR(this)) { case -ENOENT: