summaryrefslogtreecommitdiffstats
path: root/include/xen
diff options
context:
space:
mode:
authorJuergen Gross <jgross@suse.com>2022-03-07 09:48:55 +0100
committerJuergen Gross <jgross@suse.com>2022-03-07 09:48:55 +0100
commit42baefac638f06314298087394b982ead9ec444b (patch)
tree13c5afca9863b80f71aea5f31f069cb87322f3dc /include/xen
parentxen/pvcalls: use alloc/free_pages_exact() (diff)
downloadlinux-42baefac638f06314298087394b982ead9ec444b.tar.xz
linux-42baefac638f06314298087394b982ead9ec444b.zip
xen/gnttab: fix gnttab_end_foreign_access() without page specified
gnttab_end_foreign_access() is used to free a grant reference and optionally to free the associated page. In case the grant is still in use by the other side processing is being deferred. This leads to a problem in case no page to be freed is specified by the caller: the caller doesn't know that the page is still mapped by the other side and thus should not be used for other purposes. The correct way to handle this situation is to take an additional reference to the granted page in case handling is being deferred and to drop that reference when the grant reference could be freed finally. This requires that there are no users of gnttab_end_foreign_access() left directly repurposing the granted page after the call, as this might result in clobbered data or information leaks via the not yet freed grant reference. This is part of CVE-2022-23041 / XSA-396. Reported-by: Simon Gaiser <simon@invisiblethingslab.com> Signed-off-by: Juergen Gross <jgross@suse.com> Reviewed-by: Jan Beulich <jbeulich@suse.com> --- V4: - expand comment in header V5: - get page ref in case of kmalloc() failure, too
Diffstat (limited to 'include/xen')
-rw-r--r--include/xen/grant_table.h7
1 files changed, 6 insertions, 1 deletions
diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h
index ab9e692a0ef4..c9fea9389ebe 100644
--- a/include/xen/grant_table.h
+++ b/include/xen/grant_table.h
@@ -107,7 +107,12 @@ int gnttab_end_foreign_access_ref(grant_ref_t ref, int readonly);
* Note that the granted page might still be accessed (read or write) by the
* other side after gnttab_end_foreign_access() returns, so even if page was
* specified as 0 it is not allowed to just reuse the page for other
- * purposes immediately.
+ * purposes immediately. gnttab_end_foreign_access() will take an additional
+ * reference to the granted page in this case, which is dropped only after
+ * the grant is no longer in use.
+ * This requires that multi page allocations for areas subject to
+ * gnttab_end_foreign_access() are done via alloc_pages_exact() (and freeing
+ * via free_pages_exact()) in order to avoid high order pages.
*/
void gnttab_end_foreign_access(grant_ref_t ref, int readonly,
unsigned long page);