History

ovl: copy-up: don't unlock between lookup and link

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.

Miklos Szeredi committed 9 years ago

Commit e85f82f1 parent c0bc1261 file · +12 −12Browse files

Unified · Split

fs/overlayfs/copy_up.c+12−12
@@ -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;
@@ -403,6 +397,14 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir, · 34 unmodified lines
403397 if (err)
404398 goto out_cleanup;
405399
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+
406408 if (tmpfile)
407409 err = ovl_do_link(temp, udir, upper, true);
408410 else
@@ -416,17 +418,15 @@ static int ovl_copy_up_locked(struct dentry *workdir, struct dentry *upperdir, · 7 unmodified lines
416418
417419 /* Restore timestamps on parent (best effort) */
418420 ovl_set_timestamps(upperdir, pstat);
419−out2:
421+out:
420422 dput(temp);
421−out1:
422423 dput(upper);
423−out:
424424 return err;
425425
426426 out_cleanup:
427427 if (!tmpfile)
428428 ovl_cleanup(wdir, temp);
429− goto out2;
429+ goto out;
430430 }
431431
432432 /*