Re: [RFC PATCH] bpf: Add helpers to read useful task_struct members Date: Sat, 4 Nov 2017 18:34:27 +0900 [thread overview] Message-ID: <[email protected]> (raw) I don't think it's a solution. Tracing scripts read other fields too. Making it work for these 3 fields is a drop in a bucket. If randomization is used I think we have to accept that existing bpf scripts won't be usable. Long term solution is to support 'BPF Type Format' or BTF (which is old C-Type Format) for kernel data structures, ... There will be a tool that will take dwarf from vmlinux and compress it into BTF. Kernel will also be able to verify that BTF is a valid BTF. ... LKML thread
BTF (which is old C-Type Format) for kernel data structures, There will be a tool that will take dwarf from vmlinux and compress it into BTF. Kernel will also be able to verify that BTF is a valid BTF. From: Alexei Starovoitov <[email protected]> To: Sandipan Das <[email protected]>, <[email protected]> Subject: Re: [RFC PATCH] bpf: Add helpers to read useful task_struct members Date: Sat, 4 Nov 2017 18:34:27 +0900 [thread overview] Message-ID: <[email protected]> (raw) I don't think it's a solution. Tracing scripts read other fields too. Making it work for these 3 fields is a drop in a bucket. If randomization is used I think we have to accept that existing bpf scripts won't be usable. ... ... LKML thread
magic; __u8 version; __u8 flags; __u32 hdr_len; /* All offsets are in bytes relative to the end of this header */ __u32 type_off; /* offset of type section */ __u32 type_len; /* length of type section */ __u32 str_off; /* offset of string section */ __u32 str_len; /* length of string section */ };
magic; __u8 version; __u8 flags; __u32 hdr_len; /* All offsets are in bytes relative to the end of this header */ __u32 type_off; /* offset of type section */ __u32 type_len; /* length of type section */ __u32 str_off; /* offset of string section */ __u32 str_len; /* length of string section */ };
{ __u16 magic; __u8 version; __u8 flags; /* All offsets are in bytes relative to the end of this header */ __u32 type_off; /* offset of type section */ __u32 type_len; /* length of type section */ __u32 str_off; /* offset of string section */ __u32 str_len; /* length of string section */ };
/* length of type section */ __u32 str_off; /* offset of string section */ __u32 str_len; /* length of string section */ #define BTF_MAGIC 0xeB9F #define BTF_VERSION 1 struct btf_header { __u16 magic; __u8 version; __u8 flags; __u32 hdr_len; /* All offsets are in bytes relative to the end of this header */ };
/* length of string section */ #define BTF_MAGIC 0xeB9F #define BTF_VERSION 1 struct btf_header { __u16 magic; __u8 version; __u8 flags; __u32 hdr_len; /* All offsets are in bytes relative to the end of this header */ __u32 type_off; /* offset of type section */ __u32 type_len; /* length of type section */ };
/* length of type section */ #define BTF_MAGIC 0xeB9F #define BTF_VERSION 1 struct btf_header { __u16 magic; __u8 version; __u8 flags; __u32 hdr_len; /* All offsets are in bytes relative to the end of this header */ __u32 str_off; /* offset of string section */ __u32 str_len; /* length of string section */ };
kind_flag u32 type 0x00 0x02 (BTF_KIND_PTR) 0x00 BTF Types section int data BTF Type Appendix info BTF Type Appendix char int * Data ID 1 2 3 4 5 0x01 BTF_KIND_PTR
kind_flag u32 type 0x00 0x02 (BTF_KIND_PTR) 0x00 BTF Types section int data BTF Type Appendix info BTF Type Appendix char int * Data ID 1 2 3 4 5 0x01 BTF_KIND_PTR
kind_flag u32 type 0x00 0x02 (BTF_KIND_PTR) 0x00 BTF Types section int data BTF Type Appendix info BTF Type Appendix char int * Data ID 1 2 3 4 5 0x01 BTF_KIND_PTR
kind_flag u32 type 0x00 0x02 (BTF_KIND_PTR) 0x00 BTF Types section int data BTF Type Appendix info BTF Type Appendix char int * Data ID 1 2 3 4 5 0x01 BTF_KIND_PTR
kind_flag u32 type 0x00 0x02 (BTF_KIND_PTR) 0x00 BTF Types section int data BTF Type Appendix info BTF Type Appendix char int * Data ID 1 2 3 4 5 0x01 BTF_KIND_PTR
kind_flag u32 type 0x00 0x02 (BTF_KIND_PTR) 0x00 BTF Types section int data BTF Type Appendix info BTF Type Appendix char int * Data ID 1 2 3 4 5 0x01 BTF_KIND_PTR
u32 size 0x02 0x04 (BTF_KIND_STRUCT) 0x00 BTF Types section int data BTF Type Appendix info BTF Type Appendix char int * Data ID 1 2 3 4 5 0x10 BTF_KIND_STRUCT u32 name_off u32 type u32 offset 1 struct btf_member[] (BTF Type Appendix) u32 name_off u32 type u32 offset 2 0x30 0x35 0x02 0x01 0x00 0x00
u32 size 0x02 0x04 (BTF_KIND_STRUCT) 0x00 BTF Types section int data BTF Type Appendix info BTF Type Appendix char int * Data ID 1 2 3 4 5 0x10 BTF_KIND_STRUCT u32 name_off u32 type u32 offset 1 struct btf_member[] (BTF Type Appendix) u32 name_off u32 type u32 offset 2 0x30 0x35 0x02 0x01 0x00 0x00
u32 size 0x02 0x04 (BTF_KIND_STRUCT) 0x00 BTF Types section int data BTF Type Appendix info BTF Type Appendix char int * Data ID 1 2 3 4 5 0x10 BTF_KIND_STRUCT u32 name_off u32 type u32 offset 1 struct btf_member[] (BTF Type Appendix) u32 name_off u32 type u32 offset 2 0x30 0x35 0x02 0x01 0x00 0x00
u32 size 0x02 0x04 (BTF_KIND_STRUCT) 0x00 BTF Types section int data BTF Type Appendix info BTF Type Appendix char int * Data ID 1 2 3 4 5 0x10 BTF_KIND_STRUCT u32 name_off u32 type u32 offset 1 struct btf_member[] (BTF Type Appendix) u32 name_off u32 type u32 offset 2 0x30 0x35 0x02 0x01 0x00 0x00
u32 size 0x02 0x04 (BTF_KIND_STRUCT) 0x00 BTF Types section int data BTF Type Appendix info BTF Type Appendix char int * Data ID 1 2 3 4 5 0x10 BTF_KIND_STRUCT u32 name_off u32 type u32 offset 1 struct btf_member[] (BTF Type Appendix) u32 name_off u32 type u32 offset 2 0x30 0x35 0x02 0x01 0x00 0x00
u32 size 0x02 0x04 (BTF_KIND_STRUCT) 0x00 BTF Types section int data BTF Type Appendix info BTF Type Appendix char int * Data ID 1 2 3 4 5 0x10 BTF_KIND_STRUCT u32 name_off u32 type u32 offset 1 struct btf_member[] (BTF Type Appendix) u32 name_off u32 type u32 offset 2 0x30 0x35 0x02 0x01 0x00 0x00
u32 size 0x02 0x04 (BTF_KIND_STRUCT) 0x00 BTF Types section int data BTF Type Appendix info BTF Type Appendix char int * Data ID 1 2 3 4 5 0x10 BTF_KIND_STRUCT u32 name_off u32 type u32 offset 1 struct btf_member[] (BTF Type Appendix) u32 name_off u32 type u32 offset 2 0x30 0x35 0x02 0x01 0x00 0x00
hdr_len; /* All offsets are in bytes relative to the end of this header */ __u32 func_info_off; __u32 func_info_len; __u32 line_info_off; __u32 line_info_len; /* optional part of .BTF.ext header */ __u32 core_relo_off; __u32 core_relo_len; };
{ /* All offsets are in bytes relative to the end of this header */ __u32 func_info_off; __u32 func_info_len; __u32 line_info_off; __u32 line_info_len; /* optional part of .BTF.ext header */ __u32 core_relo_off; __u32 core_relo_len; };
version; __u8 flags; __u32 hdr_len; /* All offsets are in bytes relative to the end of this header */ __u32 line_info_off; __u32 line_info_len; /* optional part of .BTF.ext header */ __u32 core_relo_off; __u32 core_relo_len; };
version; __u8 flags; __u32 hdr_len; /* All offsets are in bytes relative to the end of this header */ __u32 func_info_off; __u32 func_info_len; /* optional part of .BTF.ext header */ __u32 core_relo_off; __u32 core_relo_len; };
version; __u8 flags; __u32 hdr_len; /* All offsets are in bytes relative to the end of this header */ __u32 func_info_off; __u32 func_info_len; __u32 line_info_off; __u32 line_info_len; /* optional part of .BTF.ext header */ };
is for __u32 insn_off; // offset of the file name in the string section __u32 file_name_off; // offset of the source line in the string section __u32 line_off; // line/column information of line in source file __u32 line_col; };
insn_off; struct bpf_line_info { // offset of the file name in the string section __u32 file_name_off; // offset of the source line in the string section __u32 line_off; // line/column information of line in source file __u32 line_col; };
__u32 file_name_off; struct bpf_line_info { // offset of the instruction this info is for __u32 insn_off; // offset of the source line in the string section __u32 line_off; // line/column information of line in source file __u32 line_col; };
__u32 line_off; struct bpf_line_info { // offset of the instruction this info is for __u32 insn_off; // offset of the file name in the string section __u32 file_name_off; // line/column information of line in source file __u32 line_col; };
struct bpf_line_info { // offset of the instruction this info is for __u32 insn_off; // offset of the file name in the string section __u32 file_name_off; // offset of the source line in the string section __u32 line_off; };
__u32 insn_off; // target type of the relocation __u32 type_id; // relocation access string (points to string in strings section) __u32 access_str_off; // kind of relocation (see `enum bpf_core_relo_kind`) enum bpf_core_relo_kind kind; };
struct bpf_core_relo { // offset of the instruction to patch __u32 insn_off; // target type of the relocation __u32 type_id; // relocation access string (points to string in strings section) __u32 access_str_off; };
*/ BPF_CORE_FIELD_BYTE_SIZE = 1, /* field size in bytes */ BPF_CORE_FIELD_EXISTS = 2, /* field existence in target kernel */ BPF_CORE_FIELD_SIGNED = 3, /* field signedness (0 - unsigned, 1 - signed) */ BPF_CORE_FIELD_LSHIFT_U64 = 4, /* bitfield-specific left bitshift */ BPF_CORE_FIELD_RSHIFT_U64 = 5, /* bitfield-specific right bitshift */ BPF_CORE_TYPE_ID_LOCAL = 6, /* type ID in local BPF object */ BPF_CORE_TYPE_ID_TARGET = 7, /* type ID in target kernel */ BPF_CORE_TYPE_EXISTS = 8, /* type existence in target kernel */ BPF_CORE_TYPE_SIZE = 9, /* type size in bytes */ BPF_CORE_ENUMVAL_EXISTS = 10, /* enum value existence in target kernel */ BPF_CORE_ENUMVAL_VALUE = 11, /* enum value integer value */ BPF_CORE_TYPE_MATCHES = 12, /* type match in target kernel */ }; Check out on Bootlin
__u32 insn_off; // target type of the relocation __u32 type_id; // relocation access string (points to string in strings section) __u32 access_str_off; // kind of relocation (see `enum bpf_core_relo_kind`) enum bpf_core_relo_kind kind; };
bpf_core_relo { // target type of the relocation __u32 type_id; // relocation access string (points to string in strings section) __u32 access_str_off; // kind of relocation (see `enum bpf_core_relo_kind`) enum bpf_core_relo_kind kind; };
{ // offset of the instruction to patch __u32 insn_off; // relocation access string (points to string in strings section) __u32 access_str_off; // kind of relocation (see `enum bpf_core_relo_kind`) enum bpf_core_relo_kind kind; };
__u32 access_str_off; struct bpf_core_relo { // offset of the instruction to patch __u32 insn_off; // target type of the relocation __u32 type_id; // kind of relocation (see `enum bpf_core_relo_kind`) enum bpf_core_relo_kind kind; };
__u32 access_str_off; // kind of relocation (see `enum bpf_core_relo_kind`) enum bpf_core_relo_kind kind; struct bpf_core_relo { // offset of the instruction to patch __u32 insn_off; // target type of the relocation __u32 type_id; };
*)bpf_get_current_task(); u32 state; // Loader will patch this to return false if(bpf_core_field_exists(t->__state)) { // Offset to read will be batched to 0xbad2310 state = BPF_CORE_READ(t, __state); } else { struct task_struct___before514 *t_old = (void *)t; state = BPF_CORE_READ(t_old, state); }
*t_old = (void *)t; state = BPF_CORE_READ(t_old, state); struct task_struct *t = (void *)bpf_get_current_task(); u32 state; // Loader will patch this to return false if(bpf_core_field_exists(t->__state)) { // Offset to read will be batched to 0xbad2310 state = BPF_CORE_READ(t, __state); }
*)bpf_get_current_task(); u32 state; // Loader will patch this to return false if(bpf_core_field_exists(t->__state)) { // Offset to read will be batched to 0xbad2310 state = BPF_CORE_READ(t, __state); } else { struct task_struct___before514 *t_old = (void *)t; state = BPF_CORE_READ(t_old, state); }
task_struct *t = (void *)bpf_get_current_task(); u32 state; // Loader will patch this to return true if(bpf_core_field_exists(t->__state)) { } else { struct task_struct___before514 *t_old = (void *)t; // Offset to read will be batched to 0xbad2310 state = BPF_CORE_READ(t_old, state); }
*)t; // Offset to read will be batched to 0xbad2310 state = BPF_CORE_READ(t_old, state); struct task_struct *t = (void *)bpf_get_current_task(); u32 state; // Loader will patch this to return true if(bpf_core_field_exists(t->__state)) { state = BPF_CORE_READ(t, __state); } else { }