mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-14 10:09:48 +00:00
Parse FreeBSD Feature Control note on the ELF image activation.
Sponsored by: The FreeBSD Foundation MFC after: 2 weeks
This commit is contained in:
parent
92328a3251
commit
cefb93f253
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=340864
@ -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 *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 char *interp,
|
||||
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 *imgp)
|
||||
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 *imgp)
|
||||
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 *imgp)
|
||||
}
|
||||
|
||||
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 *imgp)
|
||||
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_t *res)
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user