mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 10:40:03 +01:00
common/gnttab: Correct error handling for gnttab_setup_table()
Simplify the error labels to just "unlock" and "out". This fixes an erroneous path where a failure of rcu_lock_domain_by_any_id() still results in rcu_unlock_domain() being called. This is only not an XSA by luck. rcu_unlock_domain() is a nop other than decrementing the preempt count, and nothing reads the preempt count outside of a debug build. Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com> Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
9e051a840d
commit
5e436e7a45
1 file changed
+10
-9
@@ -1626,7 +1626,7 @@ gnttab_setup_table(
|
||||
XEN_GUEST_HANDLE_PARAM(gnttab_setup_table_t) uop, unsigned int count)
|
||||
{
|
||||
struct gnttab_setup_table op;
|
||||
struct domain *d;
|
||||
struct domain *d = NULL;
|
||||
struct grant_table *gt;
|
||||
int i;
|
||||
xen_pfn_t gmfn;
|
||||
@@ -1646,7 +1646,7 @@ gnttab_setup_table(
|
||||
" per domain.\n",
|
||||
max_grant_frames);
|
||||
op.status = GNTST_general_error;
|
||||
goto out1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ( !guest_handle_okay(op.frame_list, op.nr_frames) )
|
||||
@@ -1657,13 +1657,13 @@ gnttab_setup_table(
|
||||
{
|
||||
gdprintk(XENLOG_INFO, "Bad domid %d.\n", op.dom);
|
||||
op.status = GNTST_bad_domain;
|
||||
goto out2;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if ( xsm_grant_setup(XSM_TARGET, current->domain, d) )
|
||||
{
|
||||
op.status = GNTST_permission_denied;
|
||||
goto out2;
|
||||
goto out;
|
||||
}
|
||||
|
||||
gt = d->grant_table;
|
||||
@@ -1681,7 +1681,7 @@ gnttab_setup_table(
|
||||
"Expand grant table to %u failed. Current: %u Max: %u\n",
|
||||
op.nr_frames, nr_grant_frames(gt), max_grant_frames);
|
||||
op.status = GNTST_general_error;
|
||||
goto out3;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
op.status = GNTST_okay;
|
||||
@@ -1694,11 +1694,12 @@ gnttab_setup_table(
|
||||
op.status = GNTST_bad_virt_addr;
|
||||
}
|
||||
|
||||
out3:
|
||||
unlock:
|
||||
grant_write_unlock(gt);
|
||||
out2:
|
||||
rcu_unlock_domain(d);
|
||||
out1:
|
||||
out:
|
||||
if ( d )
|
||||
rcu_unlock_domain(d);
|
||||
|
||||
if ( unlikely(__copy_field_to_guest(uop, &op, status)) )
|
||||
return -EFAULT;
|
||||
|
||||
|
||||