alpha-vms: ETIR checks
Better validity checks, and remove a fuzzer vulnerability of sorts that targeted the store-immediate-repeat command with a zero length but very large repeat counts to chew cpu. * vms-alpha.c (_bfd_vms_slurp_etir): Check bound for the current command against cmd_length, not the end of record. For ETIR__C_STO_IMMR check size against cmd_length, mask repeat count to 32-bits and break out on zero size. Add ETIR__C_STC_LP_PSB cmd_length test.
This commit is contained in:
parent
3c3d03769e
commit
2fdb65f247
2 changed files with 29 additions and 13 deletions
|
@ -1,3 +1,11 @@
|
||||||
|
2020-06-01 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* vms-alpha.c (_bfd_vms_slurp_etir): Check bound for the current
|
||||||
|
command against cmd_length, not the end of record. For
|
||||||
|
ETIR__C_STO_IMMR check size against cmd_length, mask repeat count
|
||||||
|
to 32-bits and break out on zero size. Add ETIR__C_STC_LP_PSB
|
||||||
|
cmd_length test.
|
||||||
|
|
||||||
2020-05-28 David Faust <david.faust@oracle.com>
|
2020-05-28 David Faust <david.faust@oracle.com>
|
||||||
|
|
||||||
* elf64-bpf.c (bpf_elf_relocate_section): Fix handling of
|
* elf64-bpf.c (bpf_elf_relocate_section): Fix handling of
|
||||||
|
|
|
@ -1925,11 +1925,12 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
ptr += 4;
|
ptr += 4;
|
||||||
|
cmd_length -= 4;
|
||||||
|
|
||||||
#if VMS_DEBUG
|
#if VMS_DEBUG
|
||||||
_bfd_vms_debug (4, "etir: %s(%d)\n",
|
_bfd_vms_debug (4, "etir: %s(%d)\n",
|
||||||
_bfd_vms_etir_name (cmd), cmd);
|
_bfd_vms_etir_name (cmd), cmd);
|
||||||
_bfd_hexdump (8, ptr, cmd_length - 4, 0);
|
_bfd_hexdump (8, ptr, cmd_length, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch (cmd)
|
switch (cmd)
|
||||||
|
@ -1939,7 +1940,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
|
||||||
|
|
||||||
stack 32 bit value of symbol (high bits set to 0). */
|
stack 32 bit value of symbol (high bits set to 0). */
|
||||||
case ETIR__C_STA_GBL:
|
case ETIR__C_STA_GBL:
|
||||||
_bfd_vms_get_value (abfd, ptr, maxptr, info, &op1, &h);
|
_bfd_vms_get_value (abfd, ptr, ptr + cmd_length, info, &op1, &h);
|
||||||
if (!_bfd_vms_push (abfd, op1, alpha_vms_sym_to_ctxt (h)))
|
if (!_bfd_vms_push (abfd, op1, alpha_vms_sym_to_ctxt (h)))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
break;
|
break;
|
||||||
|
@ -1949,7 +1950,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
|
||||||
|
|
||||||
stack 32 bit value, sign extend to 64 bit. */
|
stack 32 bit value, sign extend to 64 bit. */
|
||||||
case ETIR__C_STA_LW:
|
case ETIR__C_STA_LW:
|
||||||
if (ptr + 4 > maxptr)
|
if (cmd_length < 4)
|
||||||
goto corrupt_etir;
|
goto corrupt_etir;
|
||||||
if (!_bfd_vms_push (abfd, bfd_getl32 (ptr), RELC_NONE))
|
if (!_bfd_vms_push (abfd, bfd_getl32 (ptr), RELC_NONE))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -1960,7 +1961,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
|
||||||
|
|
||||||
stack 64 bit value of symbol. */
|
stack 64 bit value of symbol. */
|
||||||
case ETIR__C_STA_QW:
|
case ETIR__C_STA_QW:
|
||||||
if (ptr + 8 > maxptr)
|
if (cmd_length < 8)
|
||||||
goto corrupt_etir;
|
goto corrupt_etir;
|
||||||
if (!_bfd_vms_push (abfd, bfd_getl64 (ptr), RELC_NONE))
|
if (!_bfd_vms_push (abfd, bfd_getl64 (ptr), RELC_NONE))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -1976,7 +1977,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
|
||||||
{
|
{
|
||||||
int psect;
|
int psect;
|
||||||
|
|
||||||
if (ptr + 12 > maxptr)
|
if (cmd_length < 12)
|
||||||
goto corrupt_etir;
|
goto corrupt_etir;
|
||||||
psect = bfd_getl32 (ptr);
|
psect = bfd_getl32 (ptr);
|
||||||
if ((unsigned int) psect >= PRIV (section_count))
|
if ((unsigned int) psect >= PRIV (section_count))
|
||||||
|
@ -2079,13 +2080,18 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
|
||||||
{
|
{
|
||||||
int size;
|
int size;
|
||||||
|
|
||||||
if (ptr + 4 > maxptr)
|
if (cmd_length < 4)
|
||||||
goto corrupt_etir;
|
goto corrupt_etir;
|
||||||
size = bfd_getl32 (ptr);
|
size = bfd_getl32 (ptr);
|
||||||
|
if (size > cmd_length - 4)
|
||||||
|
goto corrupt_etir;
|
||||||
if (!_bfd_vms_pop (abfd, &op1, &rel1))
|
if (!_bfd_vms_pop (abfd, &op1, &rel1))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
if (rel1 != RELC_NONE)
|
if (rel1 != RELC_NONE)
|
||||||
goto bad_context;
|
goto bad_context;
|
||||||
|
if (size == 0)
|
||||||
|
break;
|
||||||
|
op1 &= 0xffffffff;
|
||||||
while (op1-- > 0)
|
while (op1-- > 0)
|
||||||
if (!image_write (abfd, ptr + 4, size))
|
if (!image_write (abfd, ptr + 4, size))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
@ -2095,7 +2101,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
|
||||||
/* Store global: write symbol value
|
/* Store global: write symbol value
|
||||||
arg: cs global symbol name. */
|
arg: cs global symbol name. */
|
||||||
case ETIR__C_STO_GBL:
|
case ETIR__C_STO_GBL:
|
||||||
_bfd_vms_get_value (abfd, ptr, maxptr, info, &op1, &h);
|
_bfd_vms_get_value (abfd, ptr, ptr + cmd_length, info, &op1, &h);
|
||||||
if (h && h->sym)
|
if (h && h->sym)
|
||||||
{
|
{
|
||||||
if (h->sym->typ == EGSD__C_SYMG)
|
if (h->sym->typ == EGSD__C_SYMG)
|
||||||
|
@ -2120,7 +2126,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
|
||||||
/* Store code address: write address of entry point
|
/* Store code address: write address of entry point
|
||||||
arg: cs global symbol name (procedure). */
|
arg: cs global symbol name (procedure). */
|
||||||
case ETIR__C_STO_CA:
|
case ETIR__C_STO_CA:
|
||||||
_bfd_vms_get_value (abfd, ptr, maxptr, info, &op1, &h);
|
_bfd_vms_get_value (abfd, ptr, ptr + cmd_length, info, &op1, &h);
|
||||||
if (h && h->sym)
|
if (h && h->sym)
|
||||||
{
|
{
|
||||||
if (h->sym->flags & EGSY__V_NORM)
|
if (h->sym->flags & EGSY__V_NORM)
|
||||||
|
@ -2172,7 +2178,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
|
||||||
{
|
{
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
|
|
||||||
if (ptr + 4 > maxptr)
|
if (cmd_length < 4)
|
||||||
goto corrupt_etir;
|
goto corrupt_etir;
|
||||||
size = bfd_getl32 (ptr);
|
size = bfd_getl32 (ptr);
|
||||||
if (!image_write (abfd, ptr + 4, size))
|
if (!image_write (abfd, ptr + 4, size))
|
||||||
|
@ -2187,7 +2193,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
|
||||||
store global longword: store 32bit value of symbol
|
store global longword: store 32bit value of symbol
|
||||||
arg: cs symbol name. */
|
arg: cs symbol name. */
|
||||||
case ETIR__C_STO_GBL_LW:
|
case ETIR__C_STO_GBL_LW:
|
||||||
_bfd_vms_get_value (abfd, ptr, maxptr, info, &op1, &h);
|
_bfd_vms_get_value (abfd, ptr, ptr + cmd_length, info, &op1, &h);
|
||||||
#if 0
|
#if 0
|
||||||
abort ();
|
abort ();
|
||||||
#endif
|
#endif
|
||||||
|
@ -2241,7 +2247,9 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
|
||||||
da signature. */
|
da signature. */
|
||||||
|
|
||||||
case ETIR__C_STC_LP_PSB:
|
case ETIR__C_STC_LP_PSB:
|
||||||
_bfd_vms_get_value (abfd, ptr + 4, maxptr, info, &op1, &h);
|
if (cmd_length < 4)
|
||||||
|
goto corrupt_etir;
|
||||||
|
_bfd_vms_get_value (abfd, ptr + 4, ptr + cmd_length, info, &op1, &h);
|
||||||
if (h && h->sym)
|
if (h && h->sym)
|
||||||
{
|
{
|
||||||
if (h->sym->typ == EGSD__C_SYMG)
|
if (h->sym->typ == EGSD__C_SYMG)
|
||||||
|
@ -2340,7 +2348,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
|
||||||
/* Augment relocation base: increment image location counter by offset
|
/* Augment relocation base: increment image location counter by offset
|
||||||
arg: lw offset value. */
|
arg: lw offset value. */
|
||||||
case ETIR__C_CTL_AUGRB:
|
case ETIR__C_CTL_AUGRB:
|
||||||
if (ptr + 4 > maxptr)
|
if (cmd_length < 4)
|
||||||
goto corrupt_etir;
|
goto corrupt_etir;
|
||||||
op1 = bfd_getl32 (ptr);
|
op1 = bfd_getl32 (ptr);
|
||||||
image_inc_ptr (abfd, op1);
|
image_inc_ptr (abfd, op1);
|
||||||
|
@ -2554,7 +2562,7 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr += cmd_length - 4;
|
ptr += cmd_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue