Author: kib
Date: Fri Dec  7 14:45:28 2018
New Revision: 341688
URL: https://svnweb.freebsd.org/changeset/base/341688

Log:
  MFC r340864:
  Parse FreeBSD Feature Control note on the ELF image activation.

Modified:
  stable/12/sys/kern/imgact_elf.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/kern/imgact_elf.c
==============================================================================
--- stable/12/sys/kern/imgact_elf.c     Fri Dec  7 14:25:46 2018        
(r341687)
+++ stable/12/sys/kern/imgact_elf.c     Fri Dec  7 14:45:28 2018        
(r341688)
@@ -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);
 
@@ -255,7 +255,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;
@@ -279,7 +279,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);
@@ -788,6 +789,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;
 
@@ -823,6 +825,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;
@@ -888,7 +891,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]);
@@ -1091,6 +1094,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;
 
@@ -2427,29 +2431,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);
                }
        }
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to