[RFC/RFT,V2] CFI: Add support for gcc CFI in aarch64
Commit Message
Based on Sami's patch[1], this patch makes the corresponding kernel
configuration of CFI available when compiling the kernel with the gcc[2].
The code after enabling cfi (with -fsanitize=kcfi,
-fpatchable-function-entry=3,1) is as follows:
int (*p)(void);
int func (int)
{
p();
}
__kcfi_func:
.4byte 0x439d3502
.global func
.text
.LPFE1:
nop
.type func, %function
func:
nop
nop
.LFB0:
......
adrp x0, p
add x0, x0, :lo12:p
ldr x0, [x0]
ldur w16, [x0, #-8]
movk w17, #23592
movk w17, #17921, lsl #16
cmp w16, w17
b.eq .Lkcfi2
brk #0x8220
.Lkcfi2:
blr x0
......
In the compiler part[4], most of the content is the same as Sami's
implementation[3], except for some minor differences, mainly including:
1. The function typeid is calculated differently and it is difficult
to be consistent.
2. A reserved typeid (such as 0x0U on the aarch64 platform) is always
inserted in front of functions that should not be called indirectly.
Functions that can be called indirectly will not use this hash value,
which prevents instructions/data before the function from being used
as a typeid by an attacker.
3. Some bits are ignored in the typeid to avoid conflicts between the
typeid and the instruction set of a specific platform, thereby preventing
an attacker from bypassing the CFI check by using the instruction as a
typeid, such as on the aarch64 platform:
* If the following instruction sequence exists:
400620: a9be7bfd stp x29, x30, [sp, #-32]!
400624: 910003fd mov x29, sp
400628: f9000bf3 str x19, [sp, #16]
* If the expected typeid of the indirect call is exactly 0x910003fd,
the attacker can jump to the next instruction position of any
"mov x29,sp" instruction (such as 0x400628 here).
4. Insert a symbol __kcfi_<function> before each function's typeid,
which may be helpful for fine-grained KASLR implementations.
I'm not sure if these distinctions need to be removed, they're kept
in this version for now, and I'm happy to remove them in the next
version if necessary (except for the first one).
The current implementation of gcc only supports the aarch64 platform,
the x86 version is still in progress.
This produces the following oops on CFI failure (generated using lkdtm):
/ # echo CFI_FORWARD_PROTO > /sys/kernel/debug/provoke-crash/DIRECT
[ 17.153364] lkdtm: Performing direct entry CFI_FORWARD_PROTO
[ 17.153675] lkdtm: Calling matched prototype ...
[ 17.154188] lkdtm: Calling mismatched prototype ...
[ 17.154553] CFI failure at lkdtm_indirect_call+0x38/0x54 (target: lkdtm_increment_int+0x0/0x2c; expected type: 0xc59c68f1)
[ 17.155627] Internal error: Oops - CFI: 0000000000000000 [#1] PREEMPT SMP
[ 17.156025] Modules linked in:
[ 17.156580] CPU: 1 PID: 110 Comm: sh Not tainted 6.1.0-00001-g7ead10685f57-dirty #2
[ 17.156975] Hardware name: linux,dummy-virt (DT)
[ 17.157290] pstate: 80400005 (Nzcv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[ 17.157621] pc : lkdtm_indirect_call+0x38/0x54
[ 17.157902] lr : lkdtm_CFI_FORWARD_PROTO+0x48/0x7c
[ 17.158142] sp : ffff80000b083c80
[ 17.158316] x29: ffff80000b083c80 x28: ffff0000068ccc40 x27: 0000000000000000
[ 17.158820] x26: 0000000000000000 x25: 0000000000000000 x24: 000000000bd069a0
[ 17.159239] x23: ffff0000053493c0 x22: ffff80000b083df0 x21: 0000000000000012
[ 17.159673] x20: ffff80000aa29150 x19: ffff000006909000 x18: ffff80000b035068
[ 17.160110] x17: 00000000c59c68f1 x16: 00000000a2d40772 x15: 0000000000000006
[ 17.160530] x14: 0000000000000000 x13: 2e2e2e2065707974 x12: 6f746f7270206465
[ 17.160947] x11: 686374616d73696d x10: ffff80000a7254b8 x9 : ffff800009268330
[ 17.161376] x8 : 00000000ffffefff x7 : ffff80000a7254b8 x6 : 80000000fffff000
[ 17.161789] x5 : 000000000000bff4 x4 : 0000000000000000 x3 : 0000000000000000
[ 17.162264] x2 : 0000000000000000 x1 : ffff800008a4e248 x0 : ffff80000abca500
[ 17.162865] Call trace:
[ 17.163099] lkdtm_indirect_call+0x38/0x54
[ 17.163411] lkdtm_CFI_FORWARD_PROTO+0x48/0x7c
[ 17.163663] lkdtm_do_action+0x48/0x5c
[ 17.163876] direct_entry+0x144/0x160
[ 17.164084] full_proxy_write+0x84/0xe4
[ 17.164298] vfs_write+0xe8/0x32c
The gcc-related patches[4] are based on tag: releases/gcc-12.2.0.
This patch is based on tag: v6.2.
Sorry for the long delay, the next version should not be that slow.
Any suggestion please let me know :).
Thanks,
Dan.
[1] https://lore.kernel.org/all/20220908215504.3686827-1-samitolvanen@google.com/
[2] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=107048
[3] https://reviews.llvm.org/D119296
[4] https://lore.kernel.org/all/20230325081117.93245-1-ashimida.1990@gmail.com/
Signed-off-by: Dan Li <ashimida.1990@gmail.com>
---
RFC/RFT V2:
- The CFI typeid check is changed from the form of calling the callback
function to the calling of the brk instruction.
- Add support for -fpatchable-function-entry=M,N
---
Makefile | 2 +-
arch/Kconfig | 21 +++++++++++----------
arch/arm64/Kconfig | 2 +-
arch/arm64/kernel/traps.c | 8 ++++----
arch/x86/Kconfig | 12 ++++++------
arch/x86/include/asm/cfi.h | 4 ++--
arch/x86/kernel/Makefile | 2 +-
arch/x86/purgatory/Makefile | 2 +-
drivers/misc/lkdtm/cfi.c | 2 +-
include/asm-generic/vmlinux.lds.h | 2 +-
include/linux/cfi.h | 4 ++--
include/linux/cfi_types.h | 6 +++---
include/linux/compiler-gcc.h | 4 ++++
kernel/Makefile | 2 +-
kernel/module/Kconfig | 2 +-
scripts/kallsyms.c | 3 ++-
tools/perf/util/include/linux/linkage.h | 2 +-
17 files changed, 43 insertions(+), 37 deletions(-)
Comments
On Sat, Mar 25, 2023 at 01:54:16AM -0700, Dan Li wrote:
> In the compiler part[4], most of the content is the same as Sami's
> implementation[3], except for some minor differences, mainly including:
>
> 1. The function typeid is calculated differently and it is difficult
> to be consistent.
This means there is an effective ABI break between the compilers, which
is sad :-( Is there really nothing to be done about this?
On Mon, Mar 27, 2023 at 2:30 AM Peter Zijlstra <peterz@infradead.org> wrote:
>
> On Sat, Mar 25, 2023 at 01:54:16AM -0700, Dan Li wrote:
>
> > In the compiler part[4], most of the content is the same as Sami's
> > implementation[3], except for some minor differences, mainly including:
> >
> > 1. The function typeid is calculated differently and it is difficult
> > to be consistent.
>
> This means there is an effective ABI break between the compilers, which
> is sad :-( Is there really nothing to be done about this?
I agree, this would be unfortunate, and would also be a compatibility
issue with rustc where there's ongoing work to support
clang-compatible CFI type hashes:
https://github.com/rust-lang/rust/pull/105452
Sami
On 03/27, Peter Zijlstra wrote:
> On Sat, Mar 25, 2023 at 01:54:16AM -0700, Dan Li wrote:
>
> > In the compiler part[4], most of the content is the same as Sami's
> > implementation[3], except for some minor differences, mainly including:
> >
> > 1. The function typeid is calculated differently and it is difficult
> > to be consistent.
>
> This means there is an effective ABI break between the compilers, which
> is sad :-( Is there really nothing to be done about this?
Hi Peter,
I'm not so sure right now. According to Sami's tip, I need to learn more about
related patches. I'll make it ABI compatible in the next version if possible :)
Thanks,
Dan
On 03/27, Sami Tolvanen wrote:
> On Mon, Mar 27, 2023 at 2:30 AM Peter Zijlstra <peterz@infradead.org> wrote:
> >
> > On Sat, Mar 25, 2023 at 01:54:16AM -0700, Dan Li wrote:
> >
> > > In the compiler part[4], most of the content is the same as Sami's
> > > implementation[3], except for some minor differences, mainly including:
> > >
> > > 1. The function typeid is calculated differently and it is difficult
> > > to be consistent.
> >
> > This means there is an effective ABI break between the compilers, which
> > is sad :-( Is there really nothing to be done about this?
>
> I agree, this would be unfortunate, and would also be a compatibility
> issue with rustc where there's ongoing work to support
> clang-compatible CFI type hashes:
>
> https://github.com/rust-lang/rust/pull/105452
>
> Sami
Hi Sami,
Thanks for the info, I need to learn about it :)
Is there anything else that needs to be improved?
Thanks,
Dan
+ Likun
On Tue, 28 Mar 2023 at 06:18, Sami Tolvanen <samitolvanen@google.com> wrote:
>
> On Mon, Mar 27, 2023 at 2:30 AM Peter Zijlstra <peterz@infradead.org> wrote:
> >
> > On Sat, Mar 25, 2023 at 01:54:16AM -0700, Dan Li wrote:
> >
> > > In the compiler part[4], most of the content is the same as Sami's
> > > implementation[3], except for some minor differences, mainly including:
> > >
> > > 1. The function typeid is calculated differently and it is difficult
> > > to be consistent.
> >
> > This means there is an effective ABI break between the compilers, which
> > is sad :-( Is there really nothing to be done about this?
>
> I agree, this would be unfortunate, and would also be a compatibility
> issue with rustc where there's ongoing work to support
> clang-compatible CFI type hashes:
>
> https://github.com/rust-lang/rust/pull/105452
>
> Sami
On 2023/12/13 16:48, Dan Li wrote:
> + Likun
>
> On Tue, 28 Mar 2023 at 06:18, Sami Tolvanen <samitolvanen@google.com> wrote:
>> On Mon, Mar 27, 2023 at 2:30 AM Peter Zijlstra <peterz@infradead.org> wrote:
>>> On Sat, Mar 25, 2023 at 01:54:16AM -0700, Dan Li wrote:
>>>
>>>> In the compiler part[4], most of the content is the same as Sami's
>>>> implementation[3], except for some minor differences, mainly including:
>>>>
>>>> 1. The function typeid is calculated differently and it is difficult
>>>> to be consistent.
>>> This means there is an effective ABI break between the compilers, which
>>> is sad :-( Is there really nothing to be done about this?
>> I agree, this would be unfortunate, and would also be a compatibility
>> issue with rustc where there's ongoing work to support
>> clang-compatible CFI type hashes:
>>
>> https://github.com/rust-lang/rust/pull/105452
>>
>> Sami
Hi Peter and Sami
I am Dan Li's colleague, and I will take over and continue the work of CFI.
Regarding the issue of gcc cfi type id being compatible with clang, we
have analyzed and verified:
1. clang uses Mangling defined in Itanium C++ ABI to encode the function
prototype, and uses the encoding result as input to generate cfi type id;
2. Currently, gcc only implements mangling for the C++ compiler, and the
function prototype coding generated by these interfaces is compatible
with clang, but gcc's c compiler does not support mangling.;
Adding mangling to gcc's c compiler is a huge and difficult task,because
we have to refactor the mangling of C++, splitting it into basic
mangling and language specific mangling, and adding support for the c
language which requires a deep understanding of the compiler and
language processing parts.
And for the kernel cfi, I suggest separating type compatibility from CFI
basic functions. Type compatibility is independent from CFI basic
funcitons and should be dealt with under another topic. Should we focus
on the main issus of cfi, and let it work first on linux kernel, and
left the compatible issue to be solved later?
LiKun Wang
声明:这封邮件只允许文件接收者阅读,有很高的机密性要求。禁止其他人使用、打开、复制或转发里面的任何内容。如果本邮件错误地发给了你,请联系邮件发出者并删除这个文件。机密及法律的特权并不因为误发邮件而放弃或丧失。任何提出的观点或意见只属于作者的个人见解,并不一定代表本公司。
On Wed, Dec 13, 2023 at 05:01:07PM +0800, Wang wrote:
> On 2023/12/13 16:48, Dan Li wrote:
> > + Likun
> >
> > On Tue, 28 Mar 2023 at 06:18, Sami Tolvanen wrote:
> >> On Mon, Mar 27, 2023 at 2:30 AM Peter Zijlstra wrote:
> >>> On Sat, Mar 25, 2023 at 01:54:16AM -0700, Dan Li wrote:
> >>>
> >>>> In the compiler part[4], most of the content is the same as Sami's
> >>>> implementation[3], except for some minor differences, mainly including:
> >>>>
> >>>> 1. The function typeid is calculated differently and it is difficult
> >>>> to be consistent.
> >>> This means there is an effective ABI break between the compilers, which
> >>> is sad :-( Is there really nothing to be done about this?
> >> I agree, this would be unfortunate, and would also be a compatibility
> >> issue with rustc where there's ongoing work to support
> >> clang-compatible CFI type hashes:
> >>
> >> https://github.com/rust-lang/rust/pull/105452
> >>
> >> Sami
>
> Hi Peter and Sami
>
> I am Dan Li's colleague, and I will take over and continue the work of CFI.
>
> Regarding the issue of gcc cfi type id being compatible with clang, we
> have analyzed and verified:
>
> 1. clang uses Mangling defined in Itanium C++ ABI to encode the function
> prototype, and uses the encoding result as input to generate cfi type id;
> 2. Currently, gcc only implements mangling for the C++ compiler, and the
> function prototype coding generated by these interfaces is compatible
> with clang, but gcc's c compiler does not support mangling.;
>
> Adding mangling to gcc's c compiler is a huge and difficult task,because
> we have to refactor the mangling of C++, splitting it into basic
> mangling and language specific mangling, and adding support for the c
> language which requires a deep understanding of the compiler and
> language processing parts.
>
> And for the kernel cfi, I suggest separating type compatibility from CFI
> basic functions. Type compatibility is independent from CFI basic
> funcitons and should be dealt with under another topic. Should we focus
> on the main issus of cfi, and let it work first on linux kernel, and
> left the compatible issue to be solved later?
I'm not sure what you're suggesting here exactly, do you mean to add a type ID
scheme that's incompatible with clang, leaving everything else the same? If so,
what sort of scheme are you proposing?
It seems unfortunate to have a different scheme, but IIUC we expect all kernel
objects to be built with the same compiler.
Mark.
On Wed, Dec 13, 2023 at 05:01:07PM +0800, Wang wrote:
> On 2023/12/13 16:48, Dan Li wrote:
> > + Likun
> >
> > On Tue, 28 Mar 2023 at 06:18, Sami Tolvanen <samitolvanen@google.com> wrote:
> >> On Mon, Mar 27, 2023 at 2:30 AM Peter Zijlstra <peterz@infradead.org> wrote:
> >>> On Sat, Mar 25, 2023 at 01:54:16AM -0700, Dan Li wrote:
> >>>
> >>>> In the compiler part[4], most of the content is the same as Sami's
> >>>> implementation[3], except for some minor differences, mainly including:
> >>>>
> >>>> 1. The function typeid is calculated differently and it is difficult
> >>>> to be consistent.
> >>> This means there is an effective ABI break between the compilers, which
> >>> is sad :-( Is there really nothing to be done about this?
> >> I agree, this would be unfortunate, and would also be a compatibility
> >> issue with rustc where there's ongoing work to support
> >> clang-compatible CFI type hashes:
> >>
> >> https://github.com/rust-lang/rust/pull/105452
> >>
> >> Sami
>
>
> Hi Peter and Sami
>
> I am Dan Li's colleague, and I will take over and continue the work of CFI.
Welcome; this is great news! :) Thanks for picking up the work.
>
> Regarding the issue of gcc cfi type id being compatible with clang, we
> have analyzed and verified:
>
> 1. clang uses Mangling defined in Itanium C++ ABI to encode the function
> prototype, and uses the encoding result as input to generate cfi type id;
> 2. Currently, gcc only implements mangling for the C++ compiler, and the
> function prototype coding generated by these interfaces is compatible
> with clang, but gcc's c compiler does not support mangling.;
>
> Adding mangling to gcc's c compiler is a huge and difficult task,because
> we have to refactor the mangling of C++, splitting it into basic
> mangling and language specific mangling, and adding support for the c
> language which requires a deep understanding of the compiler and
> language processing parts.
>
> And for the kernel cfi, I suggest separating type compatibility from CFI
> basic functions. Type compatibility is independent from CFI basic
> funcitons and should be dealt with under another topic. Should we focus
> on the main issus of cfi, and let it work first on linux kernel, and
> left the compatible issue to be solved later?
If you mean keeping the hashes identical between Clang/LLVM and GCC,
I think this is going to be a requirement due to adding Rust to the
build environment (which uses the LLVM mangling and hashing).
FWIW, I think the subset of type mangling needed isn't the entirely C++
language spec, so it shouldn't be hard to add this to GCC.
-Kees
On 2023/12/13 22:45, Mark Rutland wrote:
> On Wed, Dec 13, 2023 at 05:01:07PM +0800, Wang wrote:
>> On 2023/12/13 16:48, Dan Li wrote:
>>> + Likun
>>>
>>> On Tue, 28 Mar 2023 at 06:18, Sami Tolvanen wrote:
>>>> On Mon, Mar 27, 2023 at 2:30 AM Peter Zijlstra wrote:
>>>>> On Sat, Mar 25, 2023 at 01:54:16AM -0700, Dan Li wrote:
>>>>>
>>>>>> In the compiler part[4], most of the content is the same as Sami's
>>>>>> implementation[3], except for some minor differences, mainly including:
>>>>>>
>>>>>> 1. The function typeid is calculated differently and it is difficult
>>>>>> to be consistent.
>>>>> This means there is an effective ABI break between the compilers, which
>>>>> is sad :-( Is there really nothing to be done about this?
>>>> I agree, this would be unfortunate, and would also be a compatibility
>>>> issue with rustc where there's ongoing work to support
>>>> clang-compatible CFI type hashes:
>>>>
>>>> https://github.com/rust-lang/rust/pull/105452
>>>>
>>>> Sami
>>
>> Hi Peter and Sami
>>
>> I am Dan Li's colleague, and I will take over and continue the work of CFI.
>>
>> Regarding the issue of gcc cfi type id being compatible with clang, we
>> have analyzed and verified:
>>
>> 1. clang uses Mangling defined in Itanium C++ ABI to encode the function
>> prototype, and uses the encoding result as input to generate cfi type id;
>> 2. Currently, gcc only implements mangling for the C++ compiler, and the
>> function prototype coding generated by these interfaces is compatible
>> with clang, but gcc's c compiler does not support mangling.;
>>
>> Adding mangling to gcc's c compiler is a huge and difficult task,because
>> we have to refactor the mangling of C++, splitting it into basic
>> mangling and language specific mangling, and adding support for the c
>> language which requires a deep understanding of the compiler and
>> language processing parts.
>>
>> And for the kernel cfi, I suggest separating type compatibility from CFI
>> basic functions. Type compatibility is independent from CFI basic
>> funcitons and should be dealt with under another topic. Should we focus
>> on the main issus of cfi, and let it work first on linux kernel, and
>> left the compatible issue to be solved later?
>
> I'm not sure what you're suggesting here exactly, do you mean to add a type ID
> scheme that's incompatible with clang, leaving everything else the same? If so,
> what sort of scheme are you proposing?
>
> It seems unfortunate to have a different scheme, but IIUC we expect all kernel
> objects to be built with the same compiler.
>
> Mark.
Thanks Mark, I will consider a scheme that is compatible with clang.
Likun Wang.
声明:这封邮件只允许文件接收者阅读,有很高的机密性要求。禁止其他人使用、打开、复制或转发里面的任何内容。如果本邮件错误地发给了你,请联系邮件发出者并删除这个文件。机密及法律的特权并不因为误发邮件而放弃或丧失。任何提出的观点或意见只属于作者的个人见解,并不一定代表本公司。
On 2023/12/14 03:35, Kees Cook wrote:
> On Wed, Dec 13, 2023 at 05:01:07PM +0800, Wang wrote:
>> On 2023/12/13 16:48, Dan Li wrote:
>>> + Likun
>>>
>>> On Tue, 28 Mar 2023 at 06:18, Sami Tolvanen <samitolvanen@google.com> wrote:
>>>> On Mon, Mar 27, 2023 at 2:30 AM Peter Zijlstra <peterz@infradead.org> wrote:
>>>>> On Sat, Mar 25, 2023 at 01:54:16AM -0700, Dan Li wrote:
>>>>>
>>>>>> In the compiler part[4], most of the content is the same as Sami's
>>>>>> implementation[3], except for some minor differences, mainly including:
>>>>>>
>>>>>> 1. The function typeid is calculated differently and it is difficult
>>>>>> to be consistent.
>>>>> This means there is an effective ABI break between the compilers, which
>>>>> is sad :-( Is there really nothing to be done about this?
>>>> I agree, this would be unfortunate, and would also be a compatibility
>>>> issue with rustc where there's ongoing work to support
>>>> clang-compatible CFI type hashes:
>>>>
>>>> https://github.com/rust-lang/rust/pull/105452
>>>>
>>>> Sami
>>
>>
>> Hi Peter and Sami
>>
>> I am Dan Li's colleague, and I will take over and continue the work of CFI.
>
> Welcome; this is great news! :) Thanks for picking up the work.
>
>>
>> Regarding the issue of gcc cfi type id being compatible with clang, we
>> have analyzed and verified:
>>
>> 1. clang uses Mangling defined in Itanium C++ ABI to encode the function
>> prototype, and uses the encoding result as input to generate cfi type id;
>> 2. Currently, gcc only implements mangling for the C++ compiler, and the
>> function prototype coding generated by these interfaces is compatible
>> with clang, but gcc's c compiler does not support mangling.;
>>
>> Adding mangling to gcc's c compiler is a huge and difficult task,because
>> we have to refactor the mangling of C++, splitting it into basic
>> mangling and language specific mangling, and adding support for the c
>> language which requires a deep understanding of the compiler and
>> language processing parts.
>>
>> And for the kernel cfi, I suggest separating type compatibility from CFI
>> basic functions. Type compatibility is independent from CFI basic
>> funcitons and should be dealt with under another topic. Should we focus
>> on the main issus of cfi, and let it work first on linux kernel, and
>> left the compatible issue to be solved later?
>
> If you mean keeping the hashes identical between Clang/LLVM and GCC,
> I think this is going to be a requirement due to adding Rust to the
> build environment (which uses the LLVM mangling and hashing).
>
> FWIW, I think the subset of type mangling needed isn't the entirely C++
> language spec, so it shouldn't be hard to add this to GCC.
>
> -Kees
>
Thanks Kees, I will first try to implement a simple interface based on
mangle to generate cfi type id.
Likun Wang
声明:这封邮件只允许文件接收者阅读,有很高的机密性要求。禁止其他人使用、打开、复制或转发里面的任何内容。如果本邮件错误地发给了你,请联系邮件发出者并删除这个文件。机密及法律的特权并不因为误发邮件而放弃或丧失。任何提出的观点或意见只属于作者的个人见解,并不一定代表本公司。
@@ -1014,7 +1014,7 @@ KBUILD_AFLAGS += -fno-lto
export CC_FLAGS_LTO
endif
-ifdef CONFIG_CFI_CLANG
+ifdef CONFIG_CFI
CC_FLAGS_CFI := -fsanitize=kcfi
KBUILD_CFLAGS += $(CC_FLAGS_CFI)
export CC_FLAGS_CFI
@@ -748,33 +748,34 @@ config LTO_CLANG_THIN
If unsure, say Y.
endchoice
-config ARCH_SUPPORTS_CFI_CLANG
+config ARCH_SUPPORTS_CFI
bool
help
- An architecture should select this option if it can support Clang's
- Control-Flow Integrity (CFI) checking.
+ An architecture should select this option if it can support the
+ compiler's Control-Flow Integrity (CFI) checking.
config ARCH_USES_CFI_TRAPS
bool
-config CFI_CLANG
- bool "Use Clang's Control Flow Integrity (CFI)"
- depends on ARCH_SUPPORTS_CFI_CLANG
+config CFI
+ bool "Use Control Flow Integrity (CFI)"
+ depends on ARCH_SUPPORTS_CFI
depends on $(cc-option,-fsanitize=kcfi)
help
- This option enables Clang’s forward-edge Control Flow Integrity
+ This option enables the compiler’s forward-edge Control Flow Integrity
(CFI) checking, where the compiler injects a runtime check to each
indirect function call to ensure the target is a valid function with
the correct static type. This restricts possible call targets and
makes it more difficult for an attacker to exploit bugs that allow
the modification of stored function pointers. More information can be
- found from Clang's documentation:
+ found from the compiler's documentation:
- https://clang.llvm.org/docs/ControlFlowIntegrity.html
+ - Clang: https://clang.llvm.org/docs/ControlFlowIntegrity.html
+ - GCC: https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html#Instrumentation-Options
config CFI_PERMISSIVE
bool "Use CFI in permissive mode"
- depends on CFI_CLANG
+ depends on CFI
help
When selected, Control Flow Integrity (CFI) violations result in a
warning instead of a kernel panic. This option should only be used
@@ -90,7 +90,7 @@ config ARM64
select ARCH_SUPPORTS_SHADOW_CALL_STACK if CC_HAVE_SHADOW_CALL_STACK
select ARCH_SUPPORTS_LTO_CLANG if CPU_LITTLE_ENDIAN
select ARCH_SUPPORTS_LTO_CLANG_THIN
- select ARCH_SUPPORTS_CFI_CLANG
+ select ARCH_SUPPORTS_CFI
select ARCH_SUPPORTS_ATOMIC_RMW
select ARCH_SUPPORTS_INT128 if CC_HAS_INT128
select ARCH_SUPPORTS_NUMA_BALANCING
@@ -981,7 +981,7 @@ static struct break_hook bug_break_hook = {
.imm = BUG_BRK_IMM,
};
-#ifdef CONFIG_CFI_CLANG
+#ifdef CONFIG_CFI
static int cfi_handler(struct pt_regs *regs, unsigned long esr)
{
unsigned long target;
@@ -1011,7 +1011,7 @@ static struct break_hook cfi_break_hook = {
.imm = CFI_BRK_IMM_BASE,
.mask = CFI_BRK_IMM_MASK,
};
-#endif /* CONFIG_CFI_CLANG */
+#endif /* CONFIG_CFI*/
static int reserved_fault_handler(struct pt_regs *regs, unsigned long esr)
{
@@ -1084,7 +1084,7 @@ static struct break_hook kasan_break_hook = {
int __init early_brk64(unsigned long addr, unsigned long esr,
struct pt_regs *regs)
{
-#ifdef CONFIG_CFI_CLANG
+#ifdef CONFIG_CFI
if ((esr_comment(esr) & ~CFI_BRK_IMM_MASK) == CFI_BRK_IMM_BASE)
return cfi_handler(regs, esr) != DBG_HOOK_HANDLED;
#endif
@@ -1098,7 +1098,7 @@ int __init early_brk64(unsigned long addr, unsigned long esr,
void __init trap_init(void)
{
register_kernel_break_hook(&bug_break_hook);
-#ifdef CONFIG_CFI_CLANG
+#ifdef CONFIG_CFI
register_kernel_break_hook(&cfi_break_hook);
#endif
register_kernel_break_hook(&fault_break_hook);
@@ -110,8 +110,8 @@ config X86
select ARCH_SUPPORTS_PAGE_TABLE_CHECK if X86_64
select ARCH_SUPPORTS_NUMA_BALANCING if X86_64
select ARCH_SUPPORTS_KMAP_LOCAL_FORCE_MAP if NR_CPUS <= 4096
- select ARCH_SUPPORTS_CFI_CLANG if X86_64
- select ARCH_USES_CFI_TRAPS if X86_64 && CFI_CLANG
+ select ARCH_SUPPORTS_CFI if X86_64
+ select ARCH_USES_CFI_TRAPS if X86_64 && CFI
select ARCH_SUPPORTS_LTO_CLANG
select ARCH_SUPPORTS_LTO_CLANG_THIN
select ARCH_USE_BUILTIN_BSWAP
@@ -2501,11 +2501,11 @@ config FUNCTION_PADDING_CFI
default 3 if FUNCTION_ALIGNMENT_8B
default 0
-# Basically: FUNCTION_ALIGNMENT - 5*CFI_CLANG
+# Basically: FUNCTION_ALIGNMENT - 5*CFI
# except Kconfig can't do arithmetic :/
config FUNCTION_PADDING_BYTES
int
- default FUNCTION_PADDING_CFI if CFI_CLANG
+ default FUNCTION_PADDING_CFI if CFI
default FUNCTION_ALIGNMENT
config CALL_PADDING
@@ -2515,7 +2515,7 @@ config CALL_PADDING
config FINEIBT
def_bool y
- depends on X86_KERNEL_IBT && CFI_CLANG && RETPOLINE
+ depends on X86_KERNEL_IBT && CFI && RETPOLINE
select CALL_PADDING
config HAVE_CALL_THUNKS
@@ -2528,7 +2528,7 @@ config CALL_THUNKS
config PREFIX_SYMBOLS
def_bool y
- depends on CALL_PADDING && !CFI_CLANG
+ depends on CALL_PADDING && !CFI
menuconfig SPECULATION_MITIGATIONS
bool "Mitigations for speculative execution vulnerabilities"
@@ -10,13 +10,13 @@
#include <linux/cfi.h>
-#ifdef CONFIG_CFI_CLANG
+#ifdef CONFIG_CFI
enum bug_trap_type handle_cfi_failure(struct pt_regs *regs);
#else
static inline enum bug_trap_type handle_cfi_failure(struct pt_regs *regs)
{
return BUG_TRAP_TYPE_NONE;
}
-#endif /* CONFIG_CFI_CLANG */
+#endif /* CONFIG_CFI */
#endif /* _ASM_X86_CFI_H */
@@ -141,7 +141,7 @@ obj-$(CONFIG_UNWINDER_GUESS) += unwind_guess.o
obj-$(CONFIG_AMD_MEM_ENCRYPT) += sev.o
-obj-$(CONFIG_CFI_CLANG) += cfi.o
+obj-$(CONFIG_CFI) += cfi.o
obj-$(CONFIG_CALL_THUNKS) += callthunks.o
@@ -56,7 +56,7 @@ ifdef CONFIG_RETPOLINE
PURGATORY_CFLAGS_REMOVE += $(RETPOLINE_CFLAGS)
endif
-ifdef CONFIG_CFI_CLANG
+ifdef CONFIG_CFI
PURGATORY_CFLAGS_REMOVE += $(CC_FLAGS_CFI)
endif
@@ -43,7 +43,7 @@ static void lkdtm_CFI_FORWARD_PROTO(void)
lkdtm_indirect_call((void *)lkdtm_increment_int);
pr_err("FAIL: survived mismatched prototype function call!\n");
- pr_expected_config(CONFIG_CFI_CLANG);
+ pr_expected_config(CONFIG_CFI);
}
/*
@@ -162,7 +162,7 @@
#define PATCHABLE_DISCARDS *(__patchable_function_entries)
#endif
-#ifndef CONFIG_ARCH_SUPPORTS_CFI_CLANG
+#ifndef CONFIG_ARCH_SUPPORTS_CFI
/*
* Simply points to ftrace_stub, but with the proper protocol.
* Defined by the linker script in linux/vmlinux.lds.h
@@ -10,7 +10,7 @@
#include <linux/bug.h>
#include <linux/module.h>
-#ifdef CONFIG_CFI_CLANG
+#ifdef CONFIG_CFI
enum bug_trap_type report_cfi_failure(struct pt_regs *regs, unsigned long addr,
unsigned long *target, u32 type);
@@ -23,7 +23,7 @@ static inline enum bug_trap_type report_cfi_failure_noaddr(struct pt_regs *regs,
#ifdef CONFIG_ARCH_USES_CFI_TRAPS
bool is_cfi_trap(unsigned long addr);
#endif
-#endif /* CONFIG_CFI_CLANG */
+#endif /* CONFIG_CFI */
#ifdef CONFIG_MODULES
#ifdef CONFIG_ARCH_USES_CFI_TRAPS
@@ -8,7 +8,7 @@
#ifdef __ASSEMBLY__
#include <linux/linkage.h>
-#ifdef CONFIG_CFI_CLANG
+#ifdef CONFIG_CFI
/*
* Use the __kcfi_typeid_<function> type identifier symbol to
* annotate indirectly called assembly functions. The compiler emits
@@ -29,12 +29,12 @@
#define SYM_TYPED_START(name, linkage, align...) \
SYM_TYPED_ENTRY(name, linkage, align)
-#else /* CONFIG_CFI_CLANG */
+#else /* CONFIG_CFI */
#define SYM_TYPED_START(name, linkage, align...) \
SYM_START(name, linkage, align)
-#endif /* CONFIG_CFI_CLANG */
+#endif /* CONFIG_CFI */
#ifndef SYM_TYPED_FUNC_START
#define SYM_TYPED_FUNC_START(name) \
@@ -82,6 +82,10 @@
#define __noscs __attribute__((__no_sanitize__("shadow-call-stack")))
#endif
+#ifdef CONFIG_CFI
+#define __nocfi __attribute__((no_sanitize("kcfi")))
+#endif
+
#define __no_sanitize_address __attribute__((__no_sanitize_address__))
#if defined(__SANITIZE_THREAD__)
@@ -112,7 +112,7 @@ obj-$(CONFIG_KCSAN) += kcsan/
obj-$(CONFIG_SHADOW_CALL_STACK) += scs.o
obj-$(CONFIG_HAVE_STATIC_CALL) += static_call.o
obj-$(CONFIG_HAVE_STATIC_CALL_INLINE) += static_call_inline.o
-obj-$(CONFIG_CFI_CLANG) += cfi.o
+obj-$(CONFIG_CFI) += cfi.o
obj-$(CONFIG_PERF_EVENTS) += events/
@@ -289,6 +289,6 @@ config UNUSED_KSYMS_WHITELIST
config MODULES_TREE_LOOKUP
def_bool y
- depends on PERF_EVENTS || TRACING || CFI_CLANG
+ depends on PERF_EVENTS || TRACING || CFI
endif # MODULES
@@ -136,7 +136,8 @@ static bool is_ignored_symbol(const char *name, char type)
"__ThumbV7PILongThunk_",
"__LA25Thunk_", /* mips lld */
"__microLA25Thunk_",
- "__kcfi_typeid_", /* CFI type identifiers */
+ "__kcfi_", /* CFI type identifiers */
+ "__pi___kcfi", /* CFI type identifiers */
NULL
};
@@ -116,7 +116,7 @@
#endif
// In the kernel sources (include/linux/cfi_types.h), this has a different
-// definition when CONFIG_CFI_CLANG is used, for tools/ just use the !clang
+// definition when CONFIG_CFI is used, for tools/ just use the !clang
// definition:
#ifndef SYM_TYPED_START
#define SYM_TYPED_START(name, linkage, align...) \