summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2016-02-07 09:51:22 +0000
committerkib <kib@FreeBSD.org>2016-02-07 09:51:22 +0000
commitc76cb9755e8e722ba04e0c26cf28ecc0adeb52de (patch)
treef460bf27f82e21d657828960d812717d1c5b5bf2
parent4ef5827b6250178df59526f9bdcffe2704998fc4 (diff)
downloadFreeBSD-src-c76cb9755e8e722ba04e0c26cf28ecc0adeb52de.zip
FreeBSD-src-c76cb9755e8e722ba04e0c26cf28ecc0adeb52de.tar.gz
MFC r295277:
When matching brand to the ELF binary by notes, try to find a brand with interpreter name exactly matching one wanted by the binary. Approved by: re (delphij)
-rw-r--r--sys/kern/imgact_elf.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/sys/kern/imgact_elf.c b/sys/kern/imgact_elf.c
index 05f3a43..394d61f 100644
--- a/sys/kern/imgact_elf.c
+++ b/sys/kern/imgact_elf.c
@@ -261,7 +261,7 @@ __elfN(get_brandinfo)(struct image_params *imgp, const char *interp,
int interp_name_len, int32_t *osrel)
{
const Elf_Ehdr *hdr = (const Elf_Ehdr *)imgp->image_header;
- Elf_Brandinfo *bi;
+ Elf_Brandinfo *bi, *bi_m;
boolean_t ret;
int i;
@@ -273,6 +273,7 @@ __elfN(get_brandinfo)(struct image_params *imgp, const char *interp,
*/
/* Look for an ".note.ABI-tag" ELF section */
+ bi_m = NULL;
for (i = 0; i < MAX_BRANDS; i++) {
bi = elf_brand_list[i];
if (bi == NULL)
@@ -280,10 +281,28 @@ __elfN(get_brandinfo)(struct image_params *imgp, const char *interp,
if (hdr->e_machine == bi->machine && (bi->flags &
(BI_BRAND_NOTE|BI_BRAND_NOTE_MANDATORY)) != 0) {
ret = __elfN(check_note)(imgp, bi->brand_note, osrel);
+ /*
+ * If note checker claimed the binary, but the
+ * interpreter path in the image does not
+ * match default one for the brand, try to
+ * search for other brands with the same
+ * interpreter. Either there is better brand
+ * with the right interpreter, or, failing
+ * this, we return first brand which accepted
+ * our note and, optionally, header.
+ */
+ if (ret && bi_m == NULL && (strlen(bi->interp_path) +
+ 1 != interp_name_len || strncmp(interp,
+ bi->interp_path, interp_name_len) != 0)) {
+ bi_m = bi;
+ ret = 0;
+ }
if (ret)
return (bi);
}
}
+ if (bi_m != NULL)
+ return (bi_m);
/* If the executable has a brand, search for it in the brand list. */
for (i = 0; i < MAX_BRANDS; i++) {
OpenPOWER on IntegriCloud