History

Merge branch 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs

Pull overlayfs fixes from Miklos Szeredi: "Fix two bugs in copy-up code. One introduced in 4.11 and one in 4.12-rc" * 'overlayfs-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/vfs: ovl: don't set origin on broken lower hardlink ovl: copy-up: don't unlock between lookup and link

Linus Torvalds committed 9 years ago

Commit 86c3e002 parents 4d8a991 fbaf94e1 file · +19 −14Browse files

Unified · Split

fs/overlayfs/copy_up.c+19−14
@@ -330,15 +330,9 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir, · 329 unmodified lines
330 .link = link330 .link = link
331 };331 };
332 332
333 upper = lookup_one_len(dentry->d_name.name, upperdir,
334 dentry->d_name.len);
335 err = PTR_ERR(upper);
336 if (IS_ERR(upper))
337 goto out;
338
339 err = security_inode_copy_up(dentry, &new_creds);333 err = security_inode_copy_up(dentry, &new_creds);
340 if (err < 0)334 if (err < 0)
341 goto out1;335 goto out;
342 336
343 if (new_creds)337 if (new_creds)
344 old_creds = override_creds(new_creds);338 old_creds = override_creds(new_creds);
@@ -362,7 +356,7 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir, · 17 unmodified lines
362 }356 }
363 357
364 if (err)358 if (err)
365 goto out2;359 goto out;
366 360
367 if (S_ISREG(stat->mode)) {361 if (S_ISREG(stat->mode)) {
368 struct path upperpath;362 struct path upperpath;
@@ -398,10 +392,23 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir, · 29 unmodified lines
398 /*392 /*
399 * Store identifier of lower inode in upper inode xattr to393 * Store identifier of lower inode in upper inode xattr to
400 * allow lookup of the copy up origin inode.394 * allow lookup of the copy up origin inode.
395 *
396 * Don't set origin when we are breaking the association with a lower
397 * hard link.
401 */398 */
402 err = ovl_set_origin(dentry, lowerpath->dentry, temp);399 if (S_ISDIR(stat->mode) || stat->nlink == 1) {
403 if (err)400 err = ovl_set_origin(dentry, lowerpath->dentry, temp);
401 if (err)
402 goto out_cleanup;
403 }
404
405 upper = lookup_one_len(dentry->d_name.name, upperdir,
406 dentry->d_name.len);
407 if (IS_ERR(upper)) {
408 err = PTR_ERR(upper);
409 upper = NULL;
404 goto out_cleanup;410 goto out_cleanup;
411 }
405 412
406 if (tmpfile)413 if (tmpfile)
407 err = ovl_do_link(temp, udir, upper, true);414 err = ovl_do_link(temp, udir, upper, true);
@@ -416,17 +423,15 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir, · 8 unmodified lines
416 423
417 /* Restore timestamps on parent (best effort) */424 /* Restore timestamps on parent (best effort) */
418 ovl_set_timestamps(upperdir, pstat);425 ovl_set_timestamps(upperdir, pstat);
419out2:426out:
420 dput(temp);427 dput(temp);
421out1:
422 dput(upper);428 dput(upper);
423out:
424 return err;429 return err;
425 430
426out_cleanup:431out_cleanup:
427 if (!tmpfile)432 if (!tmpfile)
428 ovl_cleanup(wdir, temp);433 ovl_cleanup(wdir, temp);
429 goto out2;434 goto out;
430}435}
431 436
432/*437/*