changeset 549:0455834d29a1

- dyncallback: x64/sysv buffer overflow fix for aggregate args whose size isn't a multiple of 8
author Tassilo Philipp
date Mon, 20 Jun 2022 11:15:09 +0200
parents a6d00ee46731
children 5e1002095afa
files dyncallback/dyncall_args_x64.c
diffstat 1 files changed, 16 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/dyncallback/dyncall_args_x64.c	Mon Jun 20 11:04:20 2022 +0200
+++ b/dyncallback/dyncall_args_x64.c	Mon Jun 20 11:15:09 2022 +0200
@@ -100,7 +100,7 @@
   if(ag->sysv_classes[0] == SYSVC_MEMORY || (n_regs.i > numIntRegs) || (n_regs.f > numFloatRegs))
   {
      memcpy(target, p->stack_ptr, ag->size);
-     p->stack_ptr = p->stack_ptr + ((ag->size + (sizeof(DClonglong)-1)) >> 3); // advance to next full stack slot
+     p->stack_ptr = p->stack_ptr + ((ag->size + (sizeof(DClonglong)-1)) >> 3); /* advance to next full stack slot */
   }
   else
   {
@@ -108,8 +108,21 @@
     {
       switch (ag->sysv_classes[i])
       {
-        case SYSVC_INTEGER: ((DClonglong*)target)[i] = dcbArgLongLong(p); break;
-        case SYSVC_SSE:     ((DCdouble  *)target)[i] = dcbArgDouble  (p); break;
+        case SYSVC_INTEGER:
+          switch (ag->size - i*8) {
+            case 1:  *(DCchar *)(((DClonglong*)target) + i) = dcbArgChar    (p); break;
+            case 2:  *(DCshort*)(((DClonglong*)target) + i) = dcbArgShort   (p); break;
+            case 4:  *(DCint  *)(((DClonglong*)target) + i) = dcbArgInt     (p); break;
+            default: *          (((DClonglong*)target) + i) = dcbArgLongLong(p); break;
+          }
+          break;
+
+        case SYSVC_SSE:
+          switch (ag->size - i*8) {
+            case 4:  *(DCfloat*)(((DCdouble*)target) + i) = dcbArgFloat (p); break;
+            default: *          (((DCdouble*)target) + i) = dcbArgDouble(p); break;
+          }
+          break;
         /* @@@AGGR implement when implementing x87 types */
         default:
             assert(DC_FALSE && "Should never be reached because we check for unupported classes earlier");