HV: Fixes index out of bounds for addressing irq.

NR_MAX_IRQS is defined as 272 and IRQ_INVALID as 273 which implies
that 272 is a valid irq number. In this case, an illegal access can
occur at run time when irq_desc_array[] or irq_count[] is accessed
with index 272. This fix stops the illegal access by renaming
NR_MAX_IRQS to NR_IRQS and then places proper conditions for range
checks. If the index is >= NR_IRQS, then index is invalid otherwise
its considered valid for accessing irq arrays. IRQ_INVALID definition
is also changed to 0xffffffffU to indicate maximum unsigned value.

Signed-off-by: Madeeha Javed <madeeha_javed@mentor.com>
This commit is contained in:
Madeeha Javed 2018-07-16 14:39:45 +05:00 committed by lijinxia
parent 988a3fe0d6
commit a257f2fadc
5 changed files with 18 additions and 18 deletions

View File

@ -362,7 +362,7 @@ void setup_ioapic_irq(void)
} }
/* pinned irq before use it */ /* pinned irq before use it */
if (irq_mark_used(gsi) > NR_MAX_IRQS) { if (irq_mark_used(gsi) >= NR_IRQS) {
pr_err("failed to alloc IRQ[%d]", gsi); pr_err("failed to alloc IRQ[%d]", gsi);
gsi++; gsi++;
continue; continue;

View File

@ -8,7 +8,7 @@
static spinlock_t exception_spinlock = { .head = 0U, .tail = 0U, }; static spinlock_t exception_spinlock = { .head = 0U, .tail = 0U, };
static struct irq_desc irq_desc_array[NR_MAX_IRQS]; static struct irq_desc irq_desc_array[NR_IRQS];
static uint32_t vector_to_irq[NR_MAX_VECTOR + 1]; static uint32_t vector_to_irq[NR_MAX_VECTOR + 1];
spurious_handler_t spurious_handler; spurious_handler_t spurious_handler;
@ -17,7 +17,7 @@ static void init_irq_desc(void)
{ {
uint32_t i; uint32_t i;
for (i = 0U; i < NR_MAX_IRQS; i++) { for (i = 0U; i < NR_IRQS; i++) {
irq_desc_array[i].irq = i; irq_desc_array[i].irq = i;
irq_desc_array[i].vector = VECTOR_INVALID; irq_desc_array[i].vector = VECTOR_INVALID;
spinlock_init(&irq_desc_array[i].irq_lock); spinlock_init(&irq_desc_array[i].irq_lock);
@ -65,7 +65,7 @@ uint32_t irq_mark_used(uint32_t irq)
spinlock_rflags; spinlock_rflags;
if (irq > NR_MAX_IRQS) { if (irq >= NR_IRQS) {
return IRQ_INVALID; return IRQ_INVALID;
} }
@ -89,7 +89,7 @@ static uint32_t alloc_irq(void)
spinlock_rflags; spinlock_rflags;
for (i = irq_gsi_num(); i < NR_MAX_IRQS; i++) { for (i = irq_gsi_num(); i < NR_IRQS; i++) {
desc = &irq_desc_array[i]; desc = &irq_desc_array[i];
spinlock_irqsave_obtain(&desc->irq_lock); spinlock_irqsave_obtain(&desc->irq_lock);
if (desc->used == IRQ_NOT_ASSIGNED) { if (desc->used == IRQ_NOT_ASSIGNED) {
@ -99,7 +99,7 @@ static uint32_t alloc_irq(void)
} }
spinlock_irqrestore_release(&desc->irq_lock); spinlock_irqrestore_release(&desc->irq_lock);
} }
return (i == NR_MAX_IRQS) ? IRQ_INVALID : i; return (i == NR_IRQS) ? IRQ_INVALID : i;
} }
/* need irq_lock protection before use */ /* need irq_lock protection before use */
@ -133,7 +133,7 @@ static void _irq_desc_free_vector(uint32_t irq)
uint32_t vr; uint32_t vr;
uint16_t pcpu_id; uint16_t pcpu_id;
if (irq > NR_MAX_IRQS) { if (irq >= NR_IRQS) {
return; return;
} }
@ -212,7 +212,7 @@ common_register_handler(uint32_t irq,
* case: irq = IRQ_INVALID * case: irq = IRQ_INVALID
* caller did not know which irq to use, and want system to * caller did not know which irq to use, and want system to
* allocate available irq for it. These irq are in range: * allocate available irq for it. These irq are in range:
* nr_gsi ~ NR_MAX_IRQS * nr_gsi ~ NR_IRQS
* a irq will be allocated and the vector will be assigned to this * a irq will be allocated and the vector will be assigned to this
* irq automatically. * irq automatically.
* *
@ -245,7 +245,7 @@ common_register_handler(uint32_t irq,
irq = irq_mark_used(irq); irq = irq_mark_used(irq);
} }
if (irq > NR_MAX_IRQS) { if (irq >= NR_IRQS) {
pr_err("failed to assign IRQ"); pr_err("failed to assign IRQ");
goto OUT; goto OUT;
} }
@ -302,7 +302,7 @@ uint32_t irq_desc_alloc_vector(uint32_t irq, bool lowpri)
spinlock_rflags; spinlock_rflags;
/* irq should be always available at this time */ /* irq should be always available at this time */
if (irq > NR_MAX_IRQS) { if (irq >= NR_IRQS) {
return VECTOR_INVALID; return VECTOR_INVALID;
} }
@ -332,7 +332,7 @@ void irq_desc_try_free_vector(uint32_t irq)
spinlock_rflags; spinlock_rflags;
/* legacy irq's vector is reserved and should not be freed */ /* legacy irq's vector is reserved and should not be freed */
if (irq > NR_MAX_IRQS || irq < NR_LEGACY_IRQ) { if (irq >= NR_IRQS || irq < NR_LEGACY_IRQ) {
return; return;
} }
@ -348,7 +348,7 @@ void irq_desc_try_free_vector(uint32_t irq)
uint32_t irq_to_vector(uint32_t irq) uint32_t irq_to_vector(uint32_t irq)
{ {
if (irq < NR_MAX_IRQS) { if (irq < NR_IRQS) {
return irq_desc_array[irq].vector; return irq_desc_array[irq].vector;
} else { } else {
return VECTOR_INVALID; return VECTOR_INVALID;
@ -581,7 +581,7 @@ void update_irq_handler(uint32_t irq, irq_handler_t func)
spinlock_rflags; spinlock_rflags;
if (irq >= NR_MAX_IRQS) { if (irq >= NR_IRQS) {
return; return;
} }
@ -703,7 +703,7 @@ void get_cpu_interrupt_info(char *str, int str_max)
size -= len; size -= len;
str += len; str += len;
for (irq = 0U; irq < NR_MAX_IRQS; irq++) { for (irq = 0U; irq < NR_IRQS; irq++) {
desc = &irq_desc_array[irq]; desc = &irq_desc_array[irq];
vector = irq_to_vector(irq); vector = irq_to_vector(irq);
if (desc->used != IRQ_NOT_ASSIGNED && if (desc->used != IRQ_NOT_ASSIGNED &&

View File

@ -7,7 +7,7 @@
#include <hypervisor.h> #include <hypervisor.h>
#define MAX_TIMER_ACTIONS 32 #define MAX_TIMER_ACTIONS 32
#define TIMER_IRQ (NR_MAX_IRQS - 1) #define TIMER_IRQ (NR_IRQS - 1)
#define CAL_MS 10 #define CAL_MS 10
#define MIN_TIMER_PERIOD_US 500 #define MIN_TIMER_PERIOD_US 500

View File

@ -28,8 +28,8 @@
#define NR_MAX_VECTOR 0xFFU #define NR_MAX_VECTOR 0xFFU
#define VECTOR_INVALID (NR_MAX_VECTOR + 1U) #define VECTOR_INVALID (NR_MAX_VECTOR + 1U)
#define NR_MAX_IRQS (256U + 16U) #define NR_IRQS (256U + 16U)
#define IRQ_INVALID (NR_MAX_IRQS + 1U) #define IRQ_INVALID 0xffffffffU
#define DEFAULT_DEST_MODE IOAPIC_RTE_DESTLOG #define DEFAULT_DEST_MODE IOAPIC_RTE_DESTLOG
#define DEFAULT_DELIVERY_MODE IOAPIC_RTE_DELLOPRI #define DEFAULT_DELIVERY_MODE IOAPIC_RTE_DELLOPRI

View File

@ -20,7 +20,7 @@
struct per_cpu_region { struct per_cpu_region {
uint64_t *sbuf[ACRN_SBUF_ID_MAX]; uint64_t *sbuf[ACRN_SBUF_ID_MAX];
uint64_t irq_count[NR_MAX_IRQS]; uint64_t irq_count[NR_IRQS];
uint64_t vmexit_cnt[64]; uint64_t vmexit_cnt[64];
uint64_t vmexit_time[64]; uint64_t vmexit_time[64];
uint64_t softirq_pending; uint64_t softirq_pending;