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
330330 .link = link
331331 };
332332
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−
339333 err = security_inode_copy_up(dentry, &new_creds);
340334 if (err < 0)
341− goto out1;
335+ goto out;
342336
343337 if (new_creds)
344338 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
362356 }
363357
364358 if (err)
365− goto out2;
359+ goto out;
366360
367361 if (S_ISREG(stat->mode)) {
368362 struct path upperpath;
@@ -398,10 +392,23 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir, · 29 unmodified lines
398392 /*
399393 * Store identifier of lower inode in upper inode xattr to
400394 * 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.
401398 */
402− err = ovl_set_origin(dentry, lowerpath->dentry, temp);
403− if (err)
399+ if (S_ISDIR(stat->mode) || stat->nlink == 1) {
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;
404410 goto out_cleanup;
411+ }
405412
406413 if (tmpfile)
407414 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
416423
417424 /* Restore timestamps on parent (best effort) */
418425 ovl_set_timestamps(upperdir, pstat);
419−out2:
426+out:
420427 dput(temp);
421−out1:
422428 dput(upper);
423−out:
424429 return err;
425430
426431 out_cleanup:
427432 if (!tmpfile)
428433 ovl_cleanup(wdir, temp);
429− goto out2;
434+ goto out;
430435 }
431436
432437 /*