mirror of
https://github.com/freebsd/freebsd-src
synced 2024-07-21 10:19:04 +00:00
Support BTI in rtld
Read the elf note to decide when to set the guard page on arm64. Reviewed by: kib Sponsored by: Arm Ltd Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D39452
This commit is contained in:
parent
38cc6c3d95
commit
d8925a5f42
|
@ -29,6 +29,8 @@
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <machine/sysarch.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
@ -52,6 +54,51 @@ void *_rtld_tlsdesc_dynamic(void *);
|
||||||
|
|
||||||
void _exit(int);
|
void _exit(int);
|
||||||
|
|
||||||
|
bool
|
||||||
|
arch_digest_note(struct Struct_Obj_Entry *obj __unused, const Elf_Note *note)
|
||||||
|
{
|
||||||
|
const char *note_name;
|
||||||
|
const uint32_t *note_data;
|
||||||
|
|
||||||
|
note_name = (const char *)(note + 1);
|
||||||
|
/* Only handle GNU notes */
|
||||||
|
if (note->n_namesz != sizeof(ELF_NOTE_GNU) ||
|
||||||
|
strncmp(note_name, ELF_NOTE_GNU, sizeof(ELF_NOTE_GNU)) != 0)
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
/* Only handle GNU property notes */
|
||||||
|
if (note->n_type != NT_GNU_PROPERTY_TYPE_0)
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* note_data[0] - Type
|
||||||
|
* note_data[1] - Length
|
||||||
|
* note_data[2] - Data
|
||||||
|
* note_data[3] - Padding?
|
||||||
|
*/
|
||||||
|
note_data = (const uint32_t *)(note_name + note->n_namesz);
|
||||||
|
|
||||||
|
/* Only handle AArch64 feature notes */
|
||||||
|
if (note_data[0] != GNU_PROPERTY_AARCH64_FEATURE_1_AND)
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
/* We expect at least 4 bytes of data */
|
||||||
|
if (note_data[1] < 4)
|
||||||
|
return (false);
|
||||||
|
|
||||||
|
/* TODO: Only guard if HWCAP2_BTI is set */
|
||||||
|
if ((note_data[2] & GNU_PROPERTY_AARCH64_FEATURE_1_BTI) != 0) {
|
||||||
|
struct arm64_guard_page_args guard;
|
||||||
|
|
||||||
|
guard.addr = (uintptr_t)obj->mapbase;
|
||||||
|
guard.len = obj->mapsize;
|
||||||
|
|
||||||
|
sysarch(ARM64_GUARD_PAGE, &guard);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
init_pltgot(Obj_Entry *obj)
|
init_pltgot(Obj_Entry *obj)
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,6 +45,8 @@ struct Struct_Obj_Entry;
|
||||||
(const Elf_Dyn *)_dynamic_addr; \
|
(const Elf_Dyn *)_dynamic_addr; \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
bool arch_digest_note(struct Struct_Obj_Entry *obj, const Elf_Note *note);
|
||||||
|
|
||||||
Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
|
Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
|
||||||
const struct Struct_Obj_Entry *defobj, const struct Struct_Obj_Entry *obj,
|
const struct Struct_Obj_Entry *defobj, const struct Struct_Obj_Entry *obj,
|
||||||
const Elf_Rel *rel);
|
const Elf_Rel *rel);
|
||||||
|
|
|
@ -39,6 +39,9 @@ struct Struct_Obj_Entry;
|
||||||
Elf_Dyn *rtld_dynamic_addr(void);
|
Elf_Dyn *rtld_dynamic_addr(void);
|
||||||
#define rtld_dynamic(obj) rtld_dynamic_addr()
|
#define rtld_dynamic(obj) rtld_dynamic_addr()
|
||||||
|
|
||||||
|
/* No architecture specific notes */
|
||||||
|
#define arch_digest_note(obj, note) false
|
||||||
|
|
||||||
Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
|
Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
|
||||||
const struct Struct_Obj_Entry *obj, const struct Struct_Obj_Entry *refobj,
|
const struct Struct_Obj_Entry *obj, const struct Struct_Obj_Entry *refobj,
|
||||||
const Elf_Rel *rel);
|
const Elf_Rel *rel);
|
||||||
|
|
|
@ -39,6 +39,9 @@ struct Struct_Obj_Entry;
|
||||||
/* Return the address of the .dynamic section in the dynamic linker. */
|
/* Return the address of the .dynamic section in the dynamic linker. */
|
||||||
#define rtld_dynamic(obj) (&_DYNAMIC)
|
#define rtld_dynamic(obj) (&_DYNAMIC)
|
||||||
|
|
||||||
|
/* No architecture specific notes */
|
||||||
|
#define arch_digest_note(obj, note) false
|
||||||
|
|
||||||
Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
|
Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
|
||||||
const struct Struct_Obj_Entry *defobj, const struct Struct_Obj_Entry *obj,
|
const struct Struct_Obj_Entry *defobj, const struct Struct_Obj_Entry *obj,
|
||||||
const Elf_Rel *rel);
|
const Elf_Rel *rel);
|
||||||
|
|
|
@ -39,6 +39,9 @@ struct Struct_Obj_Entry;
|
||||||
#define rtld_dynamic(obj) \
|
#define rtld_dynamic(obj) \
|
||||||
((const Elf_Dyn *)((obj)->relocbase + (Elf_Addr)&_DYNAMIC))
|
((const Elf_Dyn *)((obj)->relocbase + (Elf_Addr)&_DYNAMIC))
|
||||||
|
|
||||||
|
/* No architecture specific notes */
|
||||||
|
#define arch_digest_note(obj, note) false
|
||||||
|
|
||||||
Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
|
Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
|
||||||
const struct Struct_Obj_Entry *obj, const struct Struct_Obj_Entry *refobj,
|
const struct Struct_Obj_Entry *obj, const struct Struct_Obj_Entry *refobj,
|
||||||
const Elf_Rel *rel);
|
const Elf_Rel *rel);
|
||||||
|
|
|
@ -38,6 +38,9 @@ struct Struct_Obj_Entry;
|
||||||
/* Return the address of the .dynamic section in the dynamic linker. */
|
/* Return the address of the .dynamic section in the dynamic linker. */
|
||||||
#define rtld_dynamic(obj) (&_DYNAMIC)
|
#define rtld_dynamic(obj) (&_DYNAMIC)
|
||||||
|
|
||||||
|
/* No architecture specific notes */
|
||||||
|
#define arch_digest_note(obj, note) false
|
||||||
|
|
||||||
Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
|
Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
|
||||||
const struct Struct_Obj_Entry *defobj, const struct Struct_Obj_Entry *obj,
|
const struct Struct_Obj_Entry *defobj, const struct Struct_Obj_Entry *obj,
|
||||||
const Elf_Rel *rel);
|
const Elf_Rel *rel);
|
||||||
|
|
|
@ -38,6 +38,9 @@ struct Struct_Obj_Entry;
|
||||||
/* Return the address of the .dynamic section in the dynamic linker. */
|
/* Return the address of the .dynamic section in the dynamic linker. */
|
||||||
#define rtld_dynamic(obj) (&_DYNAMIC)
|
#define rtld_dynamic(obj) (&_DYNAMIC)
|
||||||
|
|
||||||
|
/* No architecture specific notes */
|
||||||
|
#define arch_digest_note(obj, note) false
|
||||||
|
|
||||||
Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
|
Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
|
||||||
const struct Struct_Obj_Entry *defobj, const struct Struct_Obj_Entry *obj,
|
const struct Struct_Obj_Entry *defobj, const struct Struct_Obj_Entry *obj,
|
||||||
const Elf_Rel *rel);
|
const Elf_Rel *rel);
|
||||||
|
|
|
@ -52,6 +52,9 @@ uint64_t set_gp(struct Struct_Obj_Entry *obj);
|
||||||
(const Elf_Dyn *)_dynamic_addr; \
|
(const Elf_Dyn *)_dynamic_addr; \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
/* No architecture specific notes */
|
||||||
|
#define arch_digest_note(obj, note) false
|
||||||
|
|
||||||
Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
|
Elf_Addr reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
|
||||||
const struct Struct_Obj_Entry *defobj, const struct Struct_Obj_Entry *obj,
|
const struct Struct_Obj_Entry *defobj, const struct Struct_Obj_Entry *obj,
|
||||||
const Elf_Rel *rel);
|
const Elf_Rel *rel);
|
||||||
|
|
|
@ -1729,6 +1729,9 @@ digest_notes(Obj_Entry *obj, Elf_Addr note_start, Elf_Addr note_end)
|
||||||
note = (const Elf_Note *)((const char *)(note + 1) +
|
note = (const Elf_Note *)((const char *)(note + 1) +
|
||||||
roundup2(note->n_namesz, sizeof(Elf32_Addr)) +
|
roundup2(note->n_namesz, sizeof(Elf32_Addr)) +
|
||||||
roundup2(note->n_descsz, sizeof(Elf32_Addr)))) {
|
roundup2(note->n_descsz, sizeof(Elf32_Addr)))) {
|
||||||
|
if (arch_digest_note(obj, note))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (note->n_namesz != sizeof(NOTE_FREEBSD_VENDOR) ||
|
if (note->n_namesz != sizeof(NOTE_FREEBSD_VENDOR) ||
|
||||||
note->n_descsz != sizeof(int32_t))
|
note->n_descsz != sizeof(int32_t))
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Reference in a new issue