Commit dabc8b2
quota: fix dqput() to follow the guarantees dquot_srcu should provide
The dquot_mark_dquot_dirty() using dquot references from the inode
should be protected by dquot_srcu. quota_off code takes care to call
synchronize_srcu(&dquot_srcu) to not drop dquot references while they
are used by other users. But dquot_transfer() breaks this assumption.
We call dquot_transfer() to drop the last reference of dquot and add
it to free_dquots, but there may still be other users using the dquot
at this time, as shown in the function graph below:
cpu1 cpu2
_________________|_________________
wb_do_writeback CHOWN(1)
...
ext4_da_update_reserve_space
dquot_claim_block
...
dquot_mark_dquot_dirty // try to dirty old quota
test_bit(DQ_ACTIVE_B, &dquot->dq_flags) // still ACTIVE
if (test_bit(DQ_MOD_B, &dquot->dq_flags))
// test no dirty, wait dq_list_lock
...
dquot_transfer
__dquot_transfer
dqput_all(transfer_from) // rls old dquot
dqput // last dqput
dquot_release
clear_bit(DQ_ACTIVE_B, &dquot->dq_flags)
atomic_dec(&dquot->dq_count)
put_dquot_last(dquot)
list_add_tail(&dquot->dq_free, &free_dquots)
// add the dquot to free_dquots
if (!test_and_set_bit(DQ_MOD_B, &dquot->dq_flags))
add dqi_dirty_list // add released dquot to dirty_list
This can cause various issues, such as dquot being destroyed by
dqcache_shrink_scan() after being added to free_dquots, which can trigger
a UAF in dquot_mark_dquot_dirty(); or after dquot is added to free_dquots
and then to dirty_list, it is added to free_dquots again after
dquot_writeback_dquots() is executed, which causes the free_dquots list to
be corrupted and triggers a UAF when dqcache_shrink_scan() is called for
freeing dquot twice.
As Honza said, we need to fix dquot_transfer() to follow the guarantees
dquot_srcu should provide. But calling synchronize_srcu() directly from
dquot_transfer() is too expensive (and mostly unnecessary). So we add
dquot whose last reference should be dropped to the new global dquot
list releasing_dquots, and then queue work item which would call
synchronize_srcu() and after that perform the final cleanup of all the
dquots on releasing_dquots.
Fixes: 4580b30 ("quota: Do not dirty bad dquots")
Suggested-by: Jan Kara <jack@suse.cz>
Signed-off-by: Baokun Li <libaokun1@huawei.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Message-Id: <20230630110822.3881712-5-libaokun1@huawei.com>1 parent 33bcfaf commit dabc8b2
1 file changed
+78
-18
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
225 | 225 | | |
226 | 226 | | |
227 | 227 | | |
228 | | - | |
229 | | - | |
230 | | - | |
| 228 | + | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
231 | 232 | | |
232 | 233 | | |
233 | 234 | | |
234 | 235 | | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
235 | 244 | | |
236 | 245 | | |
237 | 246 | | |
| |||
250 | 259 | | |
251 | 260 | | |
252 | 261 | | |
| 262 | + | |
253 | 263 | | |
254 | 264 | | |
255 | 265 | | |
| |||
260 | 270 | | |
261 | 271 | | |
262 | 272 | | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
263 | 276 | | |
264 | 277 | | |
265 | 278 | | |
| |||
305 | 318 | | |
306 | 319 | | |
307 | 320 | | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
308 | 326 | | |
309 | 327 | | |
310 | 328 | | |
311 | 329 | | |
312 | 330 | | |
313 | | - | |
| 331 | + | |
| 332 | + | |
314 | 333 | | |
315 | 334 | | |
316 | 335 | | |
| |||
552 | 571 | | |
553 | 572 | | |
554 | 573 | | |
| 574 | + | |
| 575 | + | |
555 | 576 | | |
556 | 577 | | |
557 | 578 | | |
| |||
560 | 581 | | |
561 | 582 | | |
562 | 583 | | |
| 584 | + | |
| 585 | + | |
| 586 | + | |
| 587 | + | |
| 588 | + | |
| 589 | + | |
563 | 590 | | |
564 | 591 | | |
565 | 592 | | |
| |||
770 | 797 | | |
771 | 798 | | |
772 | 799 | | |
| 800 | + | |
| 801 | + | |
| 802 | + | |
| 803 | + | |
| 804 | + | |
| 805 | + | |
| 806 | + | |
| 807 | + | |
| 808 | + | |
| 809 | + | |
| 810 | + | |
| 811 | + | |
| 812 | + | |
| 813 | + | |
| 814 | + | |
| 815 | + | |
| 816 | + | |
| 817 | + | |
| 818 | + | |
| 819 | + | |
| 820 | + | |
| 821 | + | |
| 822 | + | |
| 823 | + | |
| 824 | + | |
| 825 | + | |
| 826 | + | |
| 827 | + | |
| 828 | + | |
| 829 | + | |
| 830 | + | |
| 831 | + | |
| 832 | + | |
| 833 | + | |
| 834 | + | |
| 835 | + | |
| 836 | + | |
| 837 | + | |
| 838 | + | |
| 839 | + | |
| 840 | + | |
| 841 | + | |
| 842 | + | |
773 | 843 | | |
774 | 844 | | |
775 | 845 | | |
| |||
786 | 856 | | |
787 | 857 | | |
788 | 858 | | |
789 | | - | |
| 859 | + | |
790 | 860 | | |
791 | 861 | | |
792 | 862 | | |
| |||
798 | 868 | | |
799 | 869 | | |
800 | 870 | | |
| 871 | + | |
801 | 872 | | |
802 | | - | |
803 | | - | |
804 | | - | |
805 | | - | |
806 | | - | |
807 | | - | |
808 | | - | |
809 | | - | |
810 | | - | |
811 | | - | |
812 | | - | |
813 | | - | |
814 | 873 | | |
815 | 874 | | |
816 | 875 | | |
817 | 876 | | |
818 | | - | |
| 877 | + | |
819 | 878 | | |
| 879 | + | |
820 | 880 | | |
821 | 881 | | |
822 | 882 | | |
| |||
0 commit comments