mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
gnttab: correct locking on transitive grant copy error path
While the comment next to the lock dropping in preparation of recursively calling acquire_grant_for_copy() mistakenly talks about the rd == td case (excluded a few lines further up), the same concerns apply to the calling of release_grant_for_copy() on a subsequent error path. This is CVE-2022-33748 / XSA-411. Fixes:ad48fb963d("gnttab: fix transitive grant handling") Signed-off-by: Jan Beulich <jbeulich@suse.com> master commit:6e3aab858emaster date: 2022-10-11 14:29:30 +0200
This commit is contained in:
1 parent
867fcf6ca2
commit
042de08439
1 file changed
+19
-6
@@ -2584,9 +2584,8 @@ acquire_grant_for_copy(
|
||||
trans_domid);
|
||||
|
||||
/*
|
||||
* acquire_grant_for_copy() could take the lock on the
|
||||
* remote table (if rd == td), so we have to drop the lock
|
||||
* here and reacquire.
|
||||
* acquire_grant_for_copy() will take the lock on the remote table,
|
||||
* so we have to drop the lock here and reacquire.
|
||||
*/
|
||||
active_entry_release(act);
|
||||
grant_read_unlock(rgt);
|
||||
@@ -2623,11 +2622,25 @@ acquire_grant_for_copy(
|
||||
act->trans_gref != trans_gref ||
|
||||
!act->is_sub_page)) )
|
||||
{
|
||||
release_grant_for_copy(td, trans_gref, readonly);
|
||||
fixup_status_for_copy_pin(rd, act, status);
|
||||
rcu_unlock_domain(td);
|
||||
/*
|
||||
* Like above for acquire_grant_for_copy() we need to drop and then
|
||||
* re-acquire the locks here to prevent lock order inversion issues.
|
||||
* Unlike for acquire_grant_for_copy() we don't need to re-check
|
||||
* anything, as release_grant_for_copy() doesn't depend on the grant
|
||||
* table entry: It only updates internal state and the status flags.
|
||||
*/
|
||||
active_entry_release(act);
|
||||
grant_read_unlock(rgt);
|
||||
|
||||
release_grant_for_copy(td, trans_gref, readonly);
|
||||
rcu_unlock_domain(td);
|
||||
|
||||
grant_read_lock(rgt);
|
||||
act = active_entry_acquire(rgt, gref);
|
||||
fixup_status_for_copy_pin(rd, act, status);
|
||||
active_entry_release(act);
|
||||
grant_read_unlock(rgt);
|
||||
|
||||
put_page(*page);
|
||||
*page = NULL;
|
||||
return ERESTART;
|
||||
|
||||