@@ -253,7 +253,8 @@ struct arch_elf_state {
int flags;
};
-#define ARM64_ELF_BTI (1 << 0)
+#define ARM64_ELF_INTERP_BTI (1 << 0)
+#define ARM64_ELF_EXEC_BTI (1 << 1)
#define INIT_ARCH_ELF_STATE { \
.flags = 0, \
@@ -274,9 +275,14 @@ static inline int arch_parse_elf_property(u32 type, const void *data,
if (datasz != sizeof(*p))
return -ENOEXEC;
- if (system_supports_bti() && has_interp == is_interp &&
- (*p & GNU_PROPERTY_AARCH64_FEATURE_1_BTI))
- arch->flags |= ARM64_ELF_BTI;
+ if (system_supports_bti() &&
+ (*p & GNU_PROPERTY_AARCH64_FEATURE_1_BTI)) {
+ if (is_interp) {
+ arch->flags |= ARM64_ELF_INTERP_BTI;
+ } else {
+ arch->flags |= ARM64_ELF_EXEC_BTI;
+ }
+ }
}
return 0;
@@ -744,19 +744,13 @@ asmlinkage void __sched arm64_preempt_schedule_irq(void)
int arch_elf_adjust_prot(int prot, const struct arch_elf_state *state,
bool has_interp, bool is_interp)
{
- /*
- * For dynamically linked executables the interpreter is
- * responsible for setting PROT_BTI on everything except
- * itself.
- */
- if (is_interp != has_interp)
- return prot;
+ if (prot & PROT_EXEC) {
+ if (state->flags & ARM64_ELF_INTERP_BTI && is_interp)
+ prot |= PROT_BTI;
- if (!(state->flags & ARM64_ELF_BTI))
- return prot;
-
- if (prot & PROT_EXEC)
- prot |= PROT_BTI;
+ if (state->flags & ARM64_ELF_EXEC_BTI && !is_interp)
+ prot |= PROT_BTI;
+ }
return prot;
}