1 /* AArch64 BTI functions.
2 Copyright (C) 2020-2023 Free Software Foundation, Inc.
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
14 You should have received a copy of the GNU Lesser General Public
15 License along with the GNU C Library; if not, see
16 <https://www.gnu.org/licenses/>. */
24 /* See elf/dl-load.h. */
26 # define MAP_COPY (MAP_PRIVATE | MAP_DENYWRITE)
29 /* Enable BTI protection for MAP. */
32 _dl_bti_protect (struct link_map
*map
, int fd
)
34 const size_t pagesz
= GLRO(dl_pagesize
);
35 const ElfW(Phdr
) *phdr
;
37 for (phdr
= map
->l_phdr
; phdr
< &map
->l_phdr
[map
->l_phnum
]; ++phdr
)
38 if (phdr
->p_type
== PT_LOAD
&& (phdr
->p_flags
& PF_X
))
40 size_t vstart
= ALIGN_DOWN (phdr
->p_vaddr
, pagesz
);
41 size_t vend
= ALIGN_UP (phdr
->p_vaddr
+ phdr
->p_filesz
, pagesz
);
42 off_t off
= ALIGN_DOWN (phdr
->p_offset
, pagesz
);
43 void *start
= (void *) (vstart
+ map
->l_addr
);
44 size_t len
= vend
- vstart
;
46 unsigned prot
= PROT_EXEC
| PROT_BTI
;
47 if (phdr
->p_flags
& PF_R
)
49 if (phdr
->p_flags
& PF_W
)
53 /* Ignore failures for kernel mapped binaries. */
54 __mprotect (start
, len
, prot
);
56 map
->l_mach
.bti_fail
= __mmap (start
, len
, prot
,
57 MAP_FIXED
|MAP_COPY
|MAP_FILE
,
58 fd
, off
) == MAP_FAILED
;
64 bti_failed (struct link_map
*l
, const char *program
)
67 _dl_fatal_printf ("%s: %s: failed to turn on BTI protection\n",
70 /* Note: the errno value is not available any more. */
71 _dl_signal_error (0, l
->l_name
, "dlopen",
72 N_("failed to turn on BTI protection"));
76 /* Enable BTI for L and its dependencies. */
79 _dl_bti_check (struct link_map
*l
, const char *program
)
81 if (!GLRO(dl_aarch64_cpu_features
).bti
)
84 if (l
->l_mach
.bti_fail
)
85 bti_failed (l
, program
);
87 unsigned int i
= l
->l_searchlist
.r_nlist
;
90 struct link_map
*dep
= l
->l_initfini
[i
];
91 if (dep
->l_mach
.bti_fail
)
92 bti_failed (dep
, program
);