diff --git a/sys/arm/arm/elf_machdep.c b/sys/arm/arm/elf_machdep.c index a8a0647c7224..af79a8f6ffe8 100644 --- a/sys/arm/arm/elf_machdep.c +++ b/sys/arm/arm/elf_machdep.c @@ -56,7 +56,8 @@ __FBSDID("$FreeBSD$"); #include "opt_global.h" /* for OPT_KDTRACE_HOOKS */ #include "opt_stack.h" /* for OPT_STACK */ -static boolean_t elf32_arm_abi_supported(struct image_params *); +static boolean_t elf32_arm_abi_supported(struct image_params *, int32_t *, + uint32_t *); u_long elf_hwcap; u_long elf_hwcap2; @@ -121,7 +122,8 @@ SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_FIRST, &freebsd_brand_info); static boolean_t -elf32_arm_abi_supported(struct image_params *imgp) +elf32_arm_abi_supported(struct image_params *imgp, int32_t *osrel __unused, + uint32_t *fctl0 __unused) { const Elf_Ehdr *hdr = (const Elf_Ehdr *)imgp->image_header; diff --git a/sys/arm64/arm64/elf32_machdep.c b/sys/arm64/arm64/elf32_machdep.c index d41ee0b3ac27..f99523cb6362 100644 --- a/sys/arm64/arm64/elf32_machdep.c +++ b/sys/arm64/arm64/elf32_machdep.c @@ -69,7 +69,8 @@ static void freebsd32_setregs(struct thread *td, struct image_params *imgp, u_long stack); static void freebsd32_set_syscall_retval(struct thread *, int); -static boolean_t elf32_arm_abi_supported(struct image_params *); +static boolean_t elf32_arm_abi_supported(struct image_params *, int32_t *, + uint32_t *); extern void freebsd32_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask); @@ -126,7 +127,8 @@ SYSINIT(elf32, SI_SUB_EXEC, SI_ORDER_FIRST, (sysinit_cfunc_t)elf32_insert_brand_entry, &freebsd32_brand_info); static boolean_t -elf32_arm_abi_supported(struct image_params *imgp) +elf32_arm_abi_supported(struct image_params *imgp, int32_t *osrel __unused, + uint32_t *fctl0 __unused) { const Elf32_Ehdr *hdr; diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c index fe71acabe0b7..1f40ce5fc6fd 100644 --- a/sys/kern/imgact_elf.c +++ b/sys/kern/imgact_elf.c @@ -97,7 +97,8 @@ static bool __elfN(freebsd_trans_osrel)(const Elf_Note *note, int32_t *osrel); static bool kfreebsd_trans_osrel(const Elf_Note *note, int32_t *osrel); static boolean_t __elfN(check_note)(struct image_params *imgp, - Elf_Brandnote *checknote, int32_t *osrel, uint32_t *fctl0); + Elf_Brandnote *checknote, int32_t *osrel, boolean_t *has_fctl0, + uint32_t *fctl0); static vm_prot_t __elfN(trans_prot)(Elf_Word); static Elf_Word __elfN(untrans_prot)(vm_prot_t); @@ -309,7 +310,7 @@ __elfN(get_brandinfo)(struct image_params *imgp, const char *interp, { const Elf_Ehdr *hdr = (const Elf_Ehdr *)imgp->image_header; Elf_Brandinfo *bi, *bi_m; - boolean_t ret; + boolean_t ret, has_fctl0; int i, interp_name_len; interp_name_len = interp != NULL ? strlen(interp) + 1 : 0; @@ -331,11 +332,16 @@ __elfN(get_brandinfo)(struct image_params *imgp, const char *interp, continue; if (hdr->e_machine == bi->machine && (bi->flags & (BI_BRAND_NOTE|BI_BRAND_NOTE_MANDATORY)) != 0) { + has_fctl0 = false; + *fctl0 = 0; + *osrel = 0; ret = __elfN(check_note)(imgp, bi->brand_note, osrel, - fctl0); + &has_fctl0, fctl0); /* Give brand a chance to veto check_note's guess */ - if (ret && bi->header_supported) - ret = bi->header_supported(imgp); + if (ret && bi->header_supported) { + ret = bi->header_supported(imgp, osrel, + has_fctl0 ? fctl0 : NULL); + } /* * If note checker claimed the binary, but the * interpreter path in the image does not @@ -374,7 +380,7 @@ __elfN(get_brandinfo)(struct image_params *imgp, const char *interp, bi->compat_3_brand) == 0))) { /* Looks good, but give brand a chance to veto */ if (bi->header_supported == NULL || - bi->header_supported(imgp)) { + bi->header_supported(imgp, NULL, NULL)) { /* * Again, prefer strictly matching * interpreter path. @@ -402,7 +408,7 @@ __elfN(get_brandinfo)(struct image_params *imgp, const char *interp, bi->header_supported == NULL) continue; if (hdr->e_machine == bi->machine) { - ret = bi->header_supported(imgp); + ret = bi->header_supported(imgp, NULL, NULL); if (ret) return (bi); } @@ -422,7 +428,7 @@ __elfN(get_brandinfo)(struct image_params *imgp, const char *interp, strlen(bi->interp_path) + 1 == interp_name_len && strncmp(interp, bi->interp_path, interp_name_len) == 0 && (bi->header_supported == NULL || - bi->header_supported(imgp))) + bi->header_supported(imgp, NULL, NULL))) return (bi); } } @@ -436,7 +442,7 @@ __elfN(get_brandinfo)(struct image_params *imgp, const char *interp, if (hdr->e_machine == bi->machine && __elfN(fallback_brand) == bi->brand && (bi->header_supported == NULL || - bi->header_supported(imgp))) + bi->header_supported(imgp, NULL, NULL))) return (bi); } return (NULL); @@ -2657,6 +2663,7 @@ static Elf_Note fctl_note = { }; struct fctl_cb_arg { + boolean_t *has_fctl0; uint32_t *fctl0; }; @@ -2671,6 +2678,7 @@ note_fctl_cb(const Elf_Note *note, void *arg0, boolean_t *res) p = (uintptr_t)(note + 1); p += roundup2(note->n_namesz, ELF_NOTE_ROUNDSIZE); desc = (const Elf32_Word *)p; + *arg->has_fctl0 = TRUE; *arg->fctl0 = desc[0]; return (TRUE); } @@ -2683,7 +2691,7 @@ note_fctl_cb(const Elf_Note *note, void *arg0, boolean_t *res) */ static boolean_t __elfN(check_note)(struct image_params *imgp, Elf_Brandnote *brandnote, - int32_t *osrel, uint32_t *fctl0) + int32_t *osrel, boolean_t *has_fctl0, uint32_t *fctl0) { const Elf_Phdr *phdr; const Elf_Ehdr *hdr; @@ -2695,6 +2703,7 @@ __elfN(check_note)(struct image_params *imgp, Elf_Brandnote *brandnote, phdr = (const Elf_Phdr *)(imgp->image_header + hdr->e_phoff); b_arg.brandnote = brandnote; b_arg.osrel = osrel; + f_arg.has_fctl0 = has_fctl0; f_arg.fctl0 = fctl0; for (i = 0; i < hdr->e_phnum; i++) { diff --git a/sys/powerpc/powerpc/elf64_machdep.c b/sys/powerpc/powerpc/elf64_machdep.c index 5cb5df710081..82c25cb8c0ff 100644 --- a/sys/powerpc/powerpc/elf64_machdep.c +++ b/sys/powerpc/powerpc/elf64_machdep.c @@ -135,8 +135,10 @@ struct sysentvec elf64_freebsd_sysvec_v2 = { }; INIT_SYSENTVEC(elf64_sysvec_v2, &elf64_freebsd_sysvec_v2); -static boolean_t ppc64_elfv1_header_match(struct image_params *params); -static boolean_t ppc64_elfv2_header_match(struct image_params *params); +static boolean_t ppc64_elfv1_header_match(struct image_params *params, + int32_t *, uint32_t *); +static boolean_t ppc64_elfv2_header_match(struct image_params *params, + int32_t *, uint32_t *); static Elf64_Brandinfo freebsd_brand_info_elfv1 = { .brand = ELFOSABI_FREEBSD, @@ -192,7 +194,8 @@ SYSINIT(oelf64, SI_SUB_EXEC, SI_ORDER_ANY, void elf_reloc_self(Elf_Dyn *dynp, Elf_Addr relocbase); static boolean_t -ppc64_elfv1_header_match(struct image_params *params) +ppc64_elfv1_header_match(struct image_params *params, int32_t *osrel __unused, + uint32_t *fctl0 __unused) { const Elf64_Ehdr *hdr = (const Elf64_Ehdr *)params->image_header; int abi = (hdr->e_flags & 3); @@ -201,7 +204,8 @@ ppc64_elfv1_header_match(struct image_params *params) } static boolean_t -ppc64_elfv2_header_match(struct image_params *params) +ppc64_elfv2_header_match(struct image_params *params, int32_t *osrel __unused, + uint32_t *fctl0 __unused) { const Elf64_Ehdr *hdr = (const Elf64_Ehdr *)params->image_header; int abi = (hdr->e_flags & 3); diff --git a/sys/sys/imgact_elf.h b/sys/sys/imgact_elf.h index 960b0fa48e7d..ca95798c7288 100644 --- a/sys/sys/imgact_elf.h +++ b/sys/sys/imgact_elf.h @@ -87,7 +87,8 @@ typedef struct { const char *interp_newpath; int flags; Elf_Brandnote *brand_note; - boolean_t (*header_supported)(struct image_params *); + boolean_t (*header_supported)(struct image_params *, + int32_t *, uint32_t *); #define BI_CAN_EXEC_DYN 0x0001 #define BI_BRAND_NOTE 0x0002 /* May have note.ABI-tag section. */ #define BI_BRAND_NOTE_MANDATORY 0x0004 /* Must have note.ABI-tag section. */