xref: /openbmc/linux/fs/overlayfs/namei.c (revision f01d0889)
1d2912cb1SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2bbb1e54dSMiklos Szeredi /*
3bbb1e54dSMiklos Szeredi  * Copyright (C) 2011 Novell Inc.
4bbb1e54dSMiklos Szeredi  * Copyright (C) 2016 Red Hat, Inc.
5bbb1e54dSMiklos Szeredi  */
6bbb1e54dSMiklos Szeredi 
7bbb1e54dSMiklos Szeredi #include <linux/fs.h>
85b825c3aSIngo Molnar #include <linux/cred.h>
99ee60ce2SAmir Goldstein #include <linux/ctype.h>
10bbb1e54dSMiklos Szeredi #include <linux/namei.h>
11bbb1e54dSMiklos Szeredi #include <linux/xattr.h>
1202b69b28SMiklos Szeredi #include <linux/ratelimit.h>
13a9d01957SAmir Goldstein #include <linux/mount.h>
14a9d01957SAmir Goldstein #include <linux/exportfs.h>
15bbb1e54dSMiklos Szeredi #include "overlayfs.h"
16bbb1e54dSMiklos Szeredi 
175436ab0aSAmir Goldstein #include "../internal.h"	/* for vfs_path_lookup */
185436ab0aSAmir Goldstein 
19e28edc46SMiklos Szeredi struct ovl_lookup_data {
20146d62e5SAmir Goldstein 	struct super_block *sb;
21dad7017aSChristian Brauner 	struct vfsmount *mnt;
22e28edc46SMiklos Szeredi 	struct qstr name;
23e28edc46SMiklos Szeredi 	bool is_dir;
24e28edc46SMiklos Szeredi 	bool opaque;
25e28edc46SMiklos Szeredi 	bool stop;
26e28edc46SMiklos Szeredi 	bool last;
2702b69b28SMiklos Szeredi 	char *redirect;
28bf070890SAlexander Larsson 	int metacopy;
295436ab0aSAmir Goldstein 	/* Referring to last redirect xattr */
305436ab0aSAmir Goldstein 	bool absolute_redirect;
31e28edc46SMiklos Szeredi };
32bbb1e54dSMiklos Szeredi 
ovl_check_redirect(const struct path * path,struct ovl_lookup_data * d,size_t prelen,const char * post)332d343087SAl Viro static int ovl_check_redirect(const struct path *path, struct ovl_lookup_data *d,
3402b69b28SMiklos Szeredi 			      size_t prelen, const char *post)
3502b69b28SMiklos Szeredi {
3602b69b28SMiklos Szeredi 	int res;
370a2d0d3fSVivek Goyal 	char *buf;
38610afc0bSMiklos Szeredi 	struct ovl_fs *ofs = OVL_FS(d->sb);
3902b69b28SMiklos Szeredi 
405436ab0aSAmir Goldstein 	d->absolute_redirect = false;
41dad7017aSChristian Brauner 	buf = ovl_get_redirect_xattr(ofs, path, prelen + strlen(post));
420a2d0d3fSVivek Goyal 	if (IS_ERR_OR_NULL(buf))
430a2d0d3fSVivek Goyal 		return PTR_ERR(buf);
4402b69b28SMiklos Szeredi 
4502b69b28SMiklos Szeredi 	if (buf[0] == '/') {
465436ab0aSAmir Goldstein 		d->absolute_redirect = true;
473ec9b3faSAmir Goldstein 		/*
483ec9b3faSAmir Goldstein 		 * One of the ancestor path elements in an absolute path
493ec9b3faSAmir Goldstein 		 * lookup in ovl_lookup_layer() could have been opaque and
503ec9b3faSAmir Goldstein 		 * that will stop further lookup in lower layers (d->stop=true)
514f119628SWilliam Dean 		 * But we have found an absolute redirect in descendant path
523ec9b3faSAmir Goldstein 		 * element and that should force continue lookup in lower
533ec9b3faSAmir Goldstein 		 * layers (reset d->stop).
543ec9b3faSAmir Goldstein 		 */
553ec9b3faSAmir Goldstein 		d->stop = false;
5602b69b28SMiklos Szeredi 	} else {
570a2d0d3fSVivek Goyal 		res = strlen(buf) + 1;
5802b69b28SMiklos Szeredi 		memmove(buf + prelen, buf, res);
5902b69b28SMiklos Szeredi 		memcpy(buf, d->name.name, prelen);
6002b69b28SMiklos Szeredi 	}
6102b69b28SMiklos Szeredi 
6202b69b28SMiklos Szeredi 	strcat(buf, post);
6302b69b28SMiklos Szeredi 	kfree(d->redirect);
6402b69b28SMiklos Szeredi 	d->redirect = buf;
6502b69b28SMiklos Szeredi 	d->name.name = d->redirect;
6602b69b28SMiklos Szeredi 	d->name.len = strlen(d->redirect);
6702b69b28SMiklos Szeredi 
6802b69b28SMiklos Szeredi 	return 0;
6902b69b28SMiklos Szeredi }
7002b69b28SMiklos Szeredi 
ovl_acceptable(void * ctx,struct dentry * dentry)71a9d01957SAmir Goldstein static int ovl_acceptable(void *ctx, struct dentry *dentry)
72a9d01957SAmir Goldstein {
73e8f9e5b7SAmir Goldstein 	/*
74e8f9e5b7SAmir Goldstein 	 * A non-dir origin may be disconnected, which is fine, because
75e8f9e5b7SAmir Goldstein 	 * we only need it for its unique inode number.
76e8f9e5b7SAmir Goldstein 	 */
77e8f9e5b7SAmir Goldstein 	if (!d_is_dir(dentry))
78a9d01957SAmir Goldstein 		return 1;
79e8f9e5b7SAmir Goldstein 
80e8f9e5b7SAmir Goldstein 	/* Don't decode a deleted empty directory */
81e8f9e5b7SAmir Goldstein 	if (d_unhashed(dentry))
82e8f9e5b7SAmir Goldstein 		return 0;
83e8f9e5b7SAmir Goldstein 
84e8f9e5b7SAmir Goldstein 	/* Check if directory belongs to the layer we are decoding from */
85e8f9e5b7SAmir Goldstein 	return is_subdir(dentry, ((struct vfsmount *)ctx)->mnt_root);
86a9d01957SAmir Goldstein }
87a9d01957SAmir Goldstein 
882e1a5328SAmir Goldstein /*
892e1a5328SAmir Goldstein  * Check validity of an overlay file handle buffer.
902e1a5328SAmir Goldstein  *
912e1a5328SAmir Goldstein  * Return 0 for a valid file handle.
922e1a5328SAmir Goldstein  * Return -ENODATA for "origin unknown".
932e1a5328SAmir Goldstein  * Return <0 for an invalid file handle.
942e1a5328SAmir Goldstein  */
ovl_check_fb_len(struct ovl_fb * fb,int fb_len)95cbe7fba8SAmir Goldstein int ovl_check_fb_len(struct ovl_fb *fb, int fb_len)
962e1a5328SAmir Goldstein {
97cbe7fba8SAmir Goldstein 	if (fb_len < sizeof(struct ovl_fb) || fb_len < fb->len)
982e1a5328SAmir Goldstein 		return -EINVAL;
992e1a5328SAmir Goldstein 
100cbe7fba8SAmir Goldstein 	if (fb->magic != OVL_FH_MAGIC)
1012e1a5328SAmir Goldstein 		return -EINVAL;
1022e1a5328SAmir Goldstein 
1032e1a5328SAmir Goldstein 	/* Treat larger version and unknown flags as "origin unknown" */
104cbe7fba8SAmir Goldstein 	if (fb->version > OVL_FH_VERSION || fb->flags & ~OVL_FH_FLAG_ALL)
1052e1a5328SAmir Goldstein 		return -ENODATA;
1062e1a5328SAmir Goldstein 
1072e1a5328SAmir Goldstein 	/* Treat endianness mismatch as "origin unknown" */
108cbe7fba8SAmir Goldstein 	if (!(fb->flags & OVL_FH_FLAG_ANY_ENDIAN) &&
109cbe7fba8SAmir Goldstein 	    (fb->flags & OVL_FH_FLAG_BIG_ENDIAN) != OVL_FH_FLAG_CPU_ENDIAN)
1102e1a5328SAmir Goldstein 		return -ENODATA;
1112e1a5328SAmir Goldstein 
1122e1a5328SAmir Goldstein 	return 0;
1132e1a5328SAmir Goldstein }
1142e1a5328SAmir Goldstein 
ovl_get_fh(struct ovl_fs * ofs,struct dentry * upperdentry,enum ovl_xattr ox)115dad7017aSChristian Brauner static struct ovl_fh *ovl_get_fh(struct ovl_fs *ofs, struct dentry *upperdentry,
11643d193f8SMiklos Szeredi 				 enum ovl_xattr ox)
117a9d01957SAmir Goldstein {
1182e1a5328SAmir Goldstein 	int res, err;
119a9d01957SAmir Goldstein 	struct ovl_fh *fh = NULL;
120a9d01957SAmir Goldstein 
121dad7017aSChristian Brauner 	res = ovl_getxattr_upper(ofs, upperdentry, ox, NULL, 0);
122a9d01957SAmir Goldstein 	if (res < 0) {
123a9d01957SAmir Goldstein 		if (res == -ENODATA || res == -EOPNOTSUPP)
124a9d01957SAmir Goldstein 			return NULL;
125a9d01957SAmir Goldstein 		goto fail;
126a9d01957SAmir Goldstein 	}
127a9d01957SAmir Goldstein 	/* Zero size value means "copied up but origin unknown" */
128a9d01957SAmir Goldstein 	if (res == 0)
129a9d01957SAmir Goldstein 		return NULL;
130a9d01957SAmir Goldstein 
131cbe7fba8SAmir Goldstein 	fh = kzalloc(res + OVL_FH_WIRE_OFFSET, GFP_KERNEL);
132a9d01957SAmir Goldstein 	if (!fh)
133a9d01957SAmir Goldstein 		return ERR_PTR(-ENOMEM);
134a9d01957SAmir Goldstein 
135dad7017aSChristian Brauner 	res = ovl_getxattr_upper(ofs, upperdentry, ox, fh->buf, res);
136a9d01957SAmir Goldstein 	if (res < 0)
137a9d01957SAmir Goldstein 		goto fail;
138a9d01957SAmir Goldstein 
139cbe7fba8SAmir Goldstein 	err = ovl_check_fb_len(&fh->fb, res);
1402e1a5328SAmir Goldstein 	if (err < 0) {
1412e1a5328SAmir Goldstein 		if (err == -ENODATA)
142a9d01957SAmir Goldstein 			goto out;
1432e1a5328SAmir Goldstein 		goto invalid;
1442e1a5328SAmir Goldstein 	}
145a9d01957SAmir Goldstein 
1468b88a2e6SAmir Goldstein 	return fh;
1478b88a2e6SAmir Goldstein 
1488b88a2e6SAmir Goldstein out:
1498b88a2e6SAmir Goldstein 	kfree(fh);
1508b88a2e6SAmir Goldstein 	return NULL;
1518b88a2e6SAmir Goldstein 
1528b88a2e6SAmir Goldstein fail:
1531bd0a3aeSlijiazi 	pr_warn_ratelimited("failed to get origin (%i)\n", res);
1548b88a2e6SAmir Goldstein 	goto out;
1558b88a2e6SAmir Goldstein invalid:
1561bd0a3aeSlijiazi 	pr_warn_ratelimited("invalid origin (%*phN)\n", res, fh);
1578b88a2e6SAmir Goldstein 	goto out;
1588b88a2e6SAmir Goldstein }
1598b88a2e6SAmir Goldstein 
ovl_decode_real_fh(struct ovl_fs * ofs,struct ovl_fh * fh,struct vfsmount * mnt,bool connected)1601cdb0cb6SPavel Tikhomirov struct dentry *ovl_decode_real_fh(struct ovl_fs *ofs, struct ovl_fh *fh,
1611cdb0cb6SPavel Tikhomirov 				  struct vfsmount *mnt, bool connected)
1628b88a2e6SAmir Goldstein {
163e8f9e5b7SAmir Goldstein 	struct dentry *real;
1648b88a2e6SAmir Goldstein 	int bytes;
1658b88a2e6SAmir Goldstein 
166c846af05SMiklos Szeredi 	if (!capable(CAP_DAC_READ_SEARCH))
167c846af05SMiklos Szeredi 		return NULL;
168c846af05SMiklos Szeredi 
169a9d01957SAmir Goldstein 	/*
170a9d01957SAmir Goldstein 	 * Make sure that the stored uuid matches the uuid of the lower
171a9d01957SAmir Goldstein 	 * layer where file handle will be decoded.
1725830fb6bSPavel Tikhomirov 	 * In case of uuid=off option just make sure that stored uuid is null.
173a9d01957SAmir Goldstein 	 */
174b0504bfeSAmir Goldstein 	if (ovl_origin_uuid(ofs) ?
175b0504bfeSAmir Goldstein 	    !uuid_equal(&fh->fb.uuid, &mnt->mnt_sb->s_uuid) :
1765830fb6bSPavel Tikhomirov 	    !uuid_is_null(&fh->fb.uuid))
1772e1a5328SAmir Goldstein 		return NULL;
178a9d01957SAmir Goldstein 
179cbe7fba8SAmir Goldstein 	bytes = (fh->fb.len - offsetof(struct ovl_fb, fid));
180cbe7fba8SAmir Goldstein 	real = exportfs_decode_fh(mnt, (struct fid *)fh->fb.fid,
181cbe7fba8SAmir Goldstein 				  bytes >> 2, (int)fh->fb.type,
1828a22efa1SAmir Goldstein 				  connected ? ovl_acceptable : NULL, mnt);
183e8f9e5b7SAmir Goldstein 	if (IS_ERR(real)) {
184e8f9e5b7SAmir Goldstein 		/*
185e8f9e5b7SAmir Goldstein 		 * Treat stale file handle to lower file as "origin unknown".
186e8f9e5b7SAmir Goldstein 		 * upper file handle could become stale when upper file is
187e8f9e5b7SAmir Goldstein 		 * unlinked and this information is needed to handle stale
188e8f9e5b7SAmir Goldstein 		 * index entries correctly.
189e8f9e5b7SAmir Goldstein 		 */
190e8f9e5b7SAmir Goldstein 		if (real == ERR_PTR(-ESTALE) &&
191cbe7fba8SAmir Goldstein 		    !(fh->fb.flags & OVL_FH_FLAG_PATH_UPPER))
192e8f9e5b7SAmir Goldstein 			real = NULL;
193e8f9e5b7SAmir Goldstein 		return real;
194a9d01957SAmir Goldstein 	}
195a9d01957SAmir Goldstein 
196e8f9e5b7SAmir Goldstein 	if (ovl_dentry_weird(real)) {
197e8f9e5b7SAmir Goldstein 		dput(real);
1982e1a5328SAmir Goldstein 		return NULL;
1992e1a5328SAmir Goldstein 	}
2002e1a5328SAmir Goldstein 
201e8f9e5b7SAmir Goldstein 	return real;
202a9d01957SAmir Goldstein }
203a9d01957SAmir Goldstein 
ovl_is_opaquedir(struct ovl_fs * ofs,const struct path * path)2042d343087SAl Viro static bool ovl_is_opaquedir(struct ovl_fs *ofs, const struct path *path)
205ee1d6d37SAmir Goldstein {
206dad7017aSChristian Brauner 	return ovl_path_check_dir_xattr(ofs, path, OVL_XATTR_OPAQUE);
207ee1d6d37SAmir Goldstein }
208ee1d6d37SAmir Goldstein 
ovl_lookup_positive_unlocked(struct ovl_lookup_data * d,const char * name,struct dentry * base,int len,bool drop_negative)209ba9ea771SChristian Brauner static struct dentry *ovl_lookup_positive_unlocked(struct ovl_lookup_data *d,
210ba9ea771SChristian Brauner 						   const char *name,
2111434a65eSChengguang Xu 						   struct dentry *base, int len,
2121434a65eSChengguang Xu 						   bool drop_negative)
2131434a65eSChengguang Xu {
2144609e1f1SChristian Brauner 	struct dentry *ret = lookup_one_unlocked(mnt_idmap(d->mnt), name, base, len);
2151434a65eSChengguang Xu 
2161434a65eSChengguang Xu 	if (!IS_ERR(ret) && d_flags_negative(smp_load_acquire(&ret->d_flags))) {
2171434a65eSChengguang Xu 		if (drop_negative && ret->d_lockref.count == 1) {
2181434a65eSChengguang Xu 			spin_lock(&ret->d_lock);
2191434a65eSChengguang Xu 			/* Recheck condition under lock */
2201434a65eSChengguang Xu 			if (d_is_negative(ret) && ret->d_lockref.count == 1)
2211434a65eSChengguang Xu 				__d_drop(ret);
2221434a65eSChengguang Xu 			spin_unlock(&ret->d_lock);
2231434a65eSChengguang Xu 		}
2241434a65eSChengguang Xu 		dput(ret);
2251434a65eSChengguang Xu 		ret = ERR_PTR(-ENOENT);
2261434a65eSChengguang Xu 	}
2271434a65eSChengguang Xu 	return ret;
2281434a65eSChengguang Xu }
2291434a65eSChengguang Xu 
ovl_lookup_single(struct dentry * base,struct ovl_lookup_data * d,const char * name,unsigned int namelen,size_t prelen,const char * post,struct dentry ** ret,bool drop_negative)230e28edc46SMiklos Szeredi static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d,
231e28edc46SMiklos Szeredi 			     const char *name, unsigned int namelen,
23202b69b28SMiklos Szeredi 			     size_t prelen, const char *post,
2331434a65eSChengguang Xu 			     struct dentry **ret, bool drop_negative)
234e28edc46SMiklos Szeredi {
235e28edc46SMiklos Szeredi 	struct dentry *this;
236dad7017aSChristian Brauner 	struct path path;
237e28edc46SMiklos Szeredi 	int err;
238102b0d11SVivek Goyal 	bool last_element = !post[0];
239e28edc46SMiklos Szeredi 
240ba9ea771SChristian Brauner 	this = ovl_lookup_positive_unlocked(d, name, base, namelen, drop_negative);
241e28edc46SMiklos Szeredi 	if (IS_ERR(this)) {
242e28edc46SMiklos Szeredi 		err = PTR_ERR(this);
243e28edc46SMiklos Szeredi 		this = NULL;
244e28edc46SMiklos Szeredi 		if (err == -ENOENT || err == -ENAMETOOLONG)
245e28edc46SMiklos Szeredi 			goto out;
246e28edc46SMiklos Szeredi 		goto out_err;
247e28edc46SMiklos Szeredi 	}
248e28edc46SMiklos Szeredi 
249e28edc46SMiklos Szeredi 	if (ovl_dentry_weird(this)) {
250e28edc46SMiklos Szeredi 		/* Don't support traversing automounts and other weirdness */
251e28edc46SMiklos Szeredi 		err = -EREMOTE;
252e28edc46SMiklos Szeredi 		goto out_err;
253e28edc46SMiklos Szeredi 	}
254e28edc46SMiklos Szeredi 	if (ovl_is_whiteout(this)) {
255e28edc46SMiklos Szeredi 		d->stop = d->opaque = true;
256e28edc46SMiklos Szeredi 		goto put_and_out;
257e28edc46SMiklos Szeredi 	}
2583a291774SMiklos Szeredi 	/*
2599d3dfea3SVivek Goyal 	 * This dentry should be a regular file if previous layer lookup
2609d3dfea3SVivek Goyal 	 * found a metacopy dentry.
2613a291774SMiklos Szeredi 	 */
2629d3dfea3SVivek Goyal 	if (last_element && d->metacopy && !d_is_reg(this)) {
2639d3dfea3SVivek Goyal 		d->stop = true;
2649d3dfea3SVivek Goyal 		goto put_and_out;
2659d3dfea3SVivek Goyal 	}
266dad7017aSChristian Brauner 
267dad7017aSChristian Brauner 	path.dentry = this;
268dad7017aSChristian Brauner 	path.mnt = d->mnt;
2699d3dfea3SVivek Goyal 	if (!d_can_lookup(this)) {
2709d3dfea3SVivek Goyal 		if (d->is_dir || !last_element) {
2719d3dfea3SVivek Goyal 			d->stop = true;
2729d3dfea3SVivek Goyal 			goto put_and_out;
2739d3dfea3SVivek Goyal 		}
274bf070890SAlexander Larsson 		err = ovl_check_metacopy_xattr(OVL_FS(d->sb), &path, NULL);
2759d3dfea3SVivek Goyal 		if (err < 0)
2769d3dfea3SVivek Goyal 			goto out_err;
2779d3dfea3SVivek Goyal 
2789d3dfea3SVivek Goyal 		d->metacopy = err;
2799d3dfea3SVivek Goyal 		d->stop = !d->metacopy;
280b8a8824cSVivek Goyal 		if (!d->metacopy || d->last)
281e28edc46SMiklos Szeredi 			goto out;
2820618a816SVivek Goyal 	} else {
283146d62e5SAmir Goldstein 		if (ovl_lookup_trap_inode(d->sb, this)) {
284146d62e5SAmir Goldstein 			/* Caught in a trap of overlapping layers */
285146d62e5SAmir Goldstein 			err = -ELOOP;
286146d62e5SAmir Goldstein 			goto out_err;
287146d62e5SAmir Goldstein 		}
288146d62e5SAmir Goldstein 
289102b0d11SVivek Goyal 		if (last_element)
290e28edc46SMiklos Szeredi 			d->is_dir = true;
291e9b77f90SVivek Goyal 		if (d->last)
292e9b77f90SVivek Goyal 			goto out;
293e9b77f90SVivek Goyal 
294dad7017aSChristian Brauner 		if (ovl_is_opaquedir(OVL_FS(d->sb), &path)) {
295102b0d11SVivek Goyal 			d->stop = true;
296102b0d11SVivek Goyal 			if (last_element)
297102b0d11SVivek Goyal 				d->opaque = true;
298e28edc46SMiklos Szeredi 			goto out;
299e28edc46SMiklos Szeredi 		}
3000618a816SVivek Goyal 	}
301dad7017aSChristian Brauner 	err = ovl_check_redirect(&path, d, prelen, post);
30202b69b28SMiklos Szeredi 	if (err)
30302b69b28SMiklos Szeredi 		goto out_err;
304e28edc46SMiklos Szeredi out:
305e28edc46SMiklos Szeredi 	*ret = this;
306e28edc46SMiklos Szeredi 	return 0;
307e28edc46SMiklos Szeredi 
308e28edc46SMiklos Szeredi put_and_out:
309e28edc46SMiklos Szeredi 	dput(this);
310e28edc46SMiklos Szeredi 	this = NULL;
311e28edc46SMiklos Szeredi 	goto out;
312e28edc46SMiklos Szeredi 
313e28edc46SMiklos Szeredi out_err:
314e28edc46SMiklos Szeredi 	dput(this);
315e28edc46SMiklos Szeredi 	return err;
316e28edc46SMiklos Szeredi }
317e28edc46SMiklos Szeredi 
ovl_lookup_layer(struct dentry * base,struct ovl_lookup_data * d,struct dentry ** ret,bool drop_negative)318e28edc46SMiklos Szeredi static int ovl_lookup_layer(struct dentry *base, struct ovl_lookup_data *d,
3191434a65eSChengguang Xu 			    struct dentry **ret, bool drop_negative)
320e28edc46SMiklos Szeredi {
3214c7d0c9cSAmir Goldstein 	/* Counting down from the end, since the prefix can change */
3224c7d0c9cSAmir Goldstein 	size_t rem = d->name.len - 1;
32302b69b28SMiklos Szeredi 	struct dentry *dentry = NULL;
32402b69b28SMiklos Szeredi 	int err;
32502b69b28SMiklos Szeredi 
3264c7d0c9cSAmir Goldstein 	if (d->name.name[0] != '/')
32702b69b28SMiklos Szeredi 		return ovl_lookup_single(base, d, d->name.name, d->name.len,
3281434a65eSChengguang Xu 					 0, "", ret, drop_negative);
32902b69b28SMiklos Szeredi 
3304c7d0c9cSAmir Goldstein 	while (!IS_ERR_OR_NULL(base) && d_can_lookup(base)) {
3314c7d0c9cSAmir Goldstein 		const char *s = d->name.name + d->name.len - rem;
33202b69b28SMiklos Szeredi 		const char *next = strchrnul(s, '/');
3334c7d0c9cSAmir Goldstein 		size_t thislen = next - s;
3344c7d0c9cSAmir Goldstein 		bool end = !next[0];
33502b69b28SMiklos Szeredi 
3364c7d0c9cSAmir Goldstein 		/* Verify we did not go off the rails */
3374c7d0c9cSAmir Goldstein 		if (WARN_ON(s[-1] != '/'))
33802b69b28SMiklos Szeredi 			return -EIO;
33902b69b28SMiklos Szeredi 
3404c7d0c9cSAmir Goldstein 		err = ovl_lookup_single(base, d, s, thislen,
3411434a65eSChengguang Xu 					d->name.len - rem, next, &base,
3421434a65eSChengguang Xu 					drop_negative);
34302b69b28SMiklos Szeredi 		dput(dentry);
34402b69b28SMiklos Szeredi 		if (err)
34502b69b28SMiklos Szeredi 			return err;
34602b69b28SMiklos Szeredi 		dentry = base;
3474c7d0c9cSAmir Goldstein 		if (end)
3484c7d0c9cSAmir Goldstein 			break;
3494c7d0c9cSAmir Goldstein 
3504c7d0c9cSAmir Goldstein 		rem -= thislen + 1;
3514c7d0c9cSAmir Goldstein 
3524c7d0c9cSAmir Goldstein 		if (WARN_ON(rem >= d->name.len))
3534c7d0c9cSAmir Goldstein 			return -EIO;
35402b69b28SMiklos Szeredi 	}
35502b69b28SMiklos Szeredi 	*ret = dentry;
35602b69b28SMiklos Szeredi 	return 0;
357e28edc46SMiklos Szeredi }
358e28edc46SMiklos Szeredi 
ovl_lookup_data_layer(struct dentry * dentry,const char * redirect,const struct ovl_layer * layer,struct path * datapath)3595436ab0aSAmir Goldstein static int ovl_lookup_data_layer(struct dentry *dentry, const char *redirect,
3605436ab0aSAmir Goldstein 				 const struct ovl_layer *layer,
3615436ab0aSAmir Goldstein 				 struct path *datapath)
3625436ab0aSAmir Goldstein {
3635436ab0aSAmir Goldstein 	int err;
3645436ab0aSAmir Goldstein 
3655436ab0aSAmir Goldstein 	err = vfs_path_lookup(layer->mnt->mnt_root, layer->mnt, redirect,
3665436ab0aSAmir Goldstein 			LOOKUP_BENEATH | LOOKUP_NO_SYMLINKS | LOOKUP_NO_XDEV,
3675436ab0aSAmir Goldstein 			datapath);
3685436ab0aSAmir Goldstein 	pr_debug("lookup lowerdata (%pd2, redirect=\"%s\", layer=%d, err=%i)\n",
3695436ab0aSAmir Goldstein 		 dentry, redirect, layer->idx, err);
3705436ab0aSAmir Goldstein 
3715436ab0aSAmir Goldstein 	if (err)
3725436ab0aSAmir Goldstein 		return err;
3735436ab0aSAmir Goldstein 
3745436ab0aSAmir Goldstein 	err = -EREMOTE;
3755436ab0aSAmir Goldstein 	if (ovl_dentry_weird(datapath->dentry))
3765436ab0aSAmir Goldstein 		goto out_path_put;
3775436ab0aSAmir Goldstein 
3785436ab0aSAmir Goldstein 	err = -ENOENT;
3795436ab0aSAmir Goldstein 	/* Only regular file is acceptable as lower data */
3805436ab0aSAmir Goldstein 	if (!d_is_reg(datapath->dentry))
3815436ab0aSAmir Goldstein 		goto out_path_put;
3825436ab0aSAmir Goldstein 
3835436ab0aSAmir Goldstein 	return 0;
3845436ab0aSAmir Goldstein 
3855436ab0aSAmir Goldstein out_path_put:
3865436ab0aSAmir Goldstein 	path_put(datapath);
3875436ab0aSAmir Goldstein 
3885436ab0aSAmir Goldstein 	return err;
3895436ab0aSAmir Goldstein }
3905436ab0aSAmir Goldstein 
3915436ab0aSAmir Goldstein /* Lookup in data-only layers by absolute redirect to layer root */
ovl_lookup_data_layers(struct dentry * dentry,const char * redirect,struct ovl_path * lowerdata)3925436ab0aSAmir Goldstein static int ovl_lookup_data_layers(struct dentry *dentry, const char *redirect,
3935436ab0aSAmir Goldstein 				  struct ovl_path *lowerdata)
3945436ab0aSAmir Goldstein {
3955436ab0aSAmir Goldstein 	struct ovl_fs *ofs = OVL_FS(dentry->d_sb);
3965436ab0aSAmir Goldstein 	const struct ovl_layer *layer;
3975436ab0aSAmir Goldstein 	struct path datapath;
3985436ab0aSAmir Goldstein 	int err = -ENOENT;
3995436ab0aSAmir Goldstein 	int i;
4005436ab0aSAmir Goldstein 
4015436ab0aSAmir Goldstein 	layer = &ofs->layers[ofs->numlayer - ofs->numdatalayer];
4025436ab0aSAmir Goldstein 	for (i = 0; i < ofs->numdatalayer; i++, layer++) {
4035436ab0aSAmir Goldstein 		err = ovl_lookup_data_layer(dentry, redirect, layer, &datapath);
4045436ab0aSAmir Goldstein 		if (!err) {
4055436ab0aSAmir Goldstein 			mntput(datapath.mnt);
4065436ab0aSAmir Goldstein 			lowerdata->dentry = datapath.dentry;
4075436ab0aSAmir Goldstein 			lowerdata->layer = layer;
4085436ab0aSAmir Goldstein 			return 0;
4095436ab0aSAmir Goldstein 		}
4105436ab0aSAmir Goldstein 	}
4115436ab0aSAmir Goldstein 
4125436ab0aSAmir Goldstein 	return err;
4135436ab0aSAmir Goldstein }
414a9d01957SAmir Goldstein 
ovl_check_origin_fh(struct ovl_fs * ofs,struct ovl_fh * fh,bool connected,struct dentry * upperdentry,struct ovl_path ** stackp)4158a22efa1SAmir Goldstein int ovl_check_origin_fh(struct ovl_fs *ofs, struct ovl_fh *fh, bool connected,
416f941866fSAmir Goldstein 			struct dentry *upperdentry, struct ovl_path **stackp)
417a9d01957SAmir Goldstein {
418f7d3dacaSAmir Goldstein 	struct dentry *origin = NULL;
419f7d3dacaSAmir Goldstein 	int i;
420a9d01957SAmir Goldstein 
42137ebf056SAmir Goldstein 	for (i = 1; i <= ovl_numlowerlayer(ofs); i++) {
4227e63c87fSAmir Goldstein 		/*
4237e63c87fSAmir Goldstein 		 * If lower fs uuid is not unique among lower fs we cannot match
4247e63c87fSAmir Goldstein 		 * fh->uuid to layer.
4257e63c87fSAmir Goldstein 		 */
42694375f9dSAmir Goldstein 		if (ofs->layers[i].fsid &&
42794375f9dSAmir Goldstein 		    ofs->layers[i].fs->bad_uuid)
4287e63c87fSAmir Goldstein 			continue;
4297e63c87fSAmir Goldstein 
4301cdb0cb6SPavel Tikhomirov 		origin = ovl_decode_real_fh(ofs, fh, ofs->layers[i].mnt,
4318a22efa1SAmir Goldstein 					    connected);
432f7d3dacaSAmir Goldstein 		if (origin)
433f7d3dacaSAmir Goldstein 			break;
434f7d3dacaSAmir Goldstein 	}
435f7d3dacaSAmir Goldstein 
436f7d3dacaSAmir Goldstein 	if (!origin)
4372e1a5328SAmir Goldstein 		return -ESTALE;
4382e1a5328SAmir Goldstein 	else if (IS_ERR(origin))
4392e1a5328SAmir Goldstein 		return PTR_ERR(origin);
440f7d3dacaSAmir Goldstein 
441f941866fSAmir Goldstein 	if (upperdentry && !ovl_is_whiteout(upperdentry) &&
4426e3e2c43SAl Viro 	    inode_wrong_type(d_inode(upperdentry), d_inode(origin)->i_mode))
4432e1a5328SAmir Goldstein 		goto invalid;
4442e1a5328SAmir Goldstein 
445415543d5SAmir Goldstein 	if (!*stackp)
446b9343632SChandan Rajendra 		*stackp = kmalloc(sizeof(struct ovl_path), GFP_KERNEL);
447a9d01957SAmir Goldstein 	if (!*stackp) {
448a9d01957SAmir Goldstein 		dput(origin);
449a9d01957SAmir Goldstein 		return -ENOMEM;
450a9d01957SAmir Goldstein 	}
4511eff1a1dSAmir Goldstein 	**stackp = (struct ovl_path){
4521eff1a1dSAmir Goldstein 		.dentry = origin,
45394375f9dSAmir Goldstein 		.layer = &ofs->layers[i]
4541eff1a1dSAmir Goldstein 	};
455a9d01957SAmir Goldstein 
456a9d01957SAmir Goldstein 	return 0;
4572e1a5328SAmir Goldstein 
4582e1a5328SAmir Goldstein invalid:
4591bd0a3aeSlijiazi 	pr_warn_ratelimited("invalid origin (%pd2, ftype=%x, origin ftype=%x).\n",
4602e1a5328SAmir Goldstein 			    upperdentry, d_inode(upperdentry)->i_mode & S_IFMT,
4612e1a5328SAmir Goldstein 			    d_inode(origin)->i_mode & S_IFMT);
4622e1a5328SAmir Goldstein 	dput(origin);
463ffb24e3cSAmir Goldstein 	return -ESTALE;
4642e1a5328SAmir Goldstein }
4652e1a5328SAmir Goldstein 
ovl_check_origin(struct ovl_fs * ofs,struct dentry * upperdentry,struct ovl_path ** stackp)4661eff1a1dSAmir Goldstein static int ovl_check_origin(struct ovl_fs *ofs, struct dentry *upperdentry,
467d78a0dcfSyoungjun 			    struct ovl_path **stackp)
4682e1a5328SAmir Goldstein {
469610afc0bSMiklos Szeredi 	struct ovl_fh *fh = ovl_get_fh(ofs, upperdentry, OVL_XATTR_ORIGIN);
4702e1a5328SAmir Goldstein 	int err;
4712e1a5328SAmir Goldstein 
4722e1a5328SAmir Goldstein 	if (IS_ERR_OR_NULL(fh))
4732e1a5328SAmir Goldstein 		return PTR_ERR(fh);
4742e1a5328SAmir Goldstein 
4758a22efa1SAmir Goldstein 	err = ovl_check_origin_fh(ofs, fh, false, upperdentry, stackp);
4762e1a5328SAmir Goldstein 	kfree(fh);
4772e1a5328SAmir Goldstein 
4782e1a5328SAmir Goldstein 	if (err) {
4792e1a5328SAmir Goldstein 		if (err == -ESTALE)
4802e1a5328SAmir Goldstein 			return 0;
4812e1a5328SAmir Goldstein 		return err;
4822e1a5328SAmir Goldstein 	}
4832e1a5328SAmir Goldstein 
4842e1a5328SAmir Goldstein 	return 0;
485a9d01957SAmir Goldstein }
486a9d01957SAmir Goldstein 
487bbb1e54dSMiklos Szeredi /*
48805122443SAmir Goldstein  * Verify that @fh matches the file handle stored in xattr @name.
4898b88a2e6SAmir Goldstein  * Return 0 on match, -ESTALE on mismatch, < 0 on error.
4908b88a2e6SAmir Goldstein  */
ovl_verify_fh(struct ovl_fs * ofs,struct dentry * dentry,enum ovl_xattr ox,const struct ovl_fh * fh)491610afc0bSMiklos Szeredi static int ovl_verify_fh(struct ovl_fs *ofs, struct dentry *dentry,
49243d193f8SMiklos Szeredi 			 enum ovl_xattr ox, const struct ovl_fh *fh)
4938b88a2e6SAmir Goldstein {
49443d193f8SMiklos Szeredi 	struct ovl_fh *ofh = ovl_get_fh(ofs, dentry, ox);
4958b88a2e6SAmir Goldstein 	int err = 0;
4968b88a2e6SAmir Goldstein 
4978b88a2e6SAmir Goldstein 	if (!ofh)
4988b88a2e6SAmir Goldstein 		return -ENODATA;
4998b88a2e6SAmir Goldstein 
5008b88a2e6SAmir Goldstein 	if (IS_ERR(ofh))
5018b88a2e6SAmir Goldstein 		return PTR_ERR(ofh);
5028b88a2e6SAmir Goldstein 
503cbe7fba8SAmir Goldstein 	if (fh->fb.len != ofh->fb.len || memcmp(&fh->fb, &ofh->fb, fh->fb.len))
5048b88a2e6SAmir Goldstein 		err = -ESTALE;
5058b88a2e6SAmir Goldstein 
5068b88a2e6SAmir Goldstein 	kfree(ofh);
5078b88a2e6SAmir Goldstein 	return err;
5088b88a2e6SAmir Goldstein }
5098b88a2e6SAmir Goldstein 
5108b88a2e6SAmir Goldstein /*
51105122443SAmir Goldstein  * Verify that @real dentry matches the file handle stored in xattr @name.
5128b88a2e6SAmir Goldstein  *
51305122443SAmir Goldstein  * If @set is true and there is no stored file handle, encode @real and store
51405122443SAmir Goldstein  * file handle in xattr @name.
5158b88a2e6SAmir Goldstein  *
51605122443SAmir Goldstein  * Return 0 on match, -ESTALE on mismatch, -ENODATA on no xattr, < 0 on error.
5178b88a2e6SAmir Goldstein  */
ovl_verify_set_fh(struct ovl_fs * ofs,struct dentry * dentry,enum ovl_xattr ox,struct dentry * real,bool is_upper,bool set)518610afc0bSMiklos Szeredi int ovl_verify_set_fh(struct ovl_fs *ofs, struct dentry *dentry,
51943d193f8SMiklos Szeredi 		      enum ovl_xattr ox, struct dentry *real, bool is_upper,
520610afc0bSMiklos Szeredi 		      bool set)
5218b88a2e6SAmir Goldstein {
5228b88a2e6SAmir Goldstein 	struct inode *inode;
5238b88a2e6SAmir Goldstein 	struct ovl_fh *fh;
5248b88a2e6SAmir Goldstein 	int err;
5258b88a2e6SAmir Goldstein 
5261cdb0cb6SPavel Tikhomirov 	fh = ovl_encode_real_fh(ofs, real, is_upper);
5278b88a2e6SAmir Goldstein 	err = PTR_ERR(fh);
528babf4770SAmir Goldstein 	if (IS_ERR(fh)) {
529babf4770SAmir Goldstein 		fh = NULL;
5308b88a2e6SAmir Goldstein 		goto fail;
531babf4770SAmir Goldstein 	}
5328b88a2e6SAmir Goldstein 
53343d193f8SMiklos Szeredi 	err = ovl_verify_fh(ofs, dentry, ox, fh);
5348b88a2e6SAmir Goldstein 	if (set && err == -ENODATA)
535c914c0e2SAmir Goldstein 		err = ovl_setxattr(ofs, dentry, ox, fh->buf, fh->fb.len);
5368b88a2e6SAmir Goldstein 	if (err)
5378b88a2e6SAmir Goldstein 		goto fail;
5388b88a2e6SAmir Goldstein 
5398b88a2e6SAmir Goldstein out:
5408b88a2e6SAmir Goldstein 	kfree(fh);
5418b88a2e6SAmir Goldstein 	return err;
5428b88a2e6SAmir Goldstein 
5438b88a2e6SAmir Goldstein fail:
54405122443SAmir Goldstein 	inode = d_inode(real);
5451bd0a3aeSlijiazi 	pr_warn_ratelimited("failed to verify %s (%pd2, ino=%lu, err=%i)\n",
54605122443SAmir Goldstein 			    is_upper ? "upper" : "origin", real,
54705122443SAmir Goldstein 			    inode ? inode->i_ino : 0, err);
5488b88a2e6SAmir Goldstein 	goto out;
5498b88a2e6SAmir Goldstein }
5508b88a2e6SAmir Goldstein 
551e8f9e5b7SAmir Goldstein /* Get upper dentry from index */
ovl_index_upper(struct ovl_fs * ofs,struct dentry * index,bool connected)5528ea28765SAmir Goldstein struct dentry *ovl_index_upper(struct ovl_fs *ofs, struct dentry *index,
5538ea28765SAmir Goldstein 			       bool connected)
554e8f9e5b7SAmir Goldstein {
555e8f9e5b7SAmir Goldstein 	struct ovl_fh *fh;
556e8f9e5b7SAmir Goldstein 	struct dentry *upper;
557e8f9e5b7SAmir Goldstein 
558e8f9e5b7SAmir Goldstein 	if (!d_is_dir(index))
559e8f9e5b7SAmir Goldstein 		return dget(index);
560e8f9e5b7SAmir Goldstein 
561610afc0bSMiklos Szeredi 	fh = ovl_get_fh(ofs, index, OVL_XATTR_UPPER);
562e8f9e5b7SAmir Goldstein 	if (IS_ERR_OR_NULL(fh))
563e8f9e5b7SAmir Goldstein 		return ERR_CAST(fh);
564e8f9e5b7SAmir Goldstein 
5658ea28765SAmir Goldstein 	upper = ovl_decode_real_fh(ofs, fh, ovl_upper_mnt(ofs), connected);
566e8f9e5b7SAmir Goldstein 	kfree(fh);
567e8f9e5b7SAmir Goldstein 
568e8f9e5b7SAmir Goldstein 	if (IS_ERR_OR_NULL(upper))
569e8f9e5b7SAmir Goldstein 		return upper ?: ERR_PTR(-ESTALE);
570e8f9e5b7SAmir Goldstein 
571e8f9e5b7SAmir Goldstein 	if (!d_is_dir(upper)) {
5721bd0a3aeSlijiazi 		pr_warn_ratelimited("invalid index upper (%pd2, upper=%pd2).\n",
573e8f9e5b7SAmir Goldstein 				    index, upper);
574e8f9e5b7SAmir Goldstein 		dput(upper);
575e8f9e5b7SAmir Goldstein 		return ERR_PTR(-EIO);
576e8f9e5b7SAmir Goldstein 	}
577e8f9e5b7SAmir Goldstein 
578e8f9e5b7SAmir Goldstein 	return upper;
579e8f9e5b7SAmir Goldstein }
580e8f9e5b7SAmir Goldstein 
5818b88a2e6SAmir Goldstein /*
582415543d5SAmir Goldstein  * Verify that an index entry name matches the origin file handle stored in
583415543d5SAmir Goldstein  * OVL_XATTR_ORIGIN and that origin file handle can be decoded to lower path.
584415543d5SAmir Goldstein  * Return 0 on match, -ESTALE on mismatch or stale origin, < 0 on error.
585415543d5SAmir Goldstein  */
ovl_verify_index(struct ovl_fs * ofs,struct dentry * index)5861eff1a1dSAmir Goldstein int ovl_verify_index(struct ovl_fs *ofs, struct dentry *index)
587415543d5SAmir Goldstein {
588415543d5SAmir Goldstein 	struct ovl_fh *fh = NULL;
589415543d5SAmir Goldstein 	size_t len;
590b9343632SChandan Rajendra 	struct ovl_path origin = { };
591b9343632SChandan Rajendra 	struct ovl_path *stack = &origin;
592e8f9e5b7SAmir Goldstein 	struct dentry *upper = NULL;
593415543d5SAmir Goldstein 	int err;
594415543d5SAmir Goldstein 
595415543d5SAmir Goldstein 	if (!d_inode(index))
596415543d5SAmir Goldstein 		return 0;
597415543d5SAmir Goldstein 
598fa0096e3SAmir Goldstein 	err = -EINVAL;
599cbe7fba8SAmir Goldstein 	if (index->d_name.len < sizeof(struct ovl_fb)*2)
600415543d5SAmir Goldstein 		goto fail;
601415543d5SAmir Goldstein 
602415543d5SAmir Goldstein 	err = -ENOMEM;
603415543d5SAmir Goldstein 	len = index->d_name.len / 2;
604cbe7fba8SAmir Goldstein 	fh = kzalloc(len + OVL_FH_WIRE_OFFSET, GFP_KERNEL);
605415543d5SAmir Goldstein 	if (!fh)
606415543d5SAmir Goldstein 		goto fail;
607415543d5SAmir Goldstein 
608415543d5SAmir Goldstein 	err = -EINVAL;
609cbe7fba8SAmir Goldstein 	if (hex2bin(fh->buf, index->d_name.name, len))
6102e1a5328SAmir Goldstein 		goto fail;
6112e1a5328SAmir Goldstein 
612cbe7fba8SAmir Goldstein 	err = ovl_check_fb_len(&fh->fb, len);
6132e1a5328SAmir Goldstein 	if (err)
614415543d5SAmir Goldstein 		goto fail;
615415543d5SAmir Goldstein 
6167db25d36SAmir Goldstein 	/*
6177db25d36SAmir Goldstein 	 * Whiteout index entries are used as an indication that an exported
6187db25d36SAmir Goldstein 	 * overlay file handle should be treated as stale (i.e. after unlink
6197db25d36SAmir Goldstein 	 * of the overlay inode). These entries contain no origin xattr.
6207db25d36SAmir Goldstein 	 */
6217db25d36SAmir Goldstein 	if (ovl_is_whiteout(index))
6227db25d36SAmir Goldstein 		goto out;
6237db25d36SAmir Goldstein 
624e8f9e5b7SAmir Goldstein 	/*
625e8f9e5b7SAmir Goldstein 	 * Verifying directory index entries are not stale is expensive, so
626e8f9e5b7SAmir Goldstein 	 * only verify stale dir index if NFS export is enabled.
627e8f9e5b7SAmir Goldstein 	 */
628e8f9e5b7SAmir Goldstein 	if (d_is_dir(index) && !ofs->config.nfs_export)
629e8f9e5b7SAmir Goldstein 		goto out;
630e8f9e5b7SAmir Goldstein 
631e8f9e5b7SAmir Goldstein 	/*
632e8f9e5b7SAmir Goldstein 	 * Directory index entries should have 'upper' xattr pointing to the
633e8f9e5b7SAmir Goldstein 	 * real upper dir. Non-dir index entries are hardlinks to the upper
634e8f9e5b7SAmir Goldstein 	 * real inode. For non-dir index, we can read the copy up origin xattr
635e8f9e5b7SAmir Goldstein 	 * directly from the index dentry, but for dir index we first need to
636e8f9e5b7SAmir Goldstein 	 * decode the upper directory.
637e8f9e5b7SAmir Goldstein 	 */
6388ea28765SAmir Goldstein 	upper = ovl_index_upper(ofs, index, false);
639e8f9e5b7SAmir Goldstein 	if (IS_ERR_OR_NULL(upper)) {
640e8f9e5b7SAmir Goldstein 		err = PTR_ERR(upper);
64124f0b172SAmir Goldstein 		/*
64224f0b172SAmir Goldstein 		 * Directory index entries with no 'upper' xattr need to be
64324f0b172SAmir Goldstein 		 * removed. When dir index entry has a stale 'upper' xattr,
64424f0b172SAmir Goldstein 		 * we assume that upper dir was removed and we treat the dir
64524f0b172SAmir Goldstein 		 * index as orphan entry that needs to be whited out.
64624f0b172SAmir Goldstein 		 */
64724f0b172SAmir Goldstein 		if (err == -ESTALE)
64824f0b172SAmir Goldstein 			goto orphan;
64924f0b172SAmir Goldstein 		else if (!err)
650e8f9e5b7SAmir Goldstein 			err = -ESTALE;
651e8f9e5b7SAmir Goldstein 		goto fail;
652e8f9e5b7SAmir Goldstein 	}
653e8f9e5b7SAmir Goldstein 
654610afc0bSMiklos Szeredi 	err = ovl_verify_fh(ofs, upper, OVL_XATTR_ORIGIN, fh);
655e8f9e5b7SAmir Goldstein 	dput(upper);
656415543d5SAmir Goldstein 	if (err)
657415543d5SAmir Goldstein 		goto fail;
658415543d5SAmir Goldstein 
659e8f9e5b7SAmir Goldstein 	/* Check if non-dir index is orphan and don't warn before cleaning it */
660e8f9e5b7SAmir Goldstein 	if (!d_is_dir(index) && d_inode(index)->i_nlink == 1) {
6618a22efa1SAmir Goldstein 		err = ovl_check_origin_fh(ofs, fh, false, index, &stack);
662415543d5SAmir Goldstein 		if (err)
663415543d5SAmir Goldstein 			goto fail;
664415543d5SAmir Goldstein 
665610afc0bSMiklos Szeredi 		if (ovl_get_nlink(ofs, origin.dentry, index, 0) == 0)
66624f0b172SAmir Goldstein 			goto orphan;
667e8f9e5b7SAmir Goldstein 	}
668caf70cb2SAmir Goldstein 
669415543d5SAmir Goldstein out:
670e8f9e5b7SAmir Goldstein 	dput(origin.dentry);
671415543d5SAmir Goldstein 	kfree(fh);
672415543d5SAmir Goldstein 	return err;
673415543d5SAmir Goldstein 
674415543d5SAmir Goldstein fail:
6751bd0a3aeSlijiazi 	pr_warn_ratelimited("failed to verify index (%pd2, ftype=%x, err=%i)\n",
67661b67471SAmir Goldstein 			    index, d_inode(index)->i_mode & S_IFMT, err);
677415543d5SAmir Goldstein 	goto out;
67824f0b172SAmir Goldstein 
67924f0b172SAmir Goldstein orphan:
6801bd0a3aeSlijiazi 	pr_warn_ratelimited("orphan index entry (%pd2, ftype=%x, nlink=%u)\n",
68124f0b172SAmir Goldstein 			    index, d_inode(index)->i_mode & S_IFMT,
68224f0b172SAmir Goldstein 			    d_inode(index)->i_nlink);
68324f0b172SAmir Goldstein 	err = -ENOENT;
68424f0b172SAmir Goldstein 	goto out;
685415543d5SAmir Goldstein }
686415543d5SAmir Goldstein 
ovl_get_index_name_fh(struct ovl_fh * fh,struct qstr * name)68791ffe7beSAmir Goldstein static int ovl_get_index_name_fh(struct ovl_fh *fh, struct qstr *name)
68891ffe7beSAmir Goldstein {
68991ffe7beSAmir Goldstein 	char *n, *s;
69091ffe7beSAmir Goldstein 
691cbe7fba8SAmir Goldstein 	n = kcalloc(fh->fb.len, 2, GFP_KERNEL);
69291ffe7beSAmir Goldstein 	if (!n)
69391ffe7beSAmir Goldstein 		return -ENOMEM;
69491ffe7beSAmir Goldstein 
695cbe7fba8SAmir Goldstein 	s  = bin2hex(n, fh->buf, fh->fb.len);
69691ffe7beSAmir Goldstein 	*name = (struct qstr) QSTR_INIT(n, s - n);
69791ffe7beSAmir Goldstein 
69891ffe7beSAmir Goldstein 	return 0;
69991ffe7beSAmir Goldstein 
70091ffe7beSAmir Goldstein }
70191ffe7beSAmir Goldstein 
702415543d5SAmir Goldstein /*
703359f392cSAmir Goldstein  * Lookup in indexdir for the index entry of a lower real inode or a copy up
704359f392cSAmir Goldstein  * origin inode. The index entry name is the hex representation of the lower
705359f392cSAmir Goldstein  * inode file handle.
706359f392cSAmir Goldstein  *
707359f392cSAmir Goldstein  * If the index dentry in negative, then either no lower aliases have been
708359f392cSAmir Goldstein  * copied up yet, or aliases have been copied up in older kernels and are
709359f392cSAmir Goldstein  * not indexed.
710359f392cSAmir Goldstein  *
711359f392cSAmir Goldstein  * If the index dentry for a copy up origin inode is positive, but points
712359f392cSAmir Goldstein  * to an inode different than the upper inode, then either the upper inode
713359f392cSAmir Goldstein  * has been copied up and not indexed or it was indexed, but since then
7144f119628SWilliam Dean  * index dir was cleared. Either way, that index cannot be used to identify
715359f392cSAmir Goldstein  * the overlay inode.
716359f392cSAmir Goldstein  */
ovl_get_index_name(struct ovl_fs * ofs,struct dentry * origin,struct qstr * name)7171cdb0cb6SPavel Tikhomirov int ovl_get_index_name(struct ovl_fs *ofs, struct dentry *origin,
7181cdb0cb6SPavel Tikhomirov 		       struct qstr *name)
719359f392cSAmir Goldstein {
720359f392cSAmir Goldstein 	struct ovl_fh *fh;
72191ffe7beSAmir Goldstein 	int err;
722359f392cSAmir Goldstein 
7231cdb0cb6SPavel Tikhomirov 	fh = ovl_encode_real_fh(ofs, origin, false);
724359f392cSAmir Goldstein 	if (IS_ERR(fh))
725359f392cSAmir Goldstein 		return PTR_ERR(fh);
726359f392cSAmir Goldstein 
72791ffe7beSAmir Goldstein 	err = ovl_get_index_name_fh(fh, name);
72891ffe7beSAmir Goldstein 
729359f392cSAmir Goldstein 	kfree(fh);
730359f392cSAmir Goldstein 	return err;
73191ffe7beSAmir Goldstein }
732359f392cSAmir Goldstein 
73391ffe7beSAmir Goldstein /* Lookup index by file handle for NFS export */
ovl_get_index_fh(struct ovl_fs * ofs,struct ovl_fh * fh)73491ffe7beSAmir Goldstein struct dentry *ovl_get_index_fh(struct ovl_fs *ofs, struct ovl_fh *fh)
73591ffe7beSAmir Goldstein {
73691ffe7beSAmir Goldstein 	struct dentry *index;
73791ffe7beSAmir Goldstein 	struct qstr name;
73891ffe7beSAmir Goldstein 	int err;
73991ffe7beSAmir Goldstein 
74091ffe7beSAmir Goldstein 	err = ovl_get_index_name_fh(fh, &name);
74191ffe7beSAmir Goldstein 	if (err)
74291ffe7beSAmir Goldstein 		return ERR_PTR(err);
74391ffe7beSAmir Goldstein 
7446c2d4798SAl Viro 	index = lookup_positive_unlocked(name.name, ofs->indexdir, name.len);
74591ffe7beSAmir Goldstein 	kfree(name.name);
74691ffe7beSAmir Goldstein 	if (IS_ERR(index)) {
74791ffe7beSAmir Goldstein 		if (PTR_ERR(index) == -ENOENT)
74891ffe7beSAmir Goldstein 			index = NULL;
74991ffe7beSAmir Goldstein 		return index;
75091ffe7beSAmir Goldstein 	}
75191ffe7beSAmir Goldstein 
7526c2d4798SAl Viro 	if (ovl_is_whiteout(index))
75391ffe7beSAmir Goldstein 		err = -ESTALE;
75491ffe7beSAmir Goldstein 	else if (ovl_dentry_weird(index))
75591ffe7beSAmir Goldstein 		err = -EIO;
75691ffe7beSAmir Goldstein 	else
75791ffe7beSAmir Goldstein 		return index;
75891ffe7beSAmir Goldstein 
75991ffe7beSAmir Goldstein 	dput(index);
76091ffe7beSAmir Goldstein 	return ERR_PTR(err);
761359f392cSAmir Goldstein }
762359f392cSAmir Goldstein 
ovl_lookup_index(struct ovl_fs * ofs,struct dentry * upper,struct dentry * origin,bool verify)76306170154SAmir Goldstein struct dentry *ovl_lookup_index(struct ovl_fs *ofs, struct dentry *upper,
76406170154SAmir Goldstein 				struct dentry *origin, bool verify)
765359f392cSAmir Goldstein {
766359f392cSAmir Goldstein 	struct dentry *index;
767359f392cSAmir Goldstein 	struct inode *inode;
768359f392cSAmir Goldstein 	struct qstr name;
769ad1d615cSAmir Goldstein 	bool is_dir = d_is_dir(origin);
770359f392cSAmir Goldstein 	int err;
771359f392cSAmir Goldstein 
7721cdb0cb6SPavel Tikhomirov 	err = ovl_get_index_name(ofs, origin, &name);
773359f392cSAmir Goldstein 	if (err)
774359f392cSAmir Goldstein 		return ERR_PTR(err);
775359f392cSAmir Goldstein 
7764609e1f1SChristian Brauner 	index = lookup_one_positive_unlocked(ovl_upper_mnt_idmap(ofs), name.name,
777ba9ea771SChristian Brauner 					     ofs->indexdir, name.len);
778359f392cSAmir Goldstein 	if (IS_ERR(index)) {
779e0082a0fSAmir Goldstein 		err = PTR_ERR(index);
7807937a56fSAmir Goldstein 		if (err == -ENOENT) {
7817937a56fSAmir Goldstein 			index = NULL;
7827937a56fSAmir Goldstein 			goto out;
7837937a56fSAmir Goldstein 		}
7841bd0a3aeSlijiazi 		pr_warn_ratelimited("failed inode index lookup (ino=%lu, key=%.*s, err=%i);\n"
785359f392cSAmir Goldstein 				    "overlayfs: mount with '-o index=off' to disable inodes index.\n",
786359f392cSAmir Goldstein 				    d_inode(origin)->i_ino, name.len, name.name,
787359f392cSAmir Goldstein 				    err);
788359f392cSAmir Goldstein 		goto out;
789359f392cSAmir Goldstein 	}
790359f392cSAmir Goldstein 
7910e082555SAmir Goldstein 	inode = d_inode(index);
7926c2d4798SAl Viro 	if (ovl_is_whiteout(index) && !verify) {
79306170154SAmir Goldstein 		/*
79406170154SAmir Goldstein 		 * When index lookup is called with !verify for decoding an
79506170154SAmir Goldstein 		 * overlay file handle, a whiteout index implies that decode
79606170154SAmir Goldstein 		 * should treat file handle as stale and no need to print a
79706170154SAmir Goldstein 		 * warning about it.
79806170154SAmir Goldstein 		 */
79906170154SAmir Goldstein 		dput(index);
80006170154SAmir Goldstein 		index = ERR_PTR(-ESTALE);
80106170154SAmir Goldstein 		goto out;
8020e082555SAmir Goldstein 	} else if (ovl_dentry_weird(index) || ovl_is_whiteout(index) ||
8036e3e2c43SAl Viro 		   inode_wrong_type(inode, d_inode(origin)->i_mode)) {
8040e082555SAmir Goldstein 		/*
8050e082555SAmir Goldstein 		 * Index should always be of the same file type as origin
8060e082555SAmir Goldstein 		 * except for the case of a whiteout index. A whiteout
8070e082555SAmir Goldstein 		 * index should only exist if all lower aliases have been
8080e082555SAmir Goldstein 		 * unlinked, which means that finding a lower origin on lookup
8090e082555SAmir Goldstein 		 * whose index is a whiteout should be treated as an error.
8100e082555SAmir Goldstein 		 */
8111bd0a3aeSlijiazi 		pr_warn_ratelimited("bad index found (index=%pd2, ftype=%x, origin ftype=%x).\n",
8120e082555SAmir Goldstein 				    index, d_inode(index)->i_mode & S_IFMT,
8130e082555SAmir Goldstein 				    d_inode(origin)->i_mode & S_IFMT);
814359f392cSAmir Goldstein 		goto fail;
81506170154SAmir Goldstein 	} else if (is_dir && verify) {
816ad1d615cSAmir Goldstein 		if (!upper) {
8171bd0a3aeSlijiazi 			pr_warn_ratelimited("suspected uncovered redirected dir found (origin=%pd2, index=%pd2).\n",
818ad1d615cSAmir Goldstein 					    origin, index);
819ad1d615cSAmir Goldstein 			goto fail;
820359f392cSAmir Goldstein 		}
821359f392cSAmir Goldstein 
822ad1d615cSAmir Goldstein 		/* Verify that dir index 'upper' xattr points to upper dir */
823610afc0bSMiklos Szeredi 		err = ovl_verify_upper(ofs, index, upper, false);
824ad1d615cSAmir Goldstein 		if (err) {
825ad1d615cSAmir Goldstein 			if (err == -ESTALE) {
8261bd0a3aeSlijiazi 				pr_warn_ratelimited("suspected multiply redirected dir found (upper=%pd2, origin=%pd2, index=%pd2).\n",
827ad1d615cSAmir Goldstein 						    upper, origin, index);
828ad1d615cSAmir Goldstein 			}
829ad1d615cSAmir Goldstein 			goto fail;
830ad1d615cSAmir Goldstein 		}
831ad1d615cSAmir Goldstein 	} else if (upper && d_inode(upper) != inode) {
832ad1d615cSAmir Goldstein 		goto out_dput;
833ad1d615cSAmir Goldstein 	}
834359f392cSAmir Goldstein out:
835359f392cSAmir Goldstein 	kfree(name.name);
836359f392cSAmir Goldstein 	return index;
837359f392cSAmir Goldstein 
8386eaf0111SAmir Goldstein out_dput:
8396eaf0111SAmir Goldstein 	dput(index);
8406eaf0111SAmir Goldstein 	index = NULL;
8416eaf0111SAmir Goldstein 	goto out;
8426eaf0111SAmir Goldstein 
843359f392cSAmir Goldstein fail:
844359f392cSAmir Goldstein 	dput(index);
845359f392cSAmir Goldstein 	index = ERR_PTR(-EIO);
846359f392cSAmir Goldstein 	goto out;
847359f392cSAmir Goldstein }
848359f392cSAmir Goldstein 
849359f392cSAmir Goldstein /*
850bbb1e54dSMiklos Szeredi  * Returns next layer in stack starting from top.
851bbb1e54dSMiklos Szeredi  * Returns -1 if this is the last layer.
852bbb1e54dSMiklos Szeredi  */
ovl_path_next(int idx,struct dentry * dentry,struct path * path)853bbb1e54dSMiklos Szeredi int ovl_path_next(int idx, struct dentry *dentry, struct path *path)
854bbb1e54dSMiklos Szeredi {
855a6ff2bc0SAmir Goldstein 	struct ovl_entry *oe = OVL_E(dentry);
8565522c9c7SAmir Goldstein 	struct ovl_path *lowerstack = ovl_lowerstack(oe);
857bbb1e54dSMiklos Szeredi 
858bbb1e54dSMiklos Szeredi 	BUG_ON(idx < 0);
859bbb1e54dSMiklos Szeredi 	if (idx == 0) {
860bbb1e54dSMiklos Szeredi 		ovl_path_upper(dentry, path);
861bbb1e54dSMiklos Szeredi 		if (path->dentry)
8625522c9c7SAmir Goldstein 			return ovl_numlower(oe) ? 1 : -1;
863bbb1e54dSMiklos Szeredi 		idx++;
864bbb1e54dSMiklos Szeredi 	}
8655522c9c7SAmir Goldstein 	BUG_ON(idx > ovl_numlower(oe));
8665522c9c7SAmir Goldstein 	path->dentry = lowerstack[idx - 1].dentry;
8675522c9c7SAmir Goldstein 	path->mnt = lowerstack[idx - 1].layer->mnt;
868bbb1e54dSMiklos Szeredi 
8695522c9c7SAmir Goldstein 	return (idx < ovl_numlower(oe)) ? idx + 1 : -1;
870bbb1e54dSMiklos Szeredi }
871bbb1e54dSMiklos Szeredi 
8729678e630SAmir Goldstein /* Fix missing 'origin' xattr */
ovl_fix_origin(struct ovl_fs * ofs,struct dentry * dentry,struct dentry * lower,struct dentry * upper)873610afc0bSMiklos Szeredi static int ovl_fix_origin(struct ovl_fs *ofs, struct dentry *dentry,
874610afc0bSMiklos Szeredi 			  struct dentry *lower, struct dentry *upper)
8759678e630SAmir Goldstein {
8769678e630SAmir Goldstein 	int err;
8779678e630SAmir Goldstein 
878610afc0bSMiklos Szeredi 	if (ovl_check_origin_xattr(ofs, upper))
8799678e630SAmir Goldstein 		return 0;
8809678e630SAmir Goldstein 
8819678e630SAmir Goldstein 	err = ovl_want_write(dentry);
8829678e630SAmir Goldstein 	if (err)
8839678e630SAmir Goldstein 		return err;
8849678e630SAmir Goldstein 
885a0c236b1SAmir Goldstein 	err = ovl_set_origin(ofs, lower, upper);
8869678e630SAmir Goldstein 	if (!err)
8879678e630SAmir Goldstein 		err = ovl_set_impure(dentry->d_parent, upper->d_parent);
8889678e630SAmir Goldstein 
8899678e630SAmir Goldstein 	ovl_drop_write(dentry);
8909678e630SAmir Goldstein 	return err;
8919678e630SAmir Goldstein }
8929678e630SAmir Goldstein 
ovl_maybe_validate_verity(struct dentry * dentry)893184996e9SAlexander Larsson static int ovl_maybe_validate_verity(struct dentry *dentry)
894184996e9SAlexander Larsson {
895*f01d0889SAndrea Righi 	struct ovl_fs *ofs = OVL_FS(dentry->d_sb);
896184996e9SAlexander Larsson 	struct inode *inode = d_inode(dentry);
897184996e9SAlexander Larsson 	struct path datapath, metapath;
898184996e9SAlexander Larsson 	int err;
899184996e9SAlexander Larsson 
900184996e9SAlexander Larsson 	if (!ofs->config.verity_mode ||
901184996e9SAlexander Larsson 	    !ovl_is_metacopy_dentry(dentry) ||
902184996e9SAlexander Larsson 	    ovl_test_flag(OVL_VERIFIED_DIGEST, inode))
903184996e9SAlexander Larsson 		return 0;
904184996e9SAlexander Larsson 
905184996e9SAlexander Larsson 	if (!ovl_test_flag(OVL_HAS_DIGEST, inode)) {
906184996e9SAlexander Larsson 		if (ofs->config.verity_mode == OVL_VERITY_REQUIRE) {
907184996e9SAlexander Larsson 			pr_warn_ratelimited("metacopy file '%pd' has no digest specified\n",
908184996e9SAlexander Larsson 					    dentry);
909184996e9SAlexander Larsson 			return -EIO;
910184996e9SAlexander Larsson 		}
911184996e9SAlexander Larsson 		return 0;
912184996e9SAlexander Larsson 	}
913184996e9SAlexander Larsson 
914184996e9SAlexander Larsson 	ovl_path_lowerdata(dentry, &datapath);
915184996e9SAlexander Larsson 	if (!datapath.dentry)
916184996e9SAlexander Larsson 		return -EIO;
917184996e9SAlexander Larsson 
918184996e9SAlexander Larsson 	ovl_path_real(dentry, &metapath);
919184996e9SAlexander Larsson 	if (!metapath.dentry)
920184996e9SAlexander Larsson 		return -EIO;
921184996e9SAlexander Larsson 
922184996e9SAlexander Larsson 	err = ovl_inode_lock_interruptible(inode);
923184996e9SAlexander Larsson 	if (err)
924184996e9SAlexander Larsson 		return err;
925184996e9SAlexander Larsson 
926184996e9SAlexander Larsson 	if (!ovl_test_flag(OVL_VERIFIED_DIGEST, inode)) {
927184996e9SAlexander Larsson 		const struct cred *old_cred;
928184996e9SAlexander Larsson 
929184996e9SAlexander Larsson 		old_cred = ovl_override_creds(dentry->d_sb);
930184996e9SAlexander Larsson 
931184996e9SAlexander Larsson 		err = ovl_validate_verity(ofs, &metapath, &datapath);
932184996e9SAlexander Larsson 		if (err == 0)
933184996e9SAlexander Larsson 			ovl_set_flag(OVL_VERIFIED_DIGEST, inode);
934184996e9SAlexander Larsson 
935184996e9SAlexander Larsson 		revert_creds(old_cred);
936184996e9SAlexander Larsson 	}
937184996e9SAlexander Larsson 
938184996e9SAlexander Larsson 	ovl_inode_unlock(inode);
939184996e9SAlexander Larsson 
940184996e9SAlexander Larsson 	return err;
941184996e9SAlexander Larsson }
942184996e9SAlexander Larsson 
94342dd69aeSAmir Goldstein /* Lazy lookup of lowerdata */
ovl_maybe_lookup_lowerdata(struct dentry * dentry)944184996e9SAlexander Larsson static int ovl_maybe_lookup_lowerdata(struct dentry *dentry)
94542dd69aeSAmir Goldstein {
94642dd69aeSAmir Goldstein 	struct inode *inode = d_inode(dentry);
94742dd69aeSAmir Goldstein 	const char *redirect = ovl_lowerdata_redirect(inode);
94842dd69aeSAmir Goldstein 	struct ovl_path datapath = {};
94942dd69aeSAmir Goldstein 	const struct cred *old_cred;
95042dd69aeSAmir Goldstein 	int err;
95142dd69aeSAmir Goldstein 
95242dd69aeSAmir Goldstein 	if (!redirect || ovl_dentry_lowerdata(dentry))
95342dd69aeSAmir Goldstein 		return 0;
95442dd69aeSAmir Goldstein 
95542dd69aeSAmir Goldstein 	if (redirect[0] != '/')
95642dd69aeSAmir Goldstein 		return -EIO;
95742dd69aeSAmir Goldstein 
95842dd69aeSAmir Goldstein 	err = ovl_inode_lock_interruptible(inode);
95942dd69aeSAmir Goldstein 	if (err)
96042dd69aeSAmir Goldstein 		return err;
96142dd69aeSAmir Goldstein 
96242dd69aeSAmir Goldstein 	err = 0;
96342dd69aeSAmir Goldstein 	/* Someone got here before us? */
96442dd69aeSAmir Goldstein 	if (ovl_dentry_lowerdata(dentry))
96542dd69aeSAmir Goldstein 		goto out;
96642dd69aeSAmir Goldstein 
96742dd69aeSAmir Goldstein 	old_cred = ovl_override_creds(dentry->d_sb);
96842dd69aeSAmir Goldstein 	err = ovl_lookup_data_layers(dentry, redirect, &datapath);
96942dd69aeSAmir Goldstein 	revert_creds(old_cred);
97042dd69aeSAmir Goldstein 	if (err)
97142dd69aeSAmir Goldstein 		goto out_err;
97242dd69aeSAmir Goldstein 
97342dd69aeSAmir Goldstein 	err = ovl_dentry_set_lowerdata(dentry, &datapath);
97442dd69aeSAmir Goldstein 	if (err)
97542dd69aeSAmir Goldstein 		goto out_err;
97642dd69aeSAmir Goldstein 
97742dd69aeSAmir Goldstein out:
97842dd69aeSAmir Goldstein 	ovl_inode_unlock(inode);
97942dd69aeSAmir Goldstein 	dput(datapath.dentry);
98042dd69aeSAmir Goldstein 
98142dd69aeSAmir Goldstein 	return err;
98242dd69aeSAmir Goldstein 
98342dd69aeSAmir Goldstein out_err:
98442dd69aeSAmir Goldstein 	pr_warn_ratelimited("lazy lowerdata lookup failed (%pd2, err=%i)\n",
98542dd69aeSAmir Goldstein 			    dentry, err);
98642dd69aeSAmir Goldstein 	goto out;
98742dd69aeSAmir Goldstein }
98842dd69aeSAmir Goldstein 
ovl_verify_lowerdata(struct dentry * dentry)989184996e9SAlexander Larsson int ovl_verify_lowerdata(struct dentry *dentry)
990184996e9SAlexander Larsson {
991184996e9SAlexander Larsson 	int err;
992184996e9SAlexander Larsson 
993184996e9SAlexander Larsson 	err = ovl_maybe_lookup_lowerdata(dentry);
994184996e9SAlexander Larsson 	if (err)
995184996e9SAlexander Larsson 		return err;
996184996e9SAlexander Larsson 
997184996e9SAlexander Larsson 	return ovl_maybe_validate_verity(dentry);
998184996e9SAlexander Larsson }
999184996e9SAlexander Larsson 
ovl_lookup(struct inode * dir,struct dentry * dentry,unsigned int flags)1000bbb1e54dSMiklos Szeredi struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
1001bbb1e54dSMiklos Szeredi 			  unsigned int flags)
1002bbb1e54dSMiklos Szeredi {
10030af950f5SAmir Goldstein 	struct ovl_entry *oe = NULL;
1004bbb1e54dSMiklos Szeredi 	const struct cred *old_cred;
1005*f01d0889SAndrea Righi 	struct ovl_fs *ofs = OVL_FS(dentry->d_sb);
1006a6ff2bc0SAmir Goldstein 	struct ovl_entry *poe = OVL_E(dentry->d_parent);
1007a6ff2bc0SAmir Goldstein 	struct ovl_entry *roe = OVL_E(dentry->d_sb->s_root);
10089d3dfea3SVivek Goyal 	struct ovl_path *stack = NULL, *origin_path = NULL;
1009bbb1e54dSMiklos Szeredi 	struct dentry *upperdir, *upperdentry = NULL;
1010ad1d615cSAmir Goldstein 	struct dentry *origin = NULL;
1011359f392cSAmir Goldstein 	struct dentry *index = NULL;
1012bbb1e54dSMiklos Szeredi 	unsigned int ctr = 0;
1013bbb1e54dSMiklos Szeredi 	struct inode *inode = NULL;
1014bbb1e54dSMiklos Szeredi 	bool upperopaque = false;
101502b69b28SMiklos Szeredi 	char *upperredirect = NULL;
1016bbb1e54dSMiklos Szeredi 	struct dentry *this;
1017bbb1e54dSMiklos Szeredi 	unsigned int i;
1018bbb1e54dSMiklos Szeredi 	int err;
10196815f479SVivek Goyal 	bool uppermetacopy = false;
1020184996e9SAlexander Larsson 	int metacopy_size = 0;
1021e28edc46SMiklos Szeredi 	struct ovl_lookup_data d = {
1022146d62e5SAmir Goldstein 		.sb = dentry->d_sb,
1023e28edc46SMiklos Szeredi 		.name = dentry->d_name,
1024e28edc46SMiklos Szeredi 		.is_dir = false,
1025e28edc46SMiklos Szeredi 		.opaque = false,
1026e28edc46SMiklos Szeredi 		.stop = false,
1027af5f2396SAmir Goldstein 		.last = ovl_redirect_follow(ofs) ? false : !ovl_numlower(poe),
102802b69b28SMiklos Szeredi 		.redirect = NULL,
1029bf070890SAlexander Larsson 		.metacopy = 0,
1030e28edc46SMiklos Szeredi 	};
1031bbb1e54dSMiklos Szeredi 
10326b2d5fe4SMiklos Szeredi 	if (dentry->d_name.len > ofs->namelen)
10336b2d5fe4SMiklos Szeredi 		return ERR_PTR(-ENAMETOOLONG);
10346b2d5fe4SMiklos Szeredi 
1035bbb1e54dSMiklos Szeredi 	old_cred = ovl_override_creds(dentry->d_sb);
103609d8b586SMiklos Szeredi 	upperdir = ovl_dentry_upper(dentry->d_parent);
1037bbb1e54dSMiklos Szeredi 	if (upperdir) {
1038dad7017aSChristian Brauner 		d.mnt = ovl_upper_mnt(ofs);
10391434a65eSChengguang Xu 		err = ovl_lookup_layer(upperdir, &d, &upperdentry, true);
1040e28edc46SMiklos Szeredi 		if (err)
1041bbb1e54dSMiklos Szeredi 			goto out;
1042bbb1e54dSMiklos Szeredi 
1043bccece1eSMiklos Szeredi 		if (upperdentry && upperdentry->d_flags & DCACHE_OP_REAL) {
1044e28edc46SMiklos Szeredi 			dput(upperdentry);
1045bbb1e54dSMiklos Szeredi 			err = -EREMOTE;
1046bbb1e54dSMiklos Szeredi 			goto out;
1047bbb1e54dSMiklos Szeredi 		}
1048a9d01957SAmir Goldstein 		if (upperdentry && !d.is_dir) {
1049f7d3dacaSAmir Goldstein 			/*
1050f7d3dacaSAmir Goldstein 			 * Lookup copy up origin by decoding origin file handle.
1051f7d3dacaSAmir Goldstein 			 * We may get a disconnected dentry, which is fine,
1052f7d3dacaSAmir Goldstein 			 * because we only need to hold the origin inode in
1053f7d3dacaSAmir Goldstein 			 * cache and use its inode number.  We may even get a
1054f7d3dacaSAmir Goldstein 			 * connected dentry, that is not under any of the lower
1055f7d3dacaSAmir Goldstein 			 * layers root.  That is also fine for using it's inode
1056f7d3dacaSAmir Goldstein 			 * number - it's the same as if we held a reference
1057f7d3dacaSAmir Goldstein 			 * to a dentry in lower layer that was moved under us.
1058f7d3dacaSAmir Goldstein 			 */
1059d78a0dcfSyoungjun 			err = ovl_check_origin(ofs, upperdentry, &origin_path);
1060a9d01957SAmir Goldstein 			if (err)
10615455f92bSVivek Goyal 				goto out_put_upper;
10629d3dfea3SVivek Goyal 
10639d3dfea3SVivek Goyal 			if (d.metacopy)
10646815f479SVivek Goyal 				uppermetacopy = true;
1065184996e9SAlexander Larsson 			metacopy_size = d.metacopy;
1066a9d01957SAmir Goldstein 		}
106702b69b28SMiklos Szeredi 
106802b69b28SMiklos Szeredi 		if (d.redirect) {
10690ce5cdc9SDan Carpenter 			err = -ENOMEM;
107002b69b28SMiklos Szeredi 			upperredirect = kstrdup(d.redirect, GFP_KERNEL);
107102b69b28SMiklos Szeredi 			if (!upperredirect)
107202b69b28SMiklos Szeredi 				goto out_put_upper;
107302b69b28SMiklos Szeredi 			if (d.redirect[0] == '/')
1074c22205d0SAmir Goldstein 				poe = roe;
107502b69b28SMiklos Szeredi 		}
1076e28edc46SMiklos Szeredi 		upperopaque = d.opaque;
1077bbb1e54dSMiklos Szeredi 	}
1078bbb1e54dSMiklos Szeredi 
10795522c9c7SAmir Goldstein 	if (!d.stop && ovl_numlower(poe)) {
1080bbb1e54dSMiklos Szeredi 		err = -ENOMEM;
1081163db0daSAmir Goldstein 		stack = ovl_stack_alloc(ofs->numlayer - 1);
1082bbb1e54dSMiklos Szeredi 		if (!stack)
1083bbb1e54dSMiklos Szeredi 			goto out_put_upper;
1084bbb1e54dSMiklos Szeredi 	}
1085bbb1e54dSMiklos Szeredi 
10865522c9c7SAmir Goldstein 	for (i = 0; !d.stop && i < ovl_numlower(poe); i++) {
10875522c9c7SAmir Goldstein 		struct ovl_path lower = ovl_lowerstack(poe)[i];
1088bbb1e54dSMiklos Szeredi 
1089af5f2396SAmir Goldstein 		if (!ovl_redirect_follow(ofs))
10905522c9c7SAmir Goldstein 			d.last = i == ovl_numlower(poe) - 1;
10915436ab0aSAmir Goldstein 		else if (d.is_dir || !ofs->numdatalayer)
10925522c9c7SAmir Goldstein 			d.last = lower.layer->idx == ovl_numlower(roe);
1093452061fdSVivek Goyal 
1094dad7017aSChristian Brauner 		d.mnt = lower.layer->mnt;
10951434a65eSChengguang Xu 		err = ovl_lookup_layer(lower.dentry, &d, &this, false);
1096e28edc46SMiklos Szeredi 		if (err)
1097bbb1e54dSMiklos Szeredi 			goto out_put;
10986b2d5fe4SMiklos Szeredi 
1099bbb1e54dSMiklos Szeredi 		if (!this)
1100bbb1e54dSMiklos Szeredi 			continue;
1101bbb1e54dSMiklos Szeredi 
11026815f479SVivek Goyal 		if ((uppermetacopy || d.metacopy) && !ofs->config.metacopy) {
1103eaab1d45SMickaël Salaün 			dput(this);
11046815f479SVivek Goyal 			err = -EPERM;
11056815f479SVivek Goyal 			pr_warn_ratelimited("refusing to follow metacopy origin for (%pd2)\n", dentry);
11066815f479SVivek Goyal 			goto out_put;
11076815f479SVivek Goyal 		}
11086815f479SVivek Goyal 
11096815f479SVivek Goyal 		/*
11109678e630SAmir Goldstein 		 * If no origin fh is stored in upper of a merge dir, store fh
11119678e630SAmir Goldstein 		 * of lower dir and set upper parent "impure".
11129678e630SAmir Goldstein 		 */
11139d3dfea3SVivek Goyal 		if (upperdentry && !ctr && !ofs->noxattr && d.is_dir) {
1114610afc0bSMiklos Szeredi 			err = ovl_fix_origin(ofs, dentry, this, upperdentry);
11159678e630SAmir Goldstein 			if (err) {
11169678e630SAmir Goldstein 				dput(this);
11179678e630SAmir Goldstein 				goto out_put;
11189678e630SAmir Goldstein 			}
11199678e630SAmir Goldstein 		}
11209678e630SAmir Goldstein 
112137b12916SAmir Goldstein 		/*
112237b12916SAmir Goldstein 		 * When "verify_lower" feature is enabled, do not merge with a
1123ad1d615cSAmir Goldstein 		 * lower dir that does not match a stored origin xattr. In any
1124ad1d615cSAmir Goldstein 		 * case, only verified origin is used for index lookup.
11259d3dfea3SVivek Goyal 		 *
11269d3dfea3SVivek Goyal 		 * For non-dir dentry, if index=on, then ensure origin
11279d3dfea3SVivek Goyal 		 * matches the dentry found using path based lookup,
11289d3dfea3SVivek Goyal 		 * otherwise error out.
112937b12916SAmir Goldstein 		 */
11309d3dfea3SVivek Goyal 		if (upperdentry && !ctr &&
11319d3dfea3SVivek Goyal 		    ((d.is_dir && ovl_verify_lower(dentry->d_sb)) ||
11329d3dfea3SVivek Goyal 		     (!d.is_dir && ofs->config.index && origin_path))) {
1133610afc0bSMiklos Szeredi 			err = ovl_verify_origin(ofs, upperdentry, this, false);
113437b12916SAmir Goldstein 			if (err) {
113537b12916SAmir Goldstein 				dput(this);
11369d3dfea3SVivek Goyal 				if (d.is_dir)
113737b12916SAmir Goldstein 					break;
11389d3dfea3SVivek Goyal 				goto out_put;
11399d3dfea3SVivek Goyal 			}
11409d3dfea3SVivek Goyal 			origin = this;
114137b12916SAmir Goldstein 		}
1142ad1d615cSAmir Goldstein 
1143184996e9SAlexander Larsson 		if (!upperdentry && !d.is_dir && !ctr && d.metacopy)
1144184996e9SAlexander Larsson 			metacopy_size = d.metacopy;
1145184996e9SAlexander Larsson 
114621d8d66aSVivek Goyal 		if (d.metacopy && ctr) {
114721d8d66aSVivek Goyal 			/*
114821d8d66aSVivek Goyal 			 * Do not store intermediate metacopy dentries in
114921d8d66aSVivek Goyal 			 * lower chain, except top most lower metacopy dentry.
115021d8d66aSVivek Goyal 			 * Continue the loop so that if there is an absolute
115121d8d66aSVivek Goyal 			 * redirect on this dentry, poe can be reset to roe.
115221d8d66aSVivek Goyal 			 */
115321d8d66aSVivek Goyal 			dput(this);
115421d8d66aSVivek Goyal 			this = NULL;
115521d8d66aSVivek Goyal 		} else {
1156bbb1e54dSMiklos Szeredi 			stack[ctr].dentry = this;
1157b9343632SChandan Rajendra 			stack[ctr].layer = lower.layer;
1158bbb1e54dSMiklos Szeredi 			ctr++;
115921d8d66aSVivek Goyal 		}
116002b69b28SMiklos Szeredi 
1161438c84c2SMiklos Szeredi 		/*
1162438c84c2SMiklos Szeredi 		 * Following redirects can have security consequences: it's like
1163438c84c2SMiklos Szeredi 		 * a symlink into the lower layer without the permission checks.
1164438c84c2SMiklos Szeredi 		 * This is only a problem if the upper layer is untrusted (e.g
1165438c84c2SMiklos Szeredi 		 * comes from an USB drive).  This can allow a non-readable file
1166438c84c2SMiklos Szeredi 		 * or directory to become readable.
1167438c84c2SMiklos Szeredi 		 *
1168438c84c2SMiklos Szeredi 		 * Only following redirects when redirects are enabled disables
1169438c84c2SMiklos Szeredi 		 * this attack vector when not necessary.
1170438c84c2SMiklos Szeredi 		 */
1171438c84c2SMiklos Szeredi 		err = -EPERM;
1172af5f2396SAmir Goldstein 		if (d.redirect && !ovl_redirect_follow(ofs)) {
11731bd0a3aeSlijiazi 			pr_warn_ratelimited("refusing to follow redirect for (%pd2)\n",
1174f8167817SAmir Goldstein 					    dentry);
1175438c84c2SMiklos Szeredi 			goto out_put;
1176438c84c2SMiklos Szeredi 		}
1177438c84c2SMiklos Szeredi 
1178d1fe96c0SVivek Goyal 		if (d.stop)
1179d1fe96c0SVivek Goyal 			break;
1180d1fe96c0SVivek Goyal 
1181c22205d0SAmir Goldstein 		if (d.redirect && d.redirect[0] == '/' && poe != roe) {
1182c22205d0SAmir Goldstein 			poe = roe;
118302b69b28SMiklos Szeredi 			/* Find the current layer on the root dentry */
1184d583ed7dSAmir Goldstein 			i = lower.layer->idx - 1;
118502b69b28SMiklos Szeredi 		}
1186bbb1e54dSMiklos Szeredi 	}
1187bbb1e54dSMiklos Szeredi 
118842dd69aeSAmir Goldstein 	/* Defer lookup of lowerdata in data-only layers to first access */
11895436ab0aSAmir Goldstein 	if (d.metacopy && ctr && ofs->numdatalayer && d.absolute_redirect) {
1190bf070890SAlexander Larsson 		d.metacopy = 0;
11915436ab0aSAmir Goldstein 		ctr++;
11925436ab0aSAmir Goldstein 	}
11935436ab0aSAmir Goldstein 
11949d3dfea3SVivek Goyal 	/*
11956815f479SVivek Goyal 	 * For regular non-metacopy upper dentries, there is no lower
11966815f479SVivek Goyal 	 * path based lookup, hence ctr will be zero. If a dentry is found
11976815f479SVivek Goyal 	 * using ORIGIN xattr on upper, install it in stack.
11986815f479SVivek Goyal 	 *
11996815f479SVivek Goyal 	 * For metacopy dentry, path based lookup will find lower dentries.
12006815f479SVivek Goyal 	 * Just make sure a corresponding data dentry has been found.
12019d3dfea3SVivek Goyal 	 */
12026815f479SVivek Goyal 	if (d.metacopy || (uppermetacopy && !ctr)) {
12030a8d0b64SKevin Locke 		pr_warn_ratelimited("metacopy with no lower data found - abort lookup (%pd2)\n",
12040a8d0b64SKevin Locke 				    dentry);
12059d3dfea3SVivek Goyal 		err = -EIO;
12069d3dfea3SVivek Goyal 		goto out_put;
12079d3dfea3SVivek Goyal 	} else if (!d.is_dir && upperdentry && !ctr && origin_path) {
12089d3dfea3SVivek Goyal 		if (WARN_ON(stack != NULL)) {
12099d3dfea3SVivek Goyal 			err = -EIO;
12109d3dfea3SVivek Goyal 			goto out_put;
12119d3dfea3SVivek Goyal 		}
12129d3dfea3SVivek Goyal 		stack = origin_path;
12139d3dfea3SVivek Goyal 		ctr = 1;
121459fb2013SVivek Goyal 		origin = origin_path->dentry;
12159d3dfea3SVivek Goyal 		origin_path = NULL;
12169d3dfea3SVivek Goyal 	}
12179d3dfea3SVivek Goyal 
1218ad1d615cSAmir Goldstein 	/*
121959fb2013SVivek Goyal 	 * Always lookup index if there is no-upperdentry.
12209d3dfea3SVivek Goyal 	 *
122159fb2013SVivek Goyal 	 * For the case of upperdentry, we have set origin by now if it
122259fb2013SVivek Goyal 	 * needed to be set. There are basically three cases.
12239d3dfea3SVivek Goyal 	 *
122459fb2013SVivek Goyal 	 * For directories, lookup index by lower inode and verify it matches
122559fb2013SVivek Goyal 	 * upper inode. We only trust dir index if we verified that lower dir
122659fb2013SVivek Goyal 	 * matches origin, otherwise dir index entries may be inconsistent
122759fb2013SVivek Goyal 	 * and we ignore them.
122859fb2013SVivek Goyal 	 *
122959fb2013SVivek Goyal 	 * For regular upper, we already set origin if upper had ORIGIN
123059fb2013SVivek Goyal 	 * xattr. There is no verification though as there is no path
123159fb2013SVivek Goyal 	 * based dentry lookup in lower in this case.
123259fb2013SVivek Goyal 	 *
123359fb2013SVivek Goyal 	 * For metacopy upper, we set a verified origin already if index
123459fb2013SVivek Goyal 	 * is enabled and if upper had an ORIGIN xattr.
123559fb2013SVivek Goyal 	 *
1236ad1d615cSAmir Goldstein 	 */
123759fb2013SVivek Goyal 	if (!upperdentry && ctr)
1238ad1d615cSAmir Goldstein 		origin = stack[0].dentry;
1239359f392cSAmir Goldstein 
1240ad1d615cSAmir Goldstein 	if (origin && ovl_indexdir(dentry->d_sb) &&
1241ad1d615cSAmir Goldstein 	    (!d.is_dir || ovl_index_all(dentry->d_sb))) {
124206170154SAmir Goldstein 		index = ovl_lookup_index(ofs, upperdentry, origin, true);
1243359f392cSAmir Goldstein 		if (IS_ERR(index)) {
1244359f392cSAmir Goldstein 			err = PTR_ERR(index);
1245359f392cSAmir Goldstein 			index = NULL;
1246359f392cSAmir Goldstein 			goto out_put;
1247359f392cSAmir Goldstein 		}
1248359f392cSAmir Goldstein 	}
1249359f392cSAmir Goldstein 
12500af950f5SAmir Goldstein 	if (ctr) {
1251bbb1e54dSMiklos Szeredi 		oe = ovl_alloc_entry(ctr);
1252bbb1e54dSMiklos Szeredi 		err = -ENOMEM;
1253bbb1e54dSMiklos Szeredi 		if (!oe)
1254bbb1e54dSMiklos Szeredi 			goto out_put;
1255bbb1e54dSMiklos Szeredi 
1256163db0daSAmir Goldstein 		ovl_stack_cpy(ovl_lowerstack(oe), stack, ctr);
12570af950f5SAmir Goldstein 	}
1258e6d2ebddSMiklos Szeredi 
1259c62520a8SAmir Goldstein 	if (upperopaque)
1260c62520a8SAmir Goldstein 		ovl_dentry_set_opaque(dentry);
1261c62520a8SAmir Goldstein 
126255acc661SMiklos Szeredi 	if (upperdentry)
126355acc661SMiklos Szeredi 		ovl_dentry_set_upper_alias(dentry);
12640a2d0d3fSVivek Goyal 	else if (index) {
1265dad7017aSChristian Brauner 		struct path upperpath = {
1266dad7017aSChristian Brauner 			.dentry = upperdentry = dget(index),
1267dad7017aSChristian Brauner 			.mnt = ovl_upper_mnt(ofs),
1268dad7017aSChristian Brauner 		};
1269dad7017aSChristian Brauner 
1270cf4ef780SStanislav Goriainov 		/*
1271cf4ef780SStanislav Goriainov 		 * It's safe to assign upperredirect here: the previous
1272cf4ef780SStanislav Goriainov 		 * assignment of happens only if upperdentry is non-NULL, and
1273cf4ef780SStanislav Goriainov 		 * this one only if upperdentry is NULL.
1274cf4ef780SStanislav Goriainov 		 */
1275dad7017aSChristian Brauner 		upperredirect = ovl_get_redirect_xattr(ofs, &upperpath, 0);
12760a2d0d3fSVivek Goyal 		if (IS_ERR(upperredirect)) {
12770a2d0d3fSVivek Goyal 			err = PTR_ERR(upperredirect);
12780a2d0d3fSVivek Goyal 			upperredirect = NULL;
12790a2d0d3fSVivek Goyal 			goto out_free_oe;
12800a2d0d3fSVivek Goyal 		}
1281bf070890SAlexander Larsson 		err = ovl_check_metacopy_xattr(ofs, &upperpath, NULL);
12824518dfcfSAmir Goldstein 		if (err < 0)
12834518dfcfSAmir Goldstein 			goto out_free_oe;
12844518dfcfSAmir Goldstein 		uppermetacopy = err;
1285184996e9SAlexander Larsson 		metacopy_size = err;
12860a2d0d3fSVivek Goyal 	}
1287359f392cSAmir Goldstein 
1288e6d2ebddSMiklos Szeredi 	if (upperdentry || ctr) {
1289ac6a52ebSVivek Goyal 		struct ovl_inode_params oip = {
1290ac6a52ebSVivek Goyal 			.upperdentry = upperdentry,
12910af950f5SAmir Goldstein 			.oe = oe,
1292ac6a52ebSVivek Goyal 			.index = index,
12939cec54c8SVivek Goyal 			.redirect = upperredirect,
1294ac6a52ebSVivek Goyal 		};
1295ac6a52ebSVivek Goyal 
12962b21da92SAmir Goldstein 		/* Store lowerdata redirect for lazy lookup */
12972b21da92SAmir Goldstein 		if (ctr > 1 && !d.is_dir && !stack[ctr - 1].dentry) {
12982b21da92SAmir Goldstein 			oip.lowerdata_redirect = d.redirect;
12992b21da92SAmir Goldstein 			d.redirect = NULL;
13002b21da92SAmir Goldstein 		}
1301ac6a52ebSVivek Goyal 		inode = ovl_get_inode(dentry->d_sb, &oip);
1302b9ac5c27SMiklos Szeredi 		err = PTR_ERR(inode);
1303b9ac5c27SMiklos Szeredi 		if (IS_ERR(inode))
1304e6d2ebddSMiklos Szeredi 			goto out_free_oe;
130528166ab3SVivek Goyal 		if (upperdentry && !uppermetacopy)
130628166ab3SVivek Goyal 			ovl_set_flag(OVL_UPPERDATA, inode);
1307184996e9SAlexander Larsson 
1308184996e9SAlexander Larsson 		if (metacopy_size > OVL_METACOPY_MIN_SIZE)
1309184996e9SAlexander Larsson 			ovl_set_flag(OVL_HAS_DIGEST, inode);
1310e6d2ebddSMiklos Szeredi 	}
1311e6d2ebddSMiklos Szeredi 
13120af950f5SAmir Goldstein 	ovl_dentry_init_reval(dentry, upperdentry, OVL_I_E(inode));
1313f4288844SMiklos Szeredi 
1314e6d2ebddSMiklos Szeredi 	revert_creds(old_cred);
13159d3dfea3SVivek Goyal 	if (origin_path) {
13169d3dfea3SVivek Goyal 		dput(origin_path->dentry);
13179d3dfea3SVivek Goyal 		kfree(origin_path);
13189d3dfea3SVivek Goyal 	}
1319359f392cSAmir Goldstein 	dput(index);
1320163db0daSAmir Goldstein 	ovl_stack_free(stack, ctr);
132102b69b28SMiklos Szeredi 	kfree(d.redirect);
1322829c28beSAmir Goldstein 	return d_splice_alias(inode, dentry);
1323bbb1e54dSMiklos Szeredi 
1324bbb1e54dSMiklos Szeredi out_free_oe:
1325163db0daSAmir Goldstein 	ovl_free_entry(oe);
1326bbb1e54dSMiklos Szeredi out_put:
1327359f392cSAmir Goldstein 	dput(index);
1328163db0daSAmir Goldstein 	ovl_stack_free(stack, ctr);
1329bbb1e54dSMiklos Szeredi out_put_upper:
13309d3dfea3SVivek Goyal 	if (origin_path) {
13319d3dfea3SVivek Goyal 		dput(origin_path->dentry);
13329d3dfea3SVivek Goyal 		kfree(origin_path);
13339d3dfea3SVivek Goyal 	}
1334bbb1e54dSMiklos Szeredi 	dput(upperdentry);
133502b69b28SMiklos Szeredi 	kfree(upperredirect);
1336bbb1e54dSMiklos Szeredi out:
133702b69b28SMiklos Szeredi 	kfree(d.redirect);
1338bbb1e54dSMiklos Szeredi 	revert_creds(old_cred);
1339bbb1e54dSMiklos Szeredi 	return ERR_PTR(err);
1340bbb1e54dSMiklos Szeredi }
1341bbb1e54dSMiklos Szeredi 
ovl_lower_positive(struct dentry * dentry)1342bbb1e54dSMiklos Szeredi bool ovl_lower_positive(struct dentry *dentry)
1343bbb1e54dSMiklos Szeredi {
1344a6ff2bc0SAmir Goldstein 	struct ovl_entry *poe = OVL_E(dentry->d_parent);
1345bbb1e54dSMiklos Szeredi 	const struct qstr *name = &dentry->d_name;
13466d0a8a90SAmir Goldstein 	const struct cred *old_cred;
1347bbb1e54dSMiklos Szeredi 	unsigned int i;
1348bbb1e54dSMiklos Szeredi 	bool positive = false;
1349bbb1e54dSMiklos Szeredi 	bool done = false;
1350bbb1e54dSMiklos Szeredi 
1351bbb1e54dSMiklos Szeredi 	/*
1352bbb1e54dSMiklos Szeredi 	 * If dentry is negative, then lower is positive iff this is a
1353bbb1e54dSMiklos Szeredi 	 * whiteout.
1354bbb1e54dSMiklos Szeredi 	 */
1355bbb1e54dSMiklos Szeredi 	if (!dentry->d_inode)
1356c62520a8SAmir Goldstein 		return ovl_dentry_is_opaque(dentry);
1357bbb1e54dSMiklos Szeredi 
1358bbb1e54dSMiklos Szeredi 	/* Negative upper -> positive lower */
135909d8b586SMiklos Szeredi 	if (!ovl_dentry_upper(dentry))
1360bbb1e54dSMiklos Szeredi 		return true;
1361bbb1e54dSMiklos Szeredi 
13626d0a8a90SAmir Goldstein 	old_cred = ovl_override_creds(dentry->d_sb);
1363bbb1e54dSMiklos Szeredi 	/* Positive upper -> have to look up lower to see whether it exists */
13645522c9c7SAmir Goldstein 	for (i = 0; !done && !positive && i < ovl_numlower(poe); i++) {
1365bbb1e54dSMiklos Szeredi 		struct dentry *this;
13665522c9c7SAmir Goldstein 		struct ovl_path *parentpath = &ovl_lowerstack(poe)[i];
1367bbb1e54dSMiklos Szeredi 
13685522c9c7SAmir Goldstein 		this = lookup_one_positive_unlocked(
13695522c9c7SAmir Goldstein 				mnt_idmap(parentpath->layer->mnt),
13705522c9c7SAmir Goldstein 				name->name, parentpath->dentry, name->len);
1371bbb1e54dSMiklos Szeredi 		if (IS_ERR(this)) {
1372bbb1e54dSMiklos Szeredi 			switch (PTR_ERR(this)) {
1373bbb1e54dSMiklos Szeredi 			case -ENOENT:
1374bbb1e54dSMiklos Szeredi 			case -ENAMETOOLONG:
1375bbb1e54dSMiklos Szeredi 				break;
1376bbb1e54dSMiklos Szeredi 
1377bbb1e54dSMiklos Szeredi 			default:
1378bbb1e54dSMiklos Szeredi 				/*
1379bbb1e54dSMiklos Szeredi 				 * Assume something is there, we just couldn't
1380bbb1e54dSMiklos Szeredi 				 * access it.
1381bbb1e54dSMiklos Szeredi 				 */
1382bbb1e54dSMiklos Szeredi 				positive = true;
1383bbb1e54dSMiklos Szeredi 				break;
1384bbb1e54dSMiklos Szeredi 			}
1385bbb1e54dSMiklos Szeredi 		} else {
1386bbb1e54dSMiklos Szeredi 			positive = !ovl_is_whiteout(this);
1387bbb1e54dSMiklos Szeredi 			done = true;
1388bbb1e54dSMiklos Szeredi 			dput(this);
1389bbb1e54dSMiklos Szeredi 		}
1390bbb1e54dSMiklos Szeredi 	}
13916d0a8a90SAmir Goldstein 	revert_creds(old_cred);
1392bbb1e54dSMiklos Szeredi 
1393bbb1e54dSMiklos Szeredi 	return positive;
1394bbb1e54dSMiklos Szeredi }
1395