[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen stable-4.10] gnttab/ARM: don't corrupt shared GFN array
commit e2ceb2ed665647b111efcac550935e90a1edbdc4 Author: Jan Beulich <jbeulich@xxxxxxxx> AuthorDate: Tue Feb 27 14:18:34 2018 +0100 Commit: Jan Beulich <jbeulich@xxxxxxxx> CommitDate: Tue Feb 27 14:18:34 2018 +0100 gnttab/ARM: don't corrupt shared GFN array ... by writing status GFNs to it. Introduce a second array instead. Also implement gnttab_status_gmfn() properly now that the information is suitably being tracked. While touching it anyway, remove a misguided (but luckily benign) upper bound check from gnttab_shared_gmfn(): We should never access beyond the bounds of that array. This is part of XSA-255. Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx> Reviewed-by: Stefano Stabellini <sstabellini@xxxxxxxxxx> Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> master commit: 9d2f8f9c65d4da35437f50ed9e812a2c5ab313e2 master date: 2018-02-27 14:04:44 +0100 --- xen/common/grant_table.c | 4 +++- xen/include/asm-arm/grant_table.h | 38 ++++++++++++++++++++++++++++---------- xen/include/asm-x86/grant_table.h | 2 +- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 250450b..b41d816 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -3775,6 +3775,7 @@ int gnttab_map_frame(struct domain *d, unsigned long idx, gfn_t gfn, { int rc = 0; struct grant_table *gt = d->grant_table; + bool status = false; grant_write_lock(gt); @@ -3785,6 +3786,7 @@ int gnttab_map_frame(struct domain *d, unsigned long idx, gfn_t gfn, (idx & XENMAPIDX_grant_table_status) ) { idx &= ~XENMAPIDX_grant_table_status; + status = true; if ( idx < nr_status_frames(gt) ) *mfn = _mfn(virt_to_mfn(gt->status[idx])); else @@ -3802,7 +3804,7 @@ int gnttab_map_frame(struct domain *d, unsigned long idx, gfn_t gfn, } if ( !rc ) - gnttab_set_frame_gfn(gt, idx, gfn); + gnttab_set_frame_gfn(gt, status, idx, gfn); grant_write_unlock(gt); diff --git a/xen/include/asm-arm/grant_table.h b/xen/include/asm-arm/grant_table.h index 0dfdc55..f5361c7 100644 --- a/xen/include/asm-arm/grant_table.h +++ b/xen/include/asm-arm/grant_table.h @@ -9,7 +9,8 @@ #define INITIAL_NR_GRANT_FRAMES 1U struct grant_table_arch { - gfn_t *gfn; + gfn_t *shared_gfn; + gfn_t *status_gfn; }; void gnttab_clear_flag(unsigned long nr, uint16_t *addr); @@ -21,7 +22,6 @@ int replace_grant_host_mapping(unsigned long gpaddr, unsigned long mfn, unsigned long new_gpaddr, unsigned int flags); void gnttab_mark_dirty(struct domain *d, unsigned long l); #define gnttab_create_status_page(d, t, i) do {} while (0) -#define gnttab_status_gmfn(d, t, i) (0) #define gnttab_release_host_mappings(domain) 1 static inline int replace_grant_supported(void) { @@ -42,19 +42,35 @@ static inline unsigned int gnttab_dom0_max(void) #define gnttab_init_arch(gt) \ ({ \ - (gt)->arch.gfn = xzalloc_array(gfn_t, (gt)->max_grant_frames); \ - ( (gt)->arch.gfn ? 0 : -ENOMEM ); \ + unsigned int ngf_ = (gt)->max_grant_frames; \ + unsigned int nsf_ = grant_to_status_frames(ngf_); \ + \ + (gt)->arch.shared_gfn = xmalloc_array(gfn_t, ngf_); \ + (gt)->arch.status_gfn = xmalloc_array(gfn_t, nsf_); \ + if ( (gt)->arch.shared_gfn && (gt)->arch.status_gfn ) \ + { \ + while ( ngf_-- ) \ + (gt)->arch.shared_gfn[ngf_] = INVALID_GFN; \ + while ( nsf_-- ) \ + (gt)->arch.status_gfn[nsf_] = INVALID_GFN; \ + } \ + else \ + gnttab_destroy_arch(gt); \ + (gt)->arch.shared_gfn ? 0 : -ENOMEM; \ }) #define gnttab_destroy_arch(gt) \ do { \ - xfree((gt)->arch.gfn); \ - (gt)->arch.gfn = NULL; \ + xfree((gt)->arch.shared_gfn); \ + (gt)->arch.shared_gfn = NULL; \ + xfree((gt)->arch.status_gfn); \ + (gt)->arch.status_gfn = NULL; \ } while ( 0 ) -#define gnttab_set_frame_gfn(gt, idx, gfn) \ +#define gnttab_set_frame_gfn(gt, st, idx, gfn) \ do { \ - (gt)->arch.gfn[idx] = gfn; \ + ((st) ? (gt)->arch.status_gfn : (gt)->arch.shared_gfn)[idx] = \ + (gfn); \ } while ( 0 ) #define gnttab_create_shared_page(d, t, i) \ @@ -65,8 +81,10 @@ static inline unsigned int gnttab_dom0_max(void) } while ( 0 ) #define gnttab_shared_gmfn(d, t, i) \ - ( ((i >= nr_grant_frames(t)) && \ - (i < (t)->max_grant_frames))? 0 : gfn_x((t)->arch.gfn[i])) + gfn_x(((i) >= nr_grant_frames(t)) ? INVALID_GFN : (t)->arch.shared_gfn[i]) + +#define gnttab_status_gmfn(d, t, i) \ + gfn_x(((i) >= nr_status_frames(t)) ? INVALID_GFN : (t)->arch.status_gfn[i]) #define gnttab_need_iommu_mapping(d) \ (is_domain_direct_mapped(d) && need_iommu(d)) diff --git a/xen/include/asm-x86/grant_table.h b/xen/include/asm-x86/grant_table.h index d9157e4..3177d82 100644 --- a/xen/include/asm-x86/grant_table.h +++ b/xen/include/asm-x86/grant_table.h @@ -46,7 +46,7 @@ static inline unsigned int gnttab_dom0_max(void) #define gnttab_init_arch(gt) 0 #define gnttab_destroy_arch(gt) do {} while ( 0 ) -#define gnttab_set_frame_gfn(gt, idx, gfn) do {} while ( 0 ) +#define gnttab_set_frame_gfn(gt, st, idx, gfn) do {} while ( 0 ) #define gnttab_create_shared_page(d, t, i) \ do { \ -- generated by git-patchbot for /home/xen/git/xen.git#stable-4.10 _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |