Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 23 Nov 2018 23:33:55 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r340864 - head/sys/kern
Message-ID:  <201811232333.wANNXtts047712@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: kib
Date: Fri Nov 23 23:33:55 2018
New Revision: 340864
URL: https://svnweb.freebsd.org/changeset/base/340864

Log:
  Parse FreeBSD Feature Control note on the ELF image activation.
  
  Sponsored by:	The FreeBSD Foundation
  MFC after:	2 weeks

Modified:
  head/sys/kern/imgact_elf.c

Modified: head/sys/kern/imgact_elf.c
==============================================================================
--- head/sys/kern/imgact_elf.c	Fri Nov 23 23:29:14 2018	(r340863)
+++ head/sys/kern/imgact_elf.c	Fri Nov 23 23:33:55 2018	(r340864)
@@ -88,7 +88,7 @@ __FBSDID("$FreeBSD$");
 
 static int __elfN(check_header)(const Elf_Ehdr *hdr);
 static Elf_Brandinfo *__elfN(get_brandinfo)(struct image_params *imgp,
-    const char *interp, int interp_name_len, int32_t *osrel);
+    const char *interp, int interp_name_len, int32_t *osrel, uint32_t *fctl0);
 static int __elfN(load_file)(struct proc *p, const char *file, u_long *addr,
     u_long *entry, size_t pagesize);
 static int __elfN(load_section)(struct image_params *imgp, vm_ooffset_t offset,
@@ -99,7 +99,7 @@ static bool __elfN(freebsd_trans_osrel)(const Elf_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);
+    Elf_Brandnote *checknote, int32_t *osrel, uint32_t *fctl0);
 static vm_prot_t __elfN(trans_prot)(Elf_Word);
 static Elf_Word __elfN(untrans_prot)(vm_prot_t);
 
@@ -256,7 +256,7 @@ __elfN(brand_inuse)(Elf_Brandinfo *entry)
 
 static Elf_Brandinfo *
 __elfN(get_brandinfo)(struct image_params *imgp, const char *interp,
-    int interp_name_len, int32_t *osrel)
+    int interp_name_len, int32_t *osrel, uint32_t *fctl0)
 {
 	const Elf_Ehdr *hdr = (const Elf_Ehdr *)imgp->image_header;
 	Elf_Brandinfo *bi, *bi_m;
@@ -280,7 +280,8 @@ __elfN(get_brandinfo)(struct image_params *imgp, const
 			continue;
 		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);
+			ret = __elfN(check_note)(imgp, bi->brand_note, osrel,
+			    fctl0);
 			/* Give brand a chance to veto check_note's guess */
 			if (ret && bi->header_supported)
 				ret = bi->header_supported(imgp);
@@ -789,6 +790,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i
 	vm_prot_t prot;
 	u_long text_size, data_size, total_size, text_addr, data_addr;
 	u_long seg_size, seg_addr, addr, baddr, et_dyn_addr, entry, proghdr;
+	uint32_t fctl0;
 	int32_t osrel;
 	int error, i, n, interp_name_len, have_interp;
 
@@ -824,6 +826,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i
 	n = error = 0;
 	baddr = 0;
 	osrel = 0;
+	fctl0 = 0;
 	text_size = data_size = total_size = text_addr = data_addr = 0;
 	entry = proghdr = 0;
 	interp_name_len = 0;
@@ -889,7 +892,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i
 	}
 
 	brand_info = __elfN(get_brandinfo)(imgp, interp, interp_name_len,
-	    &osrel);
+	    &osrel, &fctl0);
 	if (brand_info == NULL) {
 		uprintf("ELF binary type \"%u\" not known.\n",
 		    hdr->e_ident[EI_OSABI]);
@@ -1092,6 +1095,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *i
 	imgp->interpreted = 0;
 	imgp->reloc_base = addr;
 	imgp->proc->p_osrel = osrel;
+	imgp->proc->p_fctl0 = fctl0;
 	imgp->proc->p_elf_machine = hdr->e_machine;
 	imgp->proc->p_elf_flags = hdr->e_flags;
 
@@ -2428,29 +2432,64 @@ brandnote_cb(const Elf_Note *note, void *arg0, boolean
 	return (TRUE);
 }
 
+static Elf_Note fctl_note = {
+	.n_namesz = sizeof(FREEBSD_ABI_VENDOR),
+	.n_descsz = sizeof(uint32_t),
+	.n_type = NT_FREEBSD_FEATURE_CTL,
+};
+
+struct fctl_cb_arg {
+	uint32_t *fctl0;
+};
+
+static boolean_t
+note_fctl_cb(const Elf_Note *note, void *arg0, boolean_t *res)
+{
+	struct fctl_cb_arg *arg;
+	const Elf32_Word *desc;
+	uintptr_t p;
+
+	arg = arg0;
+	p = (uintptr_t)(note + 1);
+	p += roundup2(note->n_namesz, ELF_NOTE_ROUNDSIZE);
+	desc = (const Elf32_Word *)p;
+	*arg->fctl0 = desc[0];
+	return (TRUE);
+}
+
 /*
- * Try to find the appropriate ABI-note section for checknote,
- * fetch the osreldate for binary from the ELF OSABI-note. Only the
- * first page of the image is searched, the same as for headers.
+ * Try to find the appropriate ABI-note section for checknote, fetch
+ * the osreldate and feature control flags for binary from the ELF
+ * OSABI-note.  Only the first page of the image is searched, the same
+ * as for headers.
  */
 static boolean_t
 __elfN(check_note)(struct image_params *imgp, Elf_Brandnote *brandnote,
-    int32_t *osrel)
+    int32_t *osrel, uint32_t *fctl0)
 {
 	const Elf_Phdr *phdr;
 	const Elf_Ehdr *hdr;
 	struct brandnote_cb_arg b_arg;
-	int i;
+	struct fctl_cb_arg f_arg;
+	int i, j;
 
 	hdr = (const Elf_Ehdr *)imgp->image_header;
 	phdr = (const Elf_Phdr *)(imgp->image_header + hdr->e_phoff);
 	b_arg.brandnote = brandnote;
 	b_arg.osrel = osrel;
+	f_arg.fctl0 = fctl0;
 
 	for (i = 0; i < hdr->e_phnum; i++) {
 		if (phdr[i].p_type == PT_NOTE && __elfN(parse_notes)(imgp,
 		    &brandnote->hdr, brandnote->vendor, &phdr[i], brandnote_cb,
 		    &b_arg)) {
+			for (j = 0; j < hdr->e_phnum; j++) {
+				if (phdr[j].p_type == PT_NOTE &&
+				    __elfN(parse_notes)(imgp, &fctl_note,
+				    FREEBSD_ABI_VENDOR, &phdr[j],
+				    note_fctl_cb, &f_arg))
+					break;
+			}
 			return (TRUE);
 		}
 	}



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201811232333.wANNXtts047712>