diff options
author | Juergen Gross <jgross@suse.com> | 2022-03-07 09:48:54 +0100 |
---|---|---|
committer | Juergen Gross <jgross@suse.com> | 2022-03-07 09:48:54 +0100 |
commit | 6b1775f26a2da2b05a6dc8ec2b5d14e9a4701a1a (patch) | |
tree | a97c4aa5eeb6b768a127579eac498e7bbfc7001b /drivers/xen/grant-table.c | |
parent | 3777ea7bac3113005b7180e6b9dadf16d19a5827 (diff) | |
download | lwn-6b1775f26a2da2b05a6dc8ec2b5d14e9a4701a1a.tar.gz lwn-6b1775f26a2da2b05a6dc8ec2b5d14e9a4701a1a.zip |
xen/grant-table: add gnttab_try_end_foreign_access()
Add a new grant table function gnttab_try_end_foreign_access(), which
will remove and free a grant if it is not in use.
Its main use case is to either free a grant if it is no longer in use,
or to take some other action if it is still in use. This other action
can be an error exit, or (e.g. in the case of blkfront persistent grant
feature) some special handling.
This is CVE-2022-23036, CVE-2022-23038 / part of XSA-396.
Reported-by: Demi Marie Obenour <demi@invisiblethingslab.com>
Signed-off-by: Juergen Gross <jgross@suse.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
V2:
- new patch
V4:
- add comments to header (Jan Beulich)
Diffstat (limited to 'drivers/xen/grant-table.c')
-rw-r--r-- | drivers/xen/grant-table.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c index 3729bea0c989..1b82e7a3722a 100644 --- a/drivers/xen/grant-table.c +++ b/drivers/xen/grant-table.c @@ -435,11 +435,21 @@ static void gnttab_add_deferred(grant_ref_t ref, bool readonly, what, ref, page ? page_to_pfn(page) : -1); } +int gnttab_try_end_foreign_access(grant_ref_t ref) +{ + int ret = _gnttab_end_foreign_access_ref(ref, 0); + + if (ret) + put_free_entry(ref); + + return ret; +} +EXPORT_SYMBOL_GPL(gnttab_try_end_foreign_access); + void gnttab_end_foreign_access(grant_ref_t ref, int readonly, unsigned long page) { - if (gnttab_end_foreign_access_ref(ref, readonly)) { - put_free_entry(ref); + if (gnttab_try_end_foreign_access(ref)) { if (page != 0) put_page(virt_to_page(page)); } else |