[PATCH] xen/evtchn: fix wrong usage of array_index_nospec()

Juergen Gross posted 1 patch 2 weeks, 4 days ago
Patches applied successfully (tree, apply log)
git fetch https://gitlab.com/xen-project/patchew/xen tags/patchew/20260729141254.345989-1-jgross@suse.com
xen/common/event_fifo.c | 7 +++----
1 file changed, 3 insertions(+), 4 deletions(-)
[PATCH] xen/evtchn: fix wrong usage of array_index_nospec()
Posted by Juergen Gross 2 weeks, 4 days ago
The size passed to array_index_nospec() in evtchn_fifo_word_from_port()
doesn't match the value it is meant to clamp.

Fix it by clamping the port to a safe interval and use that value to
calculate the event_array[] index and the offset into the page
addressed by the array element.

Fixes: 443d3ab6daee ("evtchn: block speculative out-of-bound accesses")
Signed-off-by: Juergen Gross <jgross@suse.com>
---
 xen/common/event_fifo.c | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/xen/common/event_fifo.c b/xen/common/event_fifo.c
index cae08a594e..eb8e26bba1 100644
--- a/xen/common/event_fifo.c
+++ b/xen/common/event_fifo.c
@@ -71,11 +71,10 @@ static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
      */
     smp_rmb();
 
-    p = array_index_nospec(port / EVTCHN_FIFO_EVENT_WORDS_PER_PAGE,
-                           d->evtchn_fifo->num_evtchns);
-    w = port % EVTCHN_FIFO_EVENT_WORDS_PER_PAGE;
+    p = array_index_nospec(port, d->evtchn_fifo->num_evtchns);
+    w = p % EVTCHN_FIFO_EVENT_WORDS_PER_PAGE;
 
-    return d->evtchn_fifo->event_array[p] + w;
+    return d->evtchn_fifo->event_array[p / EVTCHN_FIFO_EVENT_WORDS_PER_PAGE] + w;
 }
 
 static void cf_check evtchn_fifo_init(struct domain *d, struct evtchn *evtchn)
-- 
2.55.0
Re: [PATCH] xen/evtchn: fix wrong usage of array_index_nospec()
Posted by Jan Beulich 2 weeks, 4 days ago
On 29.07.2026 16:12, Juergen Gross wrote:
> --- a/xen/common/event_fifo.c
> +++ b/xen/common/event_fifo.c
> @@ -71,11 +71,10 @@ static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
>       */
>      smp_rmb();
>  
> -    p = array_index_nospec(port / EVTCHN_FIFO_EVENT_WORDS_PER_PAGE,
> -                           d->evtchn_fifo->num_evtchns);
> -    w = port % EVTCHN_FIFO_EVENT_WORDS_PER_PAGE;
> +    p = array_index_nospec(port, d->evtchn_fifo->num_evtchns);
> +    w = p % EVTCHN_FIFO_EVENT_WORDS_PER_PAGE;

I don't see why the calculation of w would also need to change - whichever way
it is, w is bounded by EVTCHN_FIFO_EVENT_WORDS_PER_PAGE (and hence safe).
Preferably with that undone (can do while committing):
Reviewed-by: Jan Beulich <jbeulich@suse.com>

Jan

> -    return d->evtchn_fifo->event_array[p] + w;
> +    return d->evtchn_fifo->event_array[p / EVTCHN_FIFO_EVENT_WORDS_PER_PAGE] + w;
>  }
>  
>  static void cf_check evtchn_fifo_init(struct domain *d, struct evtchn *evtchn)
Re: [PATCH] xen/evtchn: fix wrong usage of array_index_nospec()
Posted by Jürgen Groß 2 weeks, 4 days ago
On 29.07.26 16:22, Jan Beulich wrote:
> On 29.07.2026 16:12, Juergen Gross wrote:
>> --- a/xen/common/event_fifo.c
>> +++ b/xen/common/event_fifo.c
>> @@ -71,11 +71,10 @@ static inline event_word_t *evtchn_fifo_word_from_port(const struct domain *d,
>>        */
>>       smp_rmb();
>>   
>> -    p = array_index_nospec(port / EVTCHN_FIFO_EVENT_WORDS_PER_PAGE,
>> -                           d->evtchn_fifo->num_evtchns);
>> -    w = port % EVTCHN_FIFO_EVENT_WORDS_PER_PAGE;
>> +    p = array_index_nospec(port, d->evtchn_fifo->num_evtchns);
>> +    w = p % EVTCHN_FIFO_EVENT_WORDS_PER_PAGE;
> 
> I don't see why the calculation of w would also need to change - whichever way
> it is, w is bounded by EVTCHN_FIFO_EVENT_WORDS_PER_PAGE (and hence safe).

I thought it would be cleaner to use p for the index AND the offset.

> Preferably with that undone (can do while committing):

If you prefer this, go ahead.

> Reviewed-by: Jan Beulich <jbeulich@suse.com>

Thanks,


Juergen