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
3f0632c424
commit
ec0b91f01d
@ -88,7 +88,7 @@ __FBSDID("$FreeBSD$");
|
|||||||
|
|
||||||
static int __elfN(check_header)(const Elf_Ehdr *hdr);
|
static int __elfN(check_header)(const Elf_Ehdr *hdr);
|
||||||
static Elf_Brandinfo *__elfN(get_brandinfo)(struct image_params *imgp,
|
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,
|
static int __elfN(load_file)(struct proc *p, const char *file, u_long *addr,
|
||||||
u_long *entry, size_t pagesize);
|
u_long *entry, size_t pagesize);
|
||||||
static int __elfN(load_section)(struct image_params *imgp, vm_ooffset_t offset,
|
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);
|
int32_t *osrel);
|
||||||
static bool kfreebsd_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,
|
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 vm_prot_t __elfN(trans_prot)(Elf_Word);
|
||||||
static Elf_Word __elfN(untrans_prot)(vm_prot_t);
|
static Elf_Word __elfN(untrans_prot)(vm_prot_t);
|
||||||
|
|
||||||
@ -256,7 +256,7 @@ __elfN(brand_inuse)(Elf_Brandinfo *entry)
|
|||||||
|
|
||||||
static Elf_Brandinfo *
|
static Elf_Brandinfo *
|
||||||
__elfN(get_brandinfo)(struct image_params *imgp, const char *interp,
|
__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;
|
const Elf_Ehdr *hdr = (const Elf_Ehdr *)imgp->image_header;
|
||||||
Elf_Brandinfo *bi, *bi_m;
|
Elf_Brandinfo *bi, *bi_m;
|
||||||
@ -280,7 +280,8 @@ __elfN(get_brandinfo)(struct image_params *imgp, const char *interp,
|
|||||||
continue;
|
continue;
|
||||||
if (hdr->e_machine == bi->machine && (bi->flags &
|
if (hdr->e_machine == bi->machine && (bi->flags &
|
||||||
(BI_BRAND_NOTE|BI_BRAND_NOTE_MANDATORY)) != 0) {
|
(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 */
|
/* Give brand a chance to veto check_note's guess */
|
||||||
if (ret && bi->header_supported)
|
if (ret && bi->header_supported)
|
||||||
ret = bi->header_supported(imgp);
|
ret = bi->header_supported(imgp);
|
||||||
@ -789,6 +790,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
|
|||||||
vm_prot_t prot;
|
vm_prot_t prot;
|
||||||
u_long text_size, data_size, total_size, text_addr, data_addr;
|
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;
|
u_long seg_size, seg_addr, addr, baddr, et_dyn_addr, entry, proghdr;
|
||||||
|
uint32_t fctl0;
|
||||||
int32_t osrel;
|
int32_t osrel;
|
||||||
int error, i, n, interp_name_len, have_interp;
|
int error, i, n, interp_name_len, have_interp;
|
||||||
|
|
||||||
@ -824,6 +826,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
|
|||||||
n = error = 0;
|
n = error = 0;
|
||||||
baddr = 0;
|
baddr = 0;
|
||||||
osrel = 0;
|
osrel = 0;
|
||||||
|
fctl0 = 0;
|
||||||
text_size = data_size = total_size = text_addr = data_addr = 0;
|
text_size = data_size = total_size = text_addr = data_addr = 0;
|
||||||
entry = proghdr = 0;
|
entry = proghdr = 0;
|
||||||
interp_name_len = 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,
|
brand_info = __elfN(get_brandinfo)(imgp, interp, interp_name_len,
|
||||||
&osrel);
|
&osrel, &fctl0);
|
||||||
if (brand_info == NULL) {
|
if (brand_info == NULL) {
|
||||||
uprintf("ELF binary type \"%u\" not known.\n",
|
uprintf("ELF binary type \"%u\" not known.\n",
|
||||||
hdr->e_ident[EI_OSABI]);
|
hdr->e_ident[EI_OSABI]);
|
||||||
@ -1092,6 +1095,7 @@ __CONCAT(exec_, __elfN(imgact))(struct image_params *imgp)
|
|||||||
imgp->interpreted = 0;
|
imgp->interpreted = 0;
|
||||||
imgp->reloc_base = addr;
|
imgp->reloc_base = addr;
|
||||||
imgp->proc->p_osrel = osrel;
|
imgp->proc->p_osrel = osrel;
|
||||||
|
imgp->proc->p_fctl0 = fctl0;
|
||||||
imgp->proc->p_elf_machine = hdr->e_machine;
|
imgp->proc->p_elf_machine = hdr->e_machine;
|
||||||
imgp->proc->p_elf_flags = hdr->e_flags;
|
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);
|
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,
|
* Try to find the appropriate ABI-note section for checknote, fetch
|
||||||
* fetch the osreldate for binary from the ELF OSABI-note. Only the
|
* the osreldate and feature control flags for binary from the ELF
|
||||||
* first page of the image is searched, the same as for headers.
|
* OSABI-note. Only the first page of the image is searched, the same
|
||||||
|
* as for headers.
|
||||||
*/
|
*/
|
||||||
static boolean_t
|
static boolean_t
|
||||||
__elfN(check_note)(struct image_params *imgp, Elf_Brandnote *brandnote,
|
__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_Phdr *phdr;
|
||||||
const Elf_Ehdr *hdr;
|
const Elf_Ehdr *hdr;
|
||||||
struct brandnote_cb_arg b_arg;
|
struct brandnote_cb_arg b_arg;
|
||||||
int i;
|
struct fctl_cb_arg f_arg;
|
||||||
|
int i, j;
|
||||||
|
|
||||||
hdr = (const Elf_Ehdr *)imgp->image_header;
|
hdr = (const Elf_Ehdr *)imgp->image_header;
|
||||||
phdr = (const Elf_Phdr *)(imgp->image_header + hdr->e_phoff);
|
phdr = (const Elf_Phdr *)(imgp->image_header + hdr->e_phoff);
|
||||||
b_arg.brandnote = brandnote;
|
b_arg.brandnote = brandnote;
|
||||||
b_arg.osrel = osrel;
|
b_arg.osrel = osrel;
|
||||||
|
f_arg.fctl0 = fctl0;
|
||||||
|
|
||||||
for (i = 0; i < hdr->e_phnum; i++) {
|
for (i = 0; i < hdr->e_phnum; i++) {
|
||||||
if (phdr[i].p_type == PT_NOTE && __elfN(parse_notes)(imgp,
|
if (phdr[i].p_type == PT_NOTE && __elfN(parse_notes)(imgp,
|
||||||
&brandnote->hdr, brandnote->vendor, &phdr[i], brandnote_cb,
|
&brandnote->hdr, brandnote->vendor, &phdr[i], brandnote_cb,
|
||||||
&b_arg)) {
|
&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);
|
return (TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user