# HG changeset patch # User Tassilo Philipp # Date 1655716509 -7200 # Node ID 0455834d29a18995d7e5390c291bf97e40d3f2d5 # Parent a6d00ee46731371ec3afe556bd75482bdf6ba9ff - dyncallback: x64/sysv buffer overflow fix for aggregate args whose size isn't a multiple of 8 diff -r a6d00ee46731 -r 0455834d29a1 dyncallback/dyncall_args_x64.c --- 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");