hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/fs/overlayfs/file.c
....@@ -21,7 +21,6 @@
2121 struct kiocb iocb;
2222 refcount_t ref;
2323 struct kiocb *orig_iocb;
24
- struct fd fd;
2524 };
2625
2726 static struct kmem_cache *ovl_aio_request_cachep;
....@@ -247,7 +246,7 @@
247246 static inline void ovl_aio_put(struct ovl_aio_req *aio_req)
248247 {
249248 if (refcount_dec_and_test(&aio_req->ref)) {
250
- fdput(aio_req->fd);
249
+ fput(aio_req->iocb.ki_filp);
251250 kmem_cache_free(ovl_aio_request_cachep, aio_req);
252251 }
253252 }
....@@ -314,10 +313,9 @@
314313 if (!aio_req)
315314 goto out;
316315
317
- aio_req->fd = real;
318316 real.flags = 0;
319317 aio_req->orig_iocb = iocb;
320
- kiocb_clone(&aio_req->iocb, iocb, real.file);
318
+ kiocb_clone(&aio_req->iocb, iocb, get_file(real.file));
321319 aio_req->iocb.ki_complete = ovl_aio_rw_complete;
322320 refcount_set(&aio_req->ref, 2);
323321 ret = vfs_iocb_iter_read(real.file, &aio_req->iocb, iter);
....@@ -387,10 +385,9 @@
387385 /* Pacify lockdep, same trick as done in aio_write() */
388386 __sb_writers_release(file_inode(real.file)->i_sb,
389387 SB_FREEZE_WRITE);
390
- aio_req->fd = real;
391388 real.flags = 0;
392389 aio_req->orig_iocb = iocb;
393
- kiocb_clone(&aio_req->iocb, iocb, real.file);
390
+ kiocb_clone(&aio_req->iocb, iocb, get_file(real.file));
394391 aio_req->iocb.ki_flags = ifl;
395392 aio_req->iocb.ki_complete = ovl_aio_rw_complete;
396393 refcount_set(&aio_req->ref, 2);
....@@ -519,9 +516,16 @@
519516 const struct cred *old_cred;
520517 int ret;
521518
519
+ inode_lock(inode);
520
+ /* Update mode */
521
+ ovl_copyattr(ovl_inode_real(inode), inode);
522
+ ret = file_remove_privs(file);
523
+ if (ret)
524
+ goto out_unlock;
525
+
522526 ret = ovl_real_fdget(file, &real);
523527 if (ret)
524
- return ret;
528
+ goto out_unlock;
525529
526530 old_cred = ovl_override_creds(file_inode(file)->i_sb);
527531 ret = vfs_fallocate(real.file, mode, offset, len);
....@@ -531,6 +535,9 @@
531535 ovl_copyattr(ovl_inode_real(inode), inode);
532536
533537 fdput(real);
538
+
539
+out_unlock:
540
+ inode_unlock(inode);
534541
535542 return ret;
536543 }
....@@ -675,14 +682,23 @@
675682 const struct cred *old_cred;
676683 loff_t ret;
677684
685
+ inode_lock(inode_out);
686
+ if (op != OVL_DEDUPE) {
687
+ /* Update mode */
688
+ ovl_copyattr(ovl_inode_real(inode_out), inode_out);
689
+ ret = file_remove_privs(file_out);
690
+ if (ret)
691
+ goto out_unlock;
692
+ }
693
+
678694 ret = ovl_real_fdget(file_out, &real_out);
679695 if (ret)
680
- return ret;
696
+ goto out_unlock;
681697
682698 ret = ovl_real_fdget(file_in, &real_in);
683699 if (ret) {
684700 fdput(real_out);
685
- return ret;
701
+ goto out_unlock;
686702 }
687703
688704 old_cred = ovl_override_creds(file_inode(file_out)->i_sb);
....@@ -711,6 +727,9 @@
711727 fdput(real_in);
712728 fdput(real_out);
713729
730
+out_unlock:
731
+ inode_unlock(inode_out);
732
+
714733 return ret;
715734 }
716735