head 1.2; access; symbols pkgsrc-2020Q2:1.1.0.4 pkgsrc-2020Q2-base:1.1 pkgsrc-2020Q1:1.1.0.2; locks; strict; comment @# @; 1.2 date 2020.08.24.10.35.35; author bouyer; state dead; branches; next 1.1; commitid MGsqrLPx72UHUilC; 1.1 date 2020.04.15.15.37.19; author bouyer; state Exp; branches 1.1.2.1; next ; commitid lAP1ZtvVXxSONu4C; 1.1.2.1 date 2020.04.15.15.37.19; author bsiegert; state dead; branches; next 1.1.2.2; commitid rED8p7xMUDKaJJ4C; 1.1.2.2 date 2020.04.17.12.34.14; author bsiegert; state Exp; branches; next ; commitid rED8p7xMUDKaJJ4C; desc @@ 1.2 log @Update to 4.11.4nb1 Keep PKGREVISION at 1 to reflect that it's not a stock Xen 4.11.4 kernel, we have additinnal security fixes (all relevant patches from upstream to date). Changes: mosly bug fixes and improvements; better support for newer AMD CPUs. full changelog at https://xenproject.org/downloads/xen-project-archives/xen-proj ect-4-11-series/xen-project-4-11-4/ @ text @$NetBSD: patch-XSA313,v 1.1 2020/04/15 15:37:19 bouyer Exp $ From: Jan Beulich Subject: xenoprof: clear buffer intended to be shared with guests alloc_xenheap_pages() making use of MEMF_no_scrub is fine for Xen internally used allocations, but buffers allocated to be shared with (unpriviliged) guests need to be zapped of their prior content. This is part of XSA-313. Reported-by: Ilja Van Sprundel Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper Reviewed-by: Wei Liu --- xen/common/xenoprof.c.orig +++ xen/common/xenoprof.c @@@@ -253,6 +253,9 @@@@ static int alloc_xenoprof_struct( return -ENOMEM; } + for ( i = 0; i < npages; ++i ) + clear_page(d->xenoprof->rawbuf + i * PAGE_SIZE); + d->xenoprof->npages = npages; d->xenoprof->nbuf = nvcpu; d->xenoprof->bufsize = bufsize; From: Jan Beulich Subject: xenoprof: limit consumption of shared buffer data Since a shared buffer can be written to by the guest, we may only read the head and tail pointers from there (all other fields should only ever be written to). Furthermore, for any particular operation the two values must be read exactly once, with both checks and consumption happening with the thus read values. (The backtrace related xenoprof_buf_space() use in xenoprof_log_event() is an exception: The values used there get re-checked by every subsequent xenoprof_add_sample().) Since that code needed touching, also fix the double increment of the lost samples count in case the backtrace related xenoprof_add_sample() invocation in xenoprof_log_event() fails. Where code is being touched anyway, add const as appropriate, but take the opportunity to entirely drop the now unused domain parameter of xenoprof_buf_space(). This is part of XSA-313. Reported-by: Ilja Van Sprundel Signed-off-by: Jan Beulich Reviewed-by: George Dunlap Reviewed-by: Wei Liu --- xen/common/xenoprof.c.orig +++ xen/common/xenoprof.c @@@@ -479,25 +479,22 @@@@ static int add_passive_list(XEN_GUEST_HA /* Get space in the buffer */ -static int xenoprof_buf_space(struct domain *d, xenoprof_buf_t * buf, int size) +static int xenoprof_buf_space(int head, int tail, int size) { - int head, tail; - - head = xenoprof_buf(d, buf, event_head); - tail = xenoprof_buf(d, buf, event_tail); - return ((tail > head) ? 0 : size) + tail - head - 1; } /* Check for space and add a sample. Return 1 if successful, 0 otherwise. */ -static int xenoprof_add_sample(struct domain *d, xenoprof_buf_t *buf, +static int xenoprof_add_sample(const struct domain *d, + const struct xenoprof_vcpu *v, uint64_t eip, int mode, int event) { + xenoprof_buf_t *buf = v->buffer; int head, tail, size; head = xenoprof_buf(d, buf, event_head); tail = xenoprof_buf(d, buf, event_tail); - size = xenoprof_buf(d, buf, event_size); + size = v->event_size; /* make sure indexes in shared buffer are sane */ if ( (head < 0) || (head >= size) || (tail < 0) || (tail >= size) ) @@@@ -506,7 +503,7 @@@@ static int xenoprof_add_sample(struct do return 0; } - if ( xenoprof_buf_space(d, buf, size) > 0 ) + if ( xenoprof_buf_space(head, tail, size) > 0 ) { xenoprof_buf(d, buf, event_log[head].eip) = eip; xenoprof_buf(d, buf, event_log[head].mode) = mode; @@@@ -530,7 +527,6 @@@@ static int xenoprof_add_sample(struct do int xenoprof_add_trace(struct vcpu *vcpu, uint64_t pc, int mode) { struct domain *d = vcpu->domain; - xenoprof_buf_t *buf = d->xenoprof->vcpu[vcpu->vcpu_id].buffer; /* Do not accidentally write an escape code due to a broken frame. */ if ( pc == XENOPROF_ESCAPE_CODE ) @@@@ -539,7 +535,8 @@@@ int xenoprof_add_trace(struct vcpu *vcpu return 0; } - return xenoprof_add_sample(d, buf, pc, mode, 0); + return xenoprof_add_sample(d, &d->xenoprof->vcpu[vcpu->vcpu_id], + pc, mode, 0); } void xenoprof_log_event(struct vcpu *vcpu, const struct cpu_user_regs *regs, @@@@ -570,17 +567,22 @@@@ void xenoprof_log_event(struct vcpu *vcp /* Provide backtrace if requested. */ if ( backtrace_depth > 0 ) { - if ( (xenoprof_buf_space(d, buf, v->event_size) < 2) || - !xenoprof_add_sample(d, buf, XENOPROF_ESCAPE_CODE, mode, - XENOPROF_TRACE_BEGIN) ) + if ( xenoprof_buf_space(xenoprof_buf(d, buf, event_head), + xenoprof_buf(d, buf, event_tail), + v->event_size) < 2 ) { xenoprof_buf(d, buf, lost_samples)++; lost_samples++; return; } + + /* xenoprof_add_sample() will increment lost_samples on failure */ + if ( !xenoprof_add_sample(d, v, XENOPROF_ESCAPE_CODE, mode, + XENOPROF_TRACE_BEGIN) ) + return; } - if ( xenoprof_add_sample(d, buf, pc, mode, event) ) + if ( xenoprof_add_sample(d, v, pc, mode, event) ) { if ( is_active(vcpu->domain) ) active_samples++; --- xen/include/xen/xenoprof.h.orig +++ xen/include/xen/xenoprof.h @@@@ -61,12 +61,12 @@@@ struct xenoprof { #ifndef CONFIG_COMPAT #define XENOPROF_COMPAT(x) 0 -#define xenoprof_buf(d, b, field) ((b)->field) +#define xenoprof_buf(d, b, field) ACCESS_ONCE((b)->field) #else #define XENOPROF_COMPAT(x) ((x)->is_compat) -#define xenoprof_buf(d, b, field) (*(!(d)->xenoprof->is_compat ? \ - &(b)->native.field : \ - &(b)->compat.field)) +#define xenoprof_buf(d, b, field) ACCESS_ONCE(*(!(d)->xenoprof->is_compat \ + ? &(b)->native.field \ + : &(b)->compat.field)) #endif struct domain; @ 1.1 log @Apply upstream patches for security issues XSA313 and XSA318. Bump PKGREVISION @ text @d1 1 a1 1 $NetBSD: $ @ 1.1.2.1 log @file patch-XSA313 was added on branch pkgsrc-2020Q1 on 2020-04-17 12:34:14 +0000 @ text @d1 160 @ 1.1.2.2 log @Pullup ticket #6160 - requested by bouyer sysutils/xenkernel411: security fix Revisions pulled up: - sysutils/xenkernel411/Makefile 1.13 - sysutils/xenkernel411/distinfo 1.10-1.11 - sysutils/xenkernel411/patches/patch-XSA313 1.1 - sysutils/xenkernel411/patches/patch-XSA316 1.1 - sysutils/xenkernel411/patches/patch-XSA318 1.1 --- Module Name: pkgsrc Committed By: bouyer Date: Wed Apr 15 15:37:20 UTC 2020 Modified Files: pkgsrc/sysutils/xenkernel411: Makefile distinfo Added Files: pkgsrc/sysutils/xenkernel411/patches: patch-XSA313 patch-XSA318 Log Message: Apply upstream patches for security issues XSA313 and XSA318. Bump PKGREVISION --- Module Name: pkgsrc Committed By: bouyer Date: Wed Apr 15 15:45:05 UTC 2020 Modified Files: pkgsrc/sysutils/xenkernel411: distinfo Added Files: pkgsrc/sysutils/xenkernel411/patches: patch-XSA316 Log Message: Also apply patch for XSA316. ride previous PKGREVISION bump @ text @a0 160 $NetBSD: patch-XSA313,v 1.1 2020/04/15 15:37:19 bouyer Exp $ From: Jan Beulich Subject: xenoprof: clear buffer intended to be shared with guests alloc_xenheap_pages() making use of MEMF_no_scrub is fine for Xen internally used allocations, but buffers allocated to be shared with (unpriviliged) guests need to be zapped of their prior content. This is part of XSA-313. Reported-by: Ilja Van Sprundel Signed-off-by: Jan Beulich Reviewed-by: Andrew Cooper Reviewed-by: Wei Liu --- xen/common/xenoprof.c.orig +++ xen/common/xenoprof.c @@@@ -253,6 +253,9 @@@@ static int alloc_xenoprof_struct( return -ENOMEM; } + for ( i = 0; i < npages; ++i ) + clear_page(d->xenoprof->rawbuf + i * PAGE_SIZE); + d->xenoprof->npages = npages; d->xenoprof->nbuf = nvcpu; d->xenoprof->bufsize = bufsize; From: Jan Beulich Subject: xenoprof: limit consumption of shared buffer data Since a shared buffer can be written to by the guest, we may only read the head and tail pointers from there (all other fields should only ever be written to). Furthermore, for any particular operation the two values must be read exactly once, with both checks and consumption happening with the thus read values. (The backtrace related xenoprof_buf_space() use in xenoprof_log_event() is an exception: The values used there get re-checked by every subsequent xenoprof_add_sample().) Since that code needed touching, also fix the double increment of the lost samples count in case the backtrace related xenoprof_add_sample() invocation in xenoprof_log_event() fails. Where code is being touched anyway, add const as appropriate, but take the opportunity to entirely drop the now unused domain parameter of xenoprof_buf_space(). This is part of XSA-313. Reported-by: Ilja Van Sprundel Signed-off-by: Jan Beulich Reviewed-by: George Dunlap Reviewed-by: Wei Liu --- xen/common/xenoprof.c.orig +++ xen/common/xenoprof.c @@@@ -479,25 +479,22 @@@@ static int add_passive_list(XEN_GUEST_HA /* Get space in the buffer */ -static int xenoprof_buf_space(struct domain *d, xenoprof_buf_t * buf, int size) +static int xenoprof_buf_space(int head, int tail, int size) { - int head, tail; - - head = xenoprof_buf(d, buf, event_head); - tail = xenoprof_buf(d, buf, event_tail); - return ((tail > head) ? 0 : size) + tail - head - 1; } /* Check for space and add a sample. Return 1 if successful, 0 otherwise. */ -static int xenoprof_add_sample(struct domain *d, xenoprof_buf_t *buf, +static int xenoprof_add_sample(const struct domain *d, + const struct xenoprof_vcpu *v, uint64_t eip, int mode, int event) { + xenoprof_buf_t *buf = v->buffer; int head, tail, size; head = xenoprof_buf(d, buf, event_head); tail = xenoprof_buf(d, buf, event_tail); - size = xenoprof_buf(d, buf, event_size); + size = v->event_size; /* make sure indexes in shared buffer are sane */ if ( (head < 0) || (head >= size) || (tail < 0) || (tail >= size) ) @@@@ -506,7 +503,7 @@@@ static int xenoprof_add_sample(struct do return 0; } - if ( xenoprof_buf_space(d, buf, size) > 0 ) + if ( xenoprof_buf_space(head, tail, size) > 0 ) { xenoprof_buf(d, buf, event_log[head].eip) = eip; xenoprof_buf(d, buf, event_log[head].mode) = mode; @@@@ -530,7 +527,6 @@@@ static int xenoprof_add_sample(struct do int xenoprof_add_trace(struct vcpu *vcpu, uint64_t pc, int mode) { struct domain *d = vcpu->domain; - xenoprof_buf_t *buf = d->xenoprof->vcpu[vcpu->vcpu_id].buffer; /* Do not accidentally write an escape code due to a broken frame. */ if ( pc == XENOPROF_ESCAPE_CODE ) @@@@ -539,7 +535,8 @@@@ int xenoprof_add_trace(struct vcpu *vcpu return 0; } - return xenoprof_add_sample(d, buf, pc, mode, 0); + return xenoprof_add_sample(d, &d->xenoprof->vcpu[vcpu->vcpu_id], + pc, mode, 0); } void xenoprof_log_event(struct vcpu *vcpu, const struct cpu_user_regs *regs, @@@@ -570,17 +567,22 @@@@ void xenoprof_log_event(struct vcpu *vcp /* Provide backtrace if requested. */ if ( backtrace_depth > 0 ) { - if ( (xenoprof_buf_space(d, buf, v->event_size) < 2) || - !xenoprof_add_sample(d, buf, XENOPROF_ESCAPE_CODE, mode, - XENOPROF_TRACE_BEGIN) ) + if ( xenoprof_buf_space(xenoprof_buf(d, buf, event_head), + xenoprof_buf(d, buf, event_tail), + v->event_size) < 2 ) { xenoprof_buf(d, buf, lost_samples)++; lost_samples++; return; } + + /* xenoprof_add_sample() will increment lost_samples on failure */ + if ( !xenoprof_add_sample(d, v, XENOPROF_ESCAPE_CODE, mode, + XENOPROF_TRACE_BEGIN) ) + return; } - if ( xenoprof_add_sample(d, buf, pc, mode, event) ) + if ( xenoprof_add_sample(d, v, pc, mode, event) ) { if ( is_active(vcpu->domain) ) active_samples++; --- xen/include/xen/xenoprof.h.orig +++ xen/include/xen/xenoprof.h @@@@ -61,12 +61,12 @@@@ struct xenoprof { #ifndef CONFIG_COMPAT #define XENOPROF_COMPAT(x) 0 -#define xenoprof_buf(d, b, field) ((b)->field) +#define xenoprof_buf(d, b, field) ACCESS_ONCE((b)->field) #else #define XENOPROF_COMPAT(x) ((x)->is_compat) -#define xenoprof_buf(d, b, field) (*(!(d)->xenoprof->is_compat ? \ - &(b)->native.field : \ - &(b)->compat.field)) +#define xenoprof_buf(d, b, field) ACCESS_ONCE(*(!(d)->xenoprof->is_compat \ + ? &(b)->native.field \ + : &(b)->compat.field)) #endif struct domain; @