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