|
| 1 | +From 7ad06c2efa635bcbd758e96a1c57a957f72e4e1a Mon Sep 17 00:00:00 2001 |
| 2 | +From: AllSpark <allspark@microsoft.com> |
| 3 | +Date: Thu, 2 Apr 2026 09:12:03 +0000 |
| 4 | +Subject: [PATCH] Backport PR33919: Fix XCOFF relocation bounds and safe |
| 5 | + handling in coff-rs6000.c/coff64-rs6000.c; use ARRAY_SIZE and return NULL |
| 6 | + howto; remove XCOFF_MAX_* macros from libxcoff.h; adjust messages to %#x |
| 7 | + |
| 8 | +Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com> |
| 9 | +Upstream-reference: AI Backport of https://sourceware.org/git/?p=binutils-gdb.git;a=patch;h=9e99dbc1f19ffaf18d0250788951706066ebe7f2 |
| 10 | +--- |
| 11 | + bfd/coff-rs6000.c | 36 +++++++++++++++++++++--------------- |
| 12 | + bfd/coff64-rs6000.c | 33 ++++++++++++++++++++------------- |
| 13 | + bfd/libxcoff.h | 3 --- |
| 14 | + 3 files changed, 41 insertions(+), 31 deletions(-) |
| 15 | + |
| 16 | +diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c |
| 17 | +index bfa999d..593d5d2 100644 |
| 18 | +--- a/bfd/coff-rs6000.c |
| 19 | ++++ b/bfd/coff-rs6000.c |
| 20 | +@@ -155,8 +155,7 @@ static xcoff_complain_function xcoff_complain_overflow_bitfield_func; |
| 21 | + static xcoff_complain_function xcoff_complain_overflow_signed_func; |
| 22 | + static xcoff_complain_function xcoff_complain_overflow_unsigned_func; |
| 23 | + |
| 24 | +-xcoff_reloc_function *const |
| 25 | +-xcoff_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION] = |
| 26 | ++xcoff_reloc_function *const xcoff_calculate_relocation[] = |
| 27 | + { |
| 28 | + xcoff_reloc_type_pos, /* R_POS (0x00) */ |
| 29 | + xcoff_reloc_type_neg, /* R_NEG (0x01) */ |
| 30 | +@@ -210,8 +209,7 @@ xcoff_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION] = |
| 31 | + xcoff_reloc_type_toc, /* R_TOCL (0x31) */ |
| 32 | + }; |
| 33 | + |
| 34 | +-xcoff_complain_function *const |
| 35 | +-xcoff_complain_overflow[XCOFF_MAX_COMPLAIN_OVERFLOW] = |
| 36 | ++xcoff_complain_function *const xcoff_complain_overflow[] = |
| 37 | + { |
| 38 | + xcoff_complain_overflow_dont_func, |
| 39 | + xcoff_complain_overflow_bitfield_func, |
| 40 | +@@ -1158,8 +1156,11 @@ reloc_howto_type xcoff_howto_table[] = |
| 41 | + void |
| 42 | + xcoff_rtype2howto (arelent *relent, struct internal_reloc *internal) |
| 43 | + { |
| 44 | +- if (internal->r_type > R_TOCL) |
| 45 | +- abort (); |
| 46 | ++ if (internal->r_type >= ARRAY_SIZE (xcoff_howto_table)) |
| 47 | ++ { |
| 48 | ++ relent->howto = NULL; |
| 49 | ++ return; |
| 50 | ++ } |
| 51 | + |
| 52 | + /* Default howto layout works most of the time */ |
| 53 | + relent->howto = &xcoff_howto_table[internal->r_type]; |
| 54 | +@@ -1183,7 +1184,7 @@ xcoff_rtype2howto (arelent *relent, struct internal_reloc *internal) |
| 55 | + if (relent->howto->dst_mask != 0 |
| 56 | + && (relent->howto->bitsize |
| 57 | + != ((unsigned int) internal->r_size & 0x1f) + 1)) |
| 58 | +- abort (); |
| 59 | ++ relent->howto = NULL; |
| 60 | + } |
| 61 | + |
| 62 | + reloc_howto_type * |
| 63 | +@@ -1236,9 +1237,7 @@ _bfd_xcoff_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, |
| 64 | + { |
| 65 | + unsigned int i; |
| 66 | + |
| 67 | +- for (i = 0; |
| 68 | +- i < sizeof (xcoff_howto_table) / sizeof (xcoff_howto_table[0]); |
| 69 | +- i++) |
| 70 | ++ for (i = 0; i < ARRAY_SIZE (xcoff_howto_table); i++) |
| 71 | + if (xcoff_howto_table[i].name != NULL |
| 72 | + && strcasecmp (xcoff_howto_table[i].name, r_name) == 0) |
| 73 | + return &xcoff_howto_table[i]; |
| 74 | +@@ -3681,6 +3680,14 @@ xcoff_ppc_relocate_section (bfd *output_bfd, |
| 75 | + the csect including the symbol which it references. */ |
| 76 | + if (rel->r_type == R_REF) |
| 77 | + continue; |
| 78 | ++ if (rel->r_type >= ARRAY_SIZE (xcoff_howto_table)) |
| 79 | ++ { |
| 80 | ++ /* xgettext:c-format */ |
| 81 | ++ _bfd_error_handler (_("%pB: unsupported relocation type %#x"), |
| 82 | ++ input_bfd, rel->r_type); |
| 83 | ++ bfd_set_error (bfd_error_bad_value); |
| 84 | ++ return false; |
| 85 | ++ } |
| 86 | + |
| 87 | + /* Retrieve default value in HOWTO table and fix up according |
| 88 | + to r_size field, if it can be different. |
| 89 | +@@ -3700,7 +3707,7 @@ xcoff_ppc_relocate_section (bfd *output_bfd, |
| 90 | + |
| 91 | + default: |
| 92 | + _bfd_error_handler |
| 93 | +- (_("%pB: relocation (%d) at 0x%" PRIx64 " has wrong r_rsize (0x%x)\n"), |
| 94 | ++ (_("%pB: relocation (%#x) at 0x%" PRIx64 " has wrong r_rsize (0x%x)\n"), |
| 95 | + input_bfd, rel->r_type, (uint64_t) rel->r_vaddr, rel->r_size); |
| 96 | + return false; |
| 97 | + } |
| 98 | +@@ -3776,10 +3783,9 @@ xcoff_ppc_relocate_section (bfd *output_bfd, |
| 99 | + } |
| 100 | + } |
| 101 | + |
| 102 | +- if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION |
| 103 | +- || !((*xcoff_calculate_relocation[rel->r_type]) |
| 104 | +- (input_bfd, input_section, output_bfd, rel, sym, &howto, val, |
| 105 | +- addend, &relocation, contents, info))) |
| 106 | ++ if (!((*xcoff_calculate_relocation[rel->r_type]) |
| 107 | ++ (input_bfd, input_section, output_bfd, rel, sym, &howto, val, |
| 108 | ++ addend, &relocation, contents, info))) |
| 109 | + return false; |
| 110 | + |
| 111 | + /* address */ |
| 112 | +diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c |
| 113 | +index fa57910..28baf8a 100644 |
| 114 | +--- a/bfd/coff64-rs6000.c |
| 115 | ++++ b/bfd/coff64-rs6000.c |
| 116 | +@@ -177,8 +177,7 @@ static bool xcoff64_bad_format_hook |
| 117 | + /* Relocation functions */ |
| 118 | + static xcoff_reloc_function xcoff64_reloc_type_br; |
| 119 | + |
| 120 | +-xcoff_reloc_function *const |
| 121 | +-xcoff64_calculate_relocation[XCOFF_MAX_CALCULATE_RELOCATION] = |
| 122 | ++xcoff_reloc_function *const xcoff64_calculate_relocation[] = |
| 123 | + { |
| 124 | + xcoff_reloc_type_pos, /* R_POS (0x00) */ |
| 125 | + xcoff_reloc_type_neg, /* R_NEG (0x01) */ |
| 126 | +@@ -1439,8 +1438,11 @@ reloc_howto_type xcoff64_howto_table[] = |
| 127 | + void |
| 128 | + xcoff64_rtype2howto (arelent *relent, struct internal_reloc *internal) |
| 129 | + { |
| 130 | +- if (internal->r_type > R_TOCL) |
| 131 | +- abort (); |
| 132 | ++ if (internal->r_type >= ARRAY_SIZE (xcoff64_howto_table)) |
| 133 | ++ { |
| 134 | ++ relent->howto = NULL; |
| 135 | ++ return; |
| 136 | ++ } |
| 137 | + |
| 138 | + /* Default howto layout works most of the time */ |
| 139 | + relent->howto = &xcoff64_howto_table[internal->r_type]; |
| 140 | +@@ -1473,7 +1475,7 @@ xcoff64_rtype2howto (arelent *relent, struct internal_reloc *internal) |
| 141 | + if (relent->howto->dst_mask != 0 |
| 142 | + && (relent->howto->bitsize |
| 143 | + != ((unsigned int) internal->r_size & 0x3f) + 1)) |
| 144 | +- abort (); |
| 145 | ++ relent->howto = NULL; |
| 146 | + } |
| 147 | + |
| 148 | + reloc_howto_type * |
| 149 | +@@ -1528,9 +1530,7 @@ xcoff64_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, |
| 150 | + { |
| 151 | + unsigned int i; |
| 152 | + |
| 153 | +- for (i = 0; |
| 154 | +- i < sizeof (xcoff64_howto_table) / sizeof (xcoff64_howto_table[0]); |
| 155 | +- i++) |
| 156 | ++ for (i = 0; i < ARRAY_SIZE (xcoff64_howto_table); i++) |
| 157 | + if (xcoff64_howto_table[i].name != NULL |
| 158 | + && strcasecmp (xcoff64_howto_table[i].name, r_name) == 0) |
| 159 | + return &xcoff64_howto_table[i]; |
| 160 | +@@ -1574,6 +1574,14 @@ xcoff64_ppc_relocate_section (bfd *output_bfd, |
| 161 | + the csect including the symbol which it references. */ |
| 162 | + if (rel->r_type == R_REF) |
| 163 | + continue; |
| 164 | ++ if (rel->r_type >= ARRAY_SIZE (xcoff64_howto_table)) |
| 165 | ++ { |
| 166 | ++ /* xgettext:c-format */ |
| 167 | ++ _bfd_error_handler (_("%pB: unsupported relocation type %#x"), |
| 168 | ++ input_bfd, rel->r_type); |
| 169 | ++ bfd_set_error (bfd_error_bad_value); |
| 170 | ++ return false; |
| 171 | ++ } |
| 172 | + |
| 173 | + /* Retrieve default value in HOWTO table and fix up according |
| 174 | + to r_size field, if it can be different. |
| 175 | +@@ -1595,7 +1603,7 @@ xcoff64_ppc_relocate_section (bfd *output_bfd, |
| 176 | + |
| 177 | + default: |
| 178 | + _bfd_error_handler |
| 179 | +- (_("%pB: relocation (%d) at (0x%" PRIx64 ") has wrong" |
| 180 | ++ (_("%pB: relocation (%#x) at (0x%" PRIx64 ") has wrong" |
| 181 | + " r_rsize (0x%x)\n"), |
| 182 | + input_bfd, rel->r_type, rel->r_vaddr, rel->r_size); |
| 183 | + return false; |
| 184 | +@@ -1668,10 +1676,9 @@ xcoff64_ppc_relocate_section (bfd *output_bfd, |
| 185 | + } |
| 186 | + } |
| 187 | + |
| 188 | +- if (rel->r_type >= XCOFF_MAX_CALCULATE_RELOCATION |
| 189 | +- || !((*xcoff64_calculate_relocation[rel->r_type]) |
| 190 | +- (input_bfd, input_section, output_bfd, rel, sym, &howto, val, |
| 191 | +- addend, &relocation, contents, info))) |
| 192 | ++ if (!((*xcoff64_calculate_relocation[rel->r_type]) |
| 193 | ++ (input_bfd, input_section, output_bfd, rel, sym, &howto, val, |
| 194 | ++ addend, &relocation, contents, info))) |
| 195 | + return false; |
| 196 | + |
| 197 | + /* address */ |
| 198 | +diff --git a/bfd/libxcoff.h b/bfd/libxcoff.h |
| 199 | +index c6ad6dc..01d8ce3 100644 |
| 200 | +--- a/bfd/libxcoff.h |
| 201 | ++++ b/bfd/libxcoff.h |
| 202 | +@@ -215,9 +215,6 @@ struct xcoff_backend_data_rec |
| 203 | + #define bfd_xcoff_text_align_power(a) ((xcoff_data (a)->text_align_power)) |
| 204 | + #define bfd_xcoff_data_align_power(a) ((xcoff_data (a)->data_align_power)) |
| 205 | + |
| 206 | +-/* xcoff*_ppc_relocate_section macros */ |
| 207 | +-#define XCOFF_MAX_CALCULATE_RELOCATION (0x32) |
| 208 | +-#define XCOFF_MAX_COMPLAIN_OVERFLOW (4) |
| 209 | + /* N_ONES produces N one bits, without overflowing machine arithmetic. */ |
| 210 | + #ifdef N_ONES |
| 211 | + #undef N_ONES |
| 212 | +-- |
| 213 | +2.45.4 |
| 214 | + |
0 commit comments