Skip to content

Commit ba9ea77

Browse files
braunerMiklos Szeredi
authored andcommitted
ovl: handle idmappings for layer lookup
Make the two places where lookup helpers can be called either on lower or upper layers take the mount's idmapping into account. To this end we pass down the mount in struct ovl_lookup_data. It can later also be used to construct struct path for various other helpers. This is needed to support idmapped base layers with overlay. Cc: <linux-unionfs@vger.kernel.org> Tested-by: Giuseppe Scrivano <gscrivan@redhat.com> Reviewed-by: Amir Goldstein <amir73il@gmail.com> Signed-off-by: Christian Brauner (Microsoft) <brauner@kernel.org> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
1 parent 50db8d0 commit ba9ea77

3 files changed

Lines changed: 18 additions & 11 deletions

File tree

fs/overlayfs/export.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,11 @@ static struct dentry *ovl_lookup_real_one(struct dentry *connected,
391391
* pointer because we hold no lock on the real dentry.
392392
*/
393393
take_dentry_name_snapshot(&name, real);
394+
/*
395+
* No mnt_userns handling here: it's an internal lookup. Could skip
396+
* permission checking altogether, but for now just use non-mnt_userns
397+
* transformed ids.
398+
*/
394399
this = lookup_one_len(name.name.name, connected, name.name.len);
395400
release_dentry_name_snapshot(&name);
396401
err = PTR_ERR(this);

fs/overlayfs/namei.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -199,11 +199,12 @@ static bool ovl_is_opaquedir(struct ovl_fs *ofs, struct path *path)
199199
return ovl_path_check_dir_xattr(ofs, path, OVL_XATTR_OPAQUE);
200200
}
201201

202-
static struct dentry *ovl_lookup_positive_unlocked(const char *name,
202+
static struct dentry *ovl_lookup_positive_unlocked(struct ovl_lookup_data *d,
203+
const char *name,
203204
struct dentry *base, int len,
204205
bool drop_negative)
205206
{
206-
struct dentry *ret = lookup_one_len_unlocked(name, base, len);
207+
struct dentry *ret = lookup_one_unlocked(mnt_user_ns(d->mnt), name, base, len);
207208

208209
if (!IS_ERR(ret) && d_flags_negative(smp_load_acquire(&ret->d_flags))) {
209210
if (drop_negative && ret->d_lockref.count == 1) {
@@ -229,7 +230,7 @@ static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d,
229230
int err;
230231
bool last_element = !post[0];
231232

232-
this = ovl_lookup_positive_unlocked(name, base, namelen, drop_negative);
233+
this = ovl_lookup_positive_unlocked(d, name, base, namelen, drop_negative);
233234
if (IS_ERR(this)) {
234235
err = PTR_ERR(this);
235236
this = NULL;
@@ -709,7 +710,8 @@ struct dentry *ovl_lookup_index(struct ovl_fs *ofs, struct dentry *upper,
709710
if (err)
710711
return ERR_PTR(err);
711712

712-
index = lookup_positive_unlocked(name.name, ofs->indexdir, name.len);
713+
index = lookup_one_positive_unlocked(ovl_upper_mnt_userns(ofs), name.name,
714+
ofs->indexdir, name.len);
713715
if (IS_ERR(index)) {
714716
err = PTR_ERR(index);
715717
if (err == -ENOENT) {
@@ -1174,8 +1176,8 @@ bool ovl_lower_positive(struct dentry *dentry)
11741176
struct dentry *this;
11751177
struct dentry *lowerdir = poe->lowerstack[i].dentry;
11761178

1177-
this = lookup_positive_unlocked(name->name, lowerdir,
1178-
name->len);
1179+
this = lookup_one_positive_unlocked(mnt_user_ns(poe->lowerstack[i].layer->mnt),
1180+
name->name, lowerdir, name->len);
11791181
if (IS_ERR(this)) {
11801182
switch (PTR_ERR(this)) {
11811183
case -ENOENT:

fs/overlayfs/readdir.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -264,11 +264,11 @@ static int ovl_fill_merge(struct dir_context *ctx, const char *name,
264264
return ovl_fill_lowest(rdd, name, namelen, offset, ino, d_type);
265265
}
266266

267-
static int ovl_check_whiteouts(struct dentry *dir, struct ovl_readdir_data *rdd)
267+
static int ovl_check_whiteouts(struct path *path, struct ovl_readdir_data *rdd)
268268
{
269269
int err;
270270
struct ovl_cache_entry *p;
271-
struct dentry *dentry;
271+
struct dentry *dentry, *dir = path->dentry;
272272
const struct cred *old_cred;
273273

274274
old_cred = ovl_override_creds(rdd->dentry->d_sb);
@@ -278,7 +278,7 @@ static int ovl_check_whiteouts(struct dentry *dir, struct ovl_readdir_data *rdd)
278278
while (rdd->first_maybe_whiteout) {
279279
p = rdd->first_maybe_whiteout;
280280
rdd->first_maybe_whiteout = p->next_maybe_whiteout;
281-
dentry = lookup_one_len(p->name, dir, p->len);
281+
dentry = lookup_one(mnt_user_ns(path->mnt), p->name, dir, p->len);
282282
if (!IS_ERR(dentry)) {
283283
p->is_whiteout = ovl_is_whiteout(dentry);
284284
dput(dentry);
@@ -312,7 +312,7 @@ static inline int ovl_dir_read(struct path *realpath,
312312
} while (!err && rdd->count);
313313

314314
if (!err && rdd->first_maybe_whiteout && rdd->dentry)
315-
err = ovl_check_whiteouts(realpath->dentry, rdd);
315+
err = ovl_check_whiteouts(realpath, rdd);
316316

317317
fput(realfile);
318318

@@ -479,7 +479,7 @@ static int ovl_cache_update_ino(struct path *path, struct ovl_cache_entry *p)
479479
goto get;
480480
}
481481
}
482-
this = lookup_one_len(p->name, dir, p->len);
482+
this = lookup_one(mnt_user_ns(path->mnt), p->name, dir, p->len);
483483
if (IS_ERR_OR_NULL(this) || !this->d_inode) {
484484
/* Mark a stale entry */
485485
p->is_whiteout = true;

0 commit comments

Comments
 (0)