From: Nadav Har'El <n...@scylladb.com>
Committer: Nadav Har'El <n...@scylladb.com>
Branch: master

xen: fix stack overread/overwrite

Gcc 12.1.1 started to detect a real error in how we used the
HYPERVISOR_physdev_op() function in bsd/sys/xen/evtchn.cc:

That function assumed its "arg" parameter points to a 16-byte area, the
maximum size of various operations, but the callers used different sizes.
This can lead to reading and writing beyond the end of the stack. It is
unlikely that the small overread/write will cause a real bug, but now
that the compiler also started to complain, let's fix it.

This is one of the fixes needed to build on Fedora 36 (refs #1198).

Signed-off-by: Nadav Har'El <n...@scylladb.com>

---
diff --git a/bsd/sys/xen/evtchn.cc b/bsd/sys/xen/evtchn.cc
--- a/bsd/sys/xen/evtchn.cc
+++ b/bsd/sys/xen/evtchn.cc
@@ -771,22 +771,23 @@ MAKE_SYMBOL(notify_remote_via_evtchn);
 static inline void 
 pirq_unmask_notify(int pirq)
 {
-       struct physdev_eoi eoi = { .irq = pirq };
+       physdev_op_arg arg;
+       arg.eoi = { .irq = pirq };
 
        if (unlikely(test_bit(pirq, &pirq_needs_unmask_notify[0]))) {
-               (void)HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &eoi);
+               (void)HYPERVISOR_physdev_op(PHYSDEVOP_eoi, &arg);
        }
 }
 
 static inline void 
 pirq_query_unmask(int pirq)
 {
-       struct physdev_irq_status_query irq_status_query;
+       physdev_op_arg arg;
 
-       irq_status_query.irq = pirq;
-       (void)HYPERVISOR_physdev_op(PHYSDEVOP_IRQ_STATUS_QUERY, 
&irq_status_query);
+       arg.irq_status_query.irq = pirq;
+       (void)HYPERVISOR_physdev_op(PHYSDEVOP_IRQ_STATUS_QUERY, &arg);
        clear_bit(pirq, &pirq_needs_unmask_notify[0]);
-       if ( irq_status_query.flags & PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY )
+       if (arg.irq_status_query.flags & PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY)
                set_bit(pirq, &pirq_needs_unmask_notify[0]);
 }
 
diff --git a/bsd/sys/xen/interface/physdev.h b/bsd/sys/xen/interface/physdev.h
--- a/bsd/sys/xen/interface/physdev.h
+++ b/bsd/sys/xen/interface/physdev.h
@@ -168,19 +168,22 @@ struct physdev_manage_pci {
 typedef struct physdev_manage_pci physdev_manage_pci_t;
 DEFINE_XEN_GUEST_HANDLE(physdev_manage_pci_t);
 
+typedef union {
+    struct physdev_irq_status_query      irq_status_query;
+    struct physdev_set_iopl              set_iopl;
+    struct physdev_set_iobitmap          set_iobitmap;
+    struct physdev_apic                  apic_op;
+    struct physdev_irq                   irq_op;
+    struct physdev_eoi                   eoi;
+} physdev_op_arg;
+
 /*
  * Argument to physdev_op_compat() hypercall. Superceded by new physdev_op()
  * hypercall since 0x00030202.
  */
 struct physdev_op {
     uint32_t cmd;
-    union {
-        struct physdev_irq_status_query      irq_status_query;
-        struct physdev_set_iopl              set_iopl;
-        struct physdev_set_iobitmap          set_iobitmap;
-        struct physdev_apic                  apic_op;
-        struct physdev_irq                   irq_op;
-    } u;
+    physdev_op_arg u;
 };
 typedef struct physdev_op physdev_op_t;
 DEFINE_XEN_GUEST_HANDLE(physdev_op_t);

-- 
You received this message because you are subscribed to the Google Groups "OSv 
Development" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to osv-dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/osv-dev/000000000000e5f59d05e254ecb4%40google.com.

Reply via email to