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 | 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); |
| @@ -362,7 +356,7 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir, · 17 unmodified lines | ||
| 362 | 356 | } |
| 363 | 357 | |
| 364 | 358 | if (err) |
| 365 | − goto out2; | |
| 359 | + goto out; | |
| 366 | 360 | |
| 367 | 361 | if (S_ISREG(stat->mode)) { |
| 368 | 362 | struct path upperpath; |
| @@ -403,6 +397,14 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir, · 34 unmodified lines | ||
| 403 | 397 | if (err) |
| 404 | 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 | 408 | if (tmpfile) |
| 407 | 409 | err = ovl_do_link(temp, udir, upper, true); |
| 408 | 410 | else |
| @@ -416,17 +418,15 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir, · 7 unmodified lines | ||
| 416 | 418 | |
| 417 | 419 | /* Restore timestamps on parent (best effort) */ |
| 418 | 420 | ovl_set_timestamps(upperdir, pstat); |
| 419 | −out2: | |
| 421 | +out: | |
| 420 | 422 | dput(temp); |
| 421 | −out1: | |
| 422 | 423 | dput(upper); |
| 423 | −out: | |
| 424 | 424 | return err; |
| 425 | 425 | |
| 426 | 426 | out_cleanup: |
| 427 | 427 | if (!tmpfile) |
| 428 | 428 | ovl_cleanup(wdir, temp); |
| 429 | − goto out2; | |
| 429 | + goto out; | |
| 430 | 430 | } |
| 431 | 431 | |
| 432 | 432 | /* |