| From 62ab108bf89332d41173dc45914200797d1e792d Mon Sep 17 00:00:00 2001 |
| From: Jeremy Drake <github@jdrake.com> |
| Date: Thu, 10 Sep 2020 10:28:28 -0700 |
| Subject: [PATCH] ld option to move default bases under 4GB. |
| |
| Some (buggy) programs have 'latent pointer truncation' issues, and |
| setting the ImageBase below 4GB indicates to Windows that it's not safe |
| to relocate these using ASLR in such a way as to trigger them. |
| --- |
| ld/emultempl/pep.em | 50 ++++++++++++++++++++++++++++++++++++++++++--- |
| 1 file changed, 47 insertions(+), 3 deletions(-) |
| |
| diff --git a/ld/emultempl/pep.em b/ld/emultempl/pep.em |
| index 639a9e96cc..0918a68059 100644 |
| --- a/ld/emultempl/pep.em |
| +++ b/ld/emultempl/pep.em |
| @@ -107,18 +107,26 @@ fragment <<EOF |
| #define NT_EXE_IMAGE_BASE \ |
| ((bfd_vma) (${move_default_addr_high} ? 0x100400000LL \ |
| : 0x140000000LL)) |
| +#undef NT_EXE_IMAGE_BASE_LOW |
| +#define NT_EXE_IMAGE_BASE_LOW ((bfd_vma) 0x400000LL) |
| #undef NT_DLL_IMAGE_BASE |
| #define NT_DLL_IMAGE_BASE \ |
| ((bfd_vma) (${move_default_addr_high} ? 0x400000000LL \ |
| : 0x180000000LL)) |
| +#undef NT_DLL_IMAGE_BASE_LOW |
| +#define NT_DLL_IMAGE_BASE_LOW ((bfd_vma) 0x10000000LL) |
| #undef NT_DLL_AUTO_IMAGE_BASE |
| #define NT_DLL_AUTO_IMAGE_BASE \ |
| ((bfd_vma) (${move_default_addr_high} ? 0x400000000LL \ |
| : 0x1C0000000LL)) |
| +#undef NT_DLL_AUTO_IMAGE_BASE_LOW |
| +#define NT_DLL_AUTO_IMAGE_BASE_LOW ((bfd_vma) 0x61300000LL) |
| #undef NT_DLL_AUTO_IMAGE_MASK |
| #define NT_DLL_AUTO_IMAGE_MASK \ |
| ((bfd_vma) (${move_default_addr_high} ? 0x1ffff0000LL \ |
| : 0x1ffff0000LL)) |
| +#undef NT_DLL_AUTO_IMAGE_MASK_LOW |
| +#define NT_DLL_AUTO_IMAGE_MASK_LOW ((bfd_vma) 0x0ffc0000LL) |
| #else |
| #undef NT_EXE_IMAGE_BASE |
| #define NT_EXE_IMAGE_BASE \ |
| @@ -151,6 +159,7 @@ static int support_old_code = 0; |
| static lang_assignment_statement_type *image_base_statement = 0; |
| static unsigned short pe_dll_characteristics = DEFAULT_DLL_CHARACTERISTICS; |
| static bfd_boolean insert_timestamp = TRUE; |
| +static bfd_boolean high_default_bases = TRUE; |
| static const char *emit_build_id; |
| |
| #ifdef DLL_SUPPORT |
| @@ -260,7 +269,9 @@ enum options |
| OPTION_DISABLE_NO_SEH, |
| OPTION_DISABLE_NO_BIND, |
| OPTION_DISABLE_WDM_DRIVER, |
| - OPTION_DISABLE_TERMINAL_SERVER_AWARE |
| + OPTION_DISABLE_TERMINAL_SERVER_AWARE, |
| + OPTION_DEFAULT_IMAGE_BASE_LOW, |
| + OPTION_DEFAULT_IMAGE_BASE_HIGH |
| }; |
| |
| static void |
| @@ -349,6 +360,10 @@ gld${EMULATION_NAME}_add_options |
| {"disable-no-bind", no_argument, NULL, OPTION_DISABLE_NO_BIND}, |
| {"disable-wdmdriver", no_argument, NULL, OPTION_DISABLE_WDM_DRIVER}, |
| {"disable-tsaware", no_argument, NULL, OPTION_DISABLE_TERMINAL_SERVER_AWARE}, |
| +#if defined(TARGET_IS_i386pep) || ! defined(DLL_SUPPORT) |
| + {"default-image-base-low", no_argument, NULL, OPTION_DEFAULT_IMAGE_BASE_LOW}, |
| + {"default-image-base-high", no_argument, NULL, OPTION_DEFAULT_IMAGE_BASE_HIGH}, |
| +#endif |
| {NULL, no_argument, NULL, 0} |
| }; |
| |
| @@ -486,6 +501,10 @@ gld_${EMULATION_NAME}_list_options (FILE *file) |
| fprintf (file, _(" --[disable-]tsaware Image is Terminal Server aware\n")); |
| fprintf (file, _(" --build-id[=STYLE] Generate build ID\n")); |
| #endif |
| +#if defined(TARGET_IS_i386pep) || ! defined(DLL_SUPPORT) |
| + fprintf (file, _(" --default-image-base-low Default image bases under 4GB\n")); |
| + fprintf (file, _(" --default-image-base-high Default image bases over 4GB\n")); |
| +#endif |
| } |
| |
| |
| @@ -893,6 +912,12 @@ gld${EMULATION_NAME}_handle_option (int optc) |
| if (strcmp (optarg, "none")) |
| emit_build_id = xstrdup (optarg); |
| break; |
| + case OPTION_DEFAULT_IMAGE_BASE_LOW: |
| + high_default_bases = FALSE; |
| + break; |
| + case OPTION_DEFAULT_IMAGE_BASE_HIGH: |
| + high_default_bases = TRUE; |
| + break; |
| } |
| |
| /* Set DLLCharacteristics bits */ |
| @@ -932,7 +957,14 @@ static bfd_vma |
| compute_dll_image_base (const char *ofile) |
| { |
| bfd_vma hash = (bfd_vma) strhash (ofile); |
| - return NT_DLL_AUTO_IMAGE_BASE + ((hash << 16) & NT_DLL_AUTO_IMAGE_MASK); |
| +#ifdef TARGET_IS_i386pep |
| + if (high_default_bases) |
| +#endif |
| + return NT_DLL_AUTO_IMAGE_BASE + ((hash << 16) & NT_DLL_AUTO_IMAGE_MASK); |
| +#ifdef TARGET_IS_i386pep |
| + else |
| + return NT_DLL_AUTO_IMAGE_BASE_LOW + ((hash << 16) & NT_DLL_AUTO_IMAGE_MASK_LOW); |
| +#endif |
| } |
| #endif |
| |
| @@ -957,13 +989,25 @@ gld_${EMULATION_NAME}_set_symbols (void) |
| #ifdef DLL_SUPPORT |
| init[IMAGEBASEOFF].value = (pep_enable_auto_image_base |
| ? compute_dll_image_base (output_filename) |
| +#ifdef TARGET_IS_i386pep |
| + : (high_default_bases |
| + ? NT_DLL_IMAGE_BASE |
| + : NT_DLL_IMAGE_BASE_LOW)); |
| +#else |
| : NT_DLL_IMAGE_BASE); |
| +#endif |
| #else |
| - init[IMAGEBASEOFF].value = NT_DLL_IMAGE_BASE; |
| + init[IMAGEBASEOFF].value = (high_default_bases ? NT_DLL_IMAGE_BASE : NT_DLL_IMAGE_BASE_LOW); |
| #endif |
| } |
| else |
| +#if defined(TARGET_IS_i386pep) || ! defined(DLL_SUPPORT) |
| + init[IMAGEBASEOFF].value = (high_default_bases |
| + ? NT_EXE_IMAGE_BASE |
| + : NT_EXE_IMAGE_BASE_LOW); |
| +#else |
| init[IMAGEBASEOFF].value = NT_EXE_IMAGE_BASE; |
| +#endif |
| init[MSIMAGEBASEOFF].value = init[IMAGEBASEOFF].value; |
| } |
| |
| -- |
| 2.28.0.windows.1 |
| |