From 7bac4137d757be98de8f6f8d8a649f04cacfdd2f Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Mon, 16 Mar 2020 08:44:38 +1030 Subject: [PATCH] asan: alpha-vms: null dereference * vms-alpha.c (dst_restore_location): Validate index into dst_ptr_offsets array before accessing. Return status. (dst_retrieve_location): Similarly, making "loc" parameter a pointer to return value. (_bfd_vms_slurp_etir): Update calls to above functions. --- bfd/ChangeLog | 8 ++++++++ bfd/vms-alpha.c | 38 +++++++++++++++++++++++++++++--------- 2 files changed, 37 insertions(+), 9 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 5f85a4b37c0..cd421649cc8 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,11 @@ +2020-03-16 Alan Modra + + * vms-alpha.c (dst_restore_location): Validate index into + dst_ptr_offsets array before accessing. Return status. + (dst_retrieve_location): Similarly, making "loc" parameter a + pointer to return value. + (_bfd_vms_slurp_etir): Update calls to above functions. + 2020-03-14 Kamil Rytarowski * configure.ac: Include netbsd-core.lo for all NetBSD arm and mips diff --git a/bfd/vms-alpha.c b/bfd/vms-alpha.c index 241dab340d7..c08d35d4b2e 100644 --- a/bfd/vms-alpha.c +++ b/bfd/vms-alpha.c @@ -1570,22 +1570,32 @@ dst_define_location (bfd *abfd, unsigned int loc) /* Restore saved DST location counter from specified index. */ -static void +static bfd_boolean dst_restore_location (bfd *abfd, unsigned int loc) { vms_debug2 ((4, "dst_restore_location (%d)\n", (int)loc)); - PRIV (image_offset) = PRIV (dst_ptr_offsets)[loc]; + if (loc < PRIV (dst_ptr_offsets_count)) + { + PRIV (image_offset) = PRIV (dst_ptr_offsets)[loc]; + return TRUE; + } + return FALSE; } /* Retrieve saved DST location counter from specified index. */ -static unsigned int -dst_retrieve_location (bfd *abfd, unsigned int loc) +static bfd_boolean +dst_retrieve_location (bfd *abfd, bfd_vma *loc) { - vms_debug2 ((4, "dst_retrieve_location (%d)\n", (int)loc)); + vms_debug2 ((4, "dst_retrieve_location (%d)\n", (int) *loc)); - return PRIV (dst_ptr_offsets)[loc]; + if (*loc < PRIV (dst_ptr_offsets_count)) + { + *loc = PRIV (dst_ptr_offsets)[*loc]; + return TRUE; + } + return FALSE; } /* Write multiple bytes to section image. */ @@ -2326,7 +2336,12 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) return FALSE; if (rel1 != RELC_NONE) goto bad_context; - dst_restore_location (abfd, op1); + if (!dst_restore_location (abfd, op1)) + { + bfd_set_error (bfd_error_bad_value); + _bfd_error_handler (_("invalid %s"), "ETIR__C_CTL_STLOC"); + return FALSE; + } break; /* Stack defined location: pop index, push location counter from index @@ -2336,8 +2351,13 @@ _bfd_vms_slurp_etir (bfd *abfd, struct bfd_link_info *info) return FALSE; if (rel1 != RELC_NONE) goto bad_context; - if (!_bfd_vms_push (abfd, dst_retrieve_location (abfd, op1), - RELC_NONE)) + if (!dst_retrieve_location (abfd, &op1)) + { + bfd_set_error (bfd_error_bad_value); + _bfd_error_handler (_("invalid %s"), "ETIR__C_CTL_STKDL"); + return FALSE; + } + if (!_bfd_vms_push (abfd, op1, RELC_NONE)) return FALSE; break; -- 2.30.2