Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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

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