From 26f60d59391c851465e6db26bdedfeeecdcff155 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 2 Mar 2020 10:10:55 +1030 Subject: alpha-vms: prevent endless recursion * vms-lib.c (vms_traverse_index): Add recur_count param and update calls. Fail on excessive recursion. --- bfd/ChangeLog | 5 +++++ bfd/vms-lib.c | 13 ++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index f57c759..d37c2cd 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,10 @@ 2020-03-02 Alan Modra + * vms-lib.c (vms_traverse_index): Add recur_count param and + update calls. Fail on excessive recursion. + +2020-03-02 Alan Modra + * vms-alpha.c (vms_get_remaining_object_record): Use bfd_realloc_or_free rather than bfd_realloc. (add_symbol_entry, vector_grow1, alpha_vms_slurp_relocs): Likewise. diff --git a/bfd/vms-lib.c b/bfd/vms-lib.c index 65fd70a..66a40bc 100644 --- a/bfd/vms-lib.c +++ b/bfd/vms-lib.c @@ -242,7 +242,8 @@ vms_write_block (bfd *abfd, unsigned int vbn, void *blk) If the entry is indirect, recurse. */ static bfd_boolean -vms_traverse_index (bfd *abfd, unsigned int vbn, struct carsym_mem *cs) +vms_traverse_index (bfd *abfd, unsigned int vbn, struct carsym_mem *cs, + unsigned int recur_count) { struct vms_indexdef indexdef; file_ptr off; @@ -250,6 +251,12 @@ vms_traverse_index (bfd *abfd, unsigned int vbn, struct carsym_mem *cs) unsigned char *endp; unsigned int n; + if (recur_count == 100) + { + bfd_set_error (bfd_error_bad_value); + return FALSE; + } + /* Read the index block. */ BFD_ASSERT (sizeof (indexdef) == VMS_BLOCK_SIZE); if (!vms_read_block (abfd, vbn, &indexdef)) @@ -307,7 +314,7 @@ vms_traverse_index (bfd *abfd, unsigned int vbn, struct carsym_mem *cs) if (idx_off == RFADEF__C_INDEX) { /* Indirect entry. Recurse. */ - if (!vms_traverse_index (abfd, idx_vbn, cs)) + if (!vms_traverse_index (abfd, idx_vbn, cs, recur_count + 1)) return FALSE; } else @@ -454,7 +461,7 @@ vms_lib_read_index (bfd *abfd, int idx, unsigned int *nbrel) /* Note: if the index is empty, there is no block to traverse. */ vbn = bfd_getl32 (idd.vbn); - if (vbn != 0 && !vms_traverse_index (abfd, vbn, &csm)) + if (vbn != 0 && !vms_traverse_index (abfd, vbn, &csm, 0)) { if (csm.realloced) free (csm.idx); -- cgit v1.1