Nothing prevents mischief on upper layer while we are busy copying up the data. Move the lookup right before the looked up dentry is actually used.
Unified · Split
| @@ -330,15 +330,9 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir, · 329 unmodified lines | |||
| 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, · 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; |
| @@ -403,6 +397,14 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir, · 34 unmodified lines | |||
| 403 | if (err) | 397 | if (err) |
| 404 | goto out_cleanup; | 398 | goto out_cleanup; |
| 405 | 399 | ||
| 400 | upper = lookup_one_len(dentry->d_name.name, upperdir, | ||
| 401 | dentry->d_name.len); | ||
| 402 | if (IS_ERR(upper)) { | ||
| 403 | err = PTR_ERR(upper); | ||
| 404 | upper = NULL; | ||
| 405 | goto out_cleanup; | ||
| 406 | } | ||
| 407 | |||
| 406 | if (tmpfile) | 408 | if (tmpfile) |
| 407 | err = ovl_do_link(temp, udir, upper, true); | 409 | err = ovl_do_link(temp, udir, upper, true); |
| 408 | else | 410 | else |
| @@ -416,17 +418,15 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir, · 7 unmodified lines | |||
| 416 | 418 | ||
| 417 | /* Restore timestamps on parent (best effort) */ | 419 | /* Restore timestamps on parent (best effort) */ |
| 418 | ovl_set_timestamps(upperdir, pstat); | 420 | ovl_set_timestamps(upperdir, pstat); |
| 419 | out2: | 421 | out: |
| 420 | dput(temp); | 422 | dput(temp); |
| 421 | out1: | ||
| 422 | dput(upper); | 423 | dput(upper); |
| 423 | out: | ||
| 424 | return err; | 424 | return err; |
| 425 | 425 | ||
| 426 | out_cleanup: | 426 | out_cleanup: |
| 427 | if (!tmpfile) | 427 | if (!tmpfile) |
| 428 | ovl_cleanup(wdir, temp); | 428 | ovl_cleanup(wdir, temp); |
| 429 | goto out2; | 429 | goto out; |
| 430 | } | 430 | } |
| 431 | 431 | ||
| 432 | /* | 432 | /* |