diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2017-06-30 13:22:59 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2017-06-30 13:22:59 -0400 |
commit | 86c3e00afd64a507aef954cd581547f28807e51a (patch) | |
tree | df0ad2fcc7749a282683acc5aac473c398b2bbc5 | |
parent | 4d8a991d460d4fa4829beaffdcba45a217ca0fa7 (diff) | |
parent | fbaf94ee3cd5cfa85fe2d4d04be968820cb00556 (diff) |
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
-rw-r--r-- | fs/overlayfs/copy_up.c | 33 |
1 files changed, 19 insertions, 14 deletions
diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index 7a44533f4bbf..a2a65120c9d0 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c | |||
@@ -330,15 +330,9 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir, | |||
330 | .link = link | 330 | .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, | |||
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, | |||
398 | /* | 392 | /* |
399 | * Store identifier of lower inode in upper inode xattr to | 393 | * 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, | |||
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); |
419 | out2: | 426 | out: |
420 | dput(temp); | 427 | dput(temp); |
421 | out1: | ||
422 | dput(upper); | 428 | dput(upper); |
423 | out: | ||
424 | return err; | 429 | return err; |
425 | 430 | ||
426 | out_cleanup: | 431 | out_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 | /* |