在 2020年09月03日 07:43, HAGIO KAZUHITO(萩尾 一仁) 写道: > Hi Lianbo, > > -----Original Message----- >> Does this need further input from my site to get merged? Lianbo acked an >> earlier version[1], so this should be fine as is? > Sorry for the delay. Thanks for your patch, Mathias. > as you commented after the ack, I thought you would check the new version > again. Can I merge the v3 patch? > Sure. The v3 looks good. Acked-by: Lianbo Jiang <lijiang@xxxxxxxxxx> Thanks. Lianbo > Thanks, > Kazu > >> >> Thanks, >> Mathias >> >> [1] https://www.redhat.com/archives/crash-utility/2020-August/msg00021.html >> >> Am 25.08.20 um 04:09 schrieb HAGIO KAZUHITO(萩尾 一仁): >>> -----Original Message----- >>>> PaX and grsecurity kernels split module memory into dedicated r/x and >>>> r/w mappings using '*_rw' and '*_rx' named member variables in 'struct >>>> module'. To add basic support for such kernels detect the split layout >>>> by testing for the corresponding structure members and use these >>>> instead. >>>> >>>> So far we limit ourself to only track module code mappings for such >>>> kernels as adding support for separate data mappings violates lots of >>>> invariants in the rest of our code base, thereby would require a major >>>> rework. However, with that patch applied, module code references can be >>>> resolved in backtraces, memory and code dumps, which makes it already >>>> very useful for analyzing such kernels. >>>> >>>> Signed-off-by: Mathias Krause <minipli@xxxxxxxxxxxxxx> >>>> --- >>>> v3: >>>> - dump offsets unconditional >>>> - fix indention of 'module_init_size' offset dump >>> >>> Thanks for the update. The v3 patch looks good to me. >>> >>> Acked-by: Kazuhito Hagio <k-hagio-ab@xxxxxxx> >>> >>> Thanks, >>> Kazu >>> >>>> >>>> v2: >>>> - add members to end of struct offset_table >>>> - add offsets to dump_offset_table() >>>> >>>> defs.h | 13 +++++++++++ >>>> kernel.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++---- >>>> symbols.c | 38 ++++++++++++++++++++++--------- >>>> 3 files changed, 103 insertions(+), 16 deletions(-) >>>> >>>> diff --git a/defs.h b/defs.h >>>> index 17e98763362b..ae860448ab15 100644 >>>> --- a/defs.h >>>> +++ b/defs.h >>>> @@ -654,12 +654,15 @@ struct new_utsname { >>>> #define TIMER_BASES (0x20ULL) >>>> #define IRQ_DESC_TREE_RADIX (0x40ULL) >>>> #define IRQ_DESC_TREE_XARRAY (0x80ULL) >>>> +#define KMOD_PAX (0x100ULL) >>>> >>>> #define XEN() (kt->flags & ARCH_XEN) >>>> #define OPENVZ() (kt->flags & ARCH_OPENVZ) >>>> #define PVOPS() (kt->flags & ARCH_PVOPS) >>>> #define PVOPS_XEN() (kt->flags & ARCH_PVOPS_XEN) >>>> >>>> +#define PAX_MODULE_SPLIT() (kt->flags2 & KMOD_PAX) >>>> + >>>> #define XEN_MACHINE_TO_MFN(m) ((ulonglong)(m) >> PAGESHIFT()) >>>> #define XEN_PFN_TO_PSEUDO(p) ((ulonglong)(p) << PAGESHIFT()) >>>> >>>> @@ -2089,6 +2092,14 @@ struct offset_table { /* stash of commonly-used offsets */ >>>> long size_class_size; >>>> long gendisk_private_data; >>>> long zram_table_entry; >>>> + long module_core_size_rw; >>>> + long module_core_size_rx; >>>> + long module_init_size_rw; >>>> + long module_init_size_rx; >>>> + long module_module_core_rw; >>>> + long module_module_core_rx; >>>> + long module_module_init_rw; >>>> + long module_module_init_rx; >>>> }; >>>> >>>> struct size_table { /* stash of commonly-used sizes */ >>>> @@ -2313,6 +2324,8 @@ struct array_table { >>>> * in the offset table, size table or array_table. >>>> */ >>>> #define OFFSET(X) (OFFSET_verify(offset_table.X, (char *)__FUNCTION__, __FILE__, __LINE__, >> #X)) >>>> +#define MODULE_OFFSET(X,Y) (PAX_MODULE_SPLIT() ? OFFSET(Y) : OFFSET(X)) >>>> +#define MODULE_OFFSET2(X,T) MODULE_OFFSET(X, X##_##T) >>>> #define SIZE(X) (SIZE_verify(size_table.X, (char *)__FUNCTION__, __FILE__, __LINE__, #X)) >>>> #define INVALID_OFFSET (-1) >>>> #define INVALID_MEMBER(X) (offset_table.X == INVALID_OFFSET) >>>> diff --git a/kernel.c b/kernel.c >>>> index f179375f2d3d..f0268adccd4a 100644 >>>> --- a/kernel.c >>>> +++ b/kernel.c >>>> @@ -3540,6 +3540,62 @@ module_init(void) >>>> "module_core"); >>>> MEMBER_OFFSET_INIT(module_module_init, "module", >>>> "module_init"); >>>> + } else if (MEMBER_EXISTS("module", "module_core_rx")) { >>>> + if (CRASHDEBUG(1)) >>>> + error(INFO, "PaX module layout detected.\n"); >>>> + kt->flags2 |= KMOD_PAX; >>>> + >>>> + MEMBER_OFFSET_INIT(module_core_size_rw, "module", >>>> + "core_size_rw"); >>>> + MEMBER_OFFSET_INIT(module_core_size_rx, "module", >>>> + "core_size_rx"); >>>> + >>>> + MEMBER_OFFSET_INIT(module_init_size_rw, "module", >>>> + "init_size_rw"); >>>> + MEMBER_OFFSET_INIT(module_init_size_rx, "module", >>>> + "init_size_rx"); >>>> + >>>> + MEMBER_OFFSET_INIT(module_module_core_rw, "module", >>>> + "module_core_rw"); >>>> + MEMBER_OFFSET_INIT(module_module_core_rx, "module", >>>> + "module_core_rx"); >>>> + >>>> + MEMBER_OFFSET_INIT(module_module_init_rw, "module", >>>> + "module_init_rw"); >>>> + MEMBER_OFFSET_INIT(module_module_init_rx, "module", >>>> + "module_init_rx"); >>>> + } else if (MEMBER_EXISTS("module_layout", "base_rx")) { >>>> + if (CRASHDEBUG(1)) >>>> + error(INFO, "PaX module layout detected.\n"); >>>> + kt->flags2 |= KMOD_PAX; >>>> + >>>> + ASSIGN_OFFSET(module_core_size_rw) = >>>> + MEMBER_OFFSET("module", "core_layout") + >>>> + MEMBER_OFFSET("module_layout", "size_rw"); >>>> + ASSIGN_OFFSET(module_core_size_rx) = >>>> + MEMBER_OFFSET("module", "core_layout") + >>>> + MEMBER_OFFSET("module_layout", "size_rx"); >>>> + >>>> + ASSIGN_OFFSET(module_init_size_rw) = >>>> + MEMBER_OFFSET("module", "init_layout") + >>>> + MEMBER_OFFSET("module_layout", "size_rw"); >>>> + ASSIGN_OFFSET(module_init_size_rx) = >>>> + MEMBER_OFFSET("module", "init_layout") + >>>> + MEMBER_OFFSET("module_layout", "size_rx"); >>>> + >>>> + ASSIGN_OFFSET(module_module_core_rw) = >>>> + MEMBER_OFFSET("module", "core_layout") + >>>> + MEMBER_OFFSET("module_layout", "base_rw"); >>>> + ASSIGN_OFFSET(module_module_core_rx) = >>>> + MEMBER_OFFSET("module", "core_layout") + >>>> + MEMBER_OFFSET("module_layout", "base_rx"); >>>> + >>>> + ASSIGN_OFFSET(module_module_init_rw) = >>>> + MEMBER_OFFSET("module", "init_layout") + >>>> + MEMBER_OFFSET("module_layout", "base_rw"); >>>> + ASSIGN_OFFSET(module_module_init_rx) = >>>> + MEMBER_OFFSET("module", "init_layout") + >>>> + MEMBER_OFFSET("module_layout", "base_rx"); >>>> } else { >>>> ASSIGN_OFFSET(module_core_size) = >>>> MEMBER_OFFSET("module", "core_layout") + >>>> @@ -3682,10 +3738,10 @@ module_init(void) >>>> case KALLSYMS_V2: >>>> if (THIS_KERNEL_VERSION >= LINUX(2,6,27)) { >>>> numksyms = UINT(modbuf + OFFSET(module_num_symtab)); >>>> - size = UINT(modbuf + OFFSET(module_core_size)); >>>> + size = UINT(modbuf + MODULE_OFFSET2(module_core_size, rx)); >>>> } else { >>>> numksyms = ULONG(modbuf + OFFSET(module_num_symtab)); >>>> - size = ULONG(modbuf + OFFSET(module_core_size)); >>>> + size = ULONG(modbuf + MODULE_OFFSET2(module_core_size, rx)); >>>> } >>>> >>>> if (!size) { >>>> @@ -3792,7 +3848,7 @@ verify_modules(void) >>>> break; >>>> case KMOD_V2: >>>> mod_base = ULONG(modbuf + >>>> - OFFSET(module_module_core)); >>>> + MODULE_OFFSET2(module_module_core, rx)); >>>> break; >>>> } >>>> >>>> @@ -3816,10 +3872,10 @@ verify_modules(void) >>>> OFFSET(module_name); >>>> if (THIS_KERNEL_VERSION >= LINUX(2,6,27)) >>>> mod_size = UINT(modbuf + >>>> - OFFSET(module_core_size)); >>>> + MODULE_OFFSET2(module_core_size, rx)); >>>> else >>>> mod_size = ULONG(modbuf + >>>> - OFFSET(module_core_size)); >>>> + MODULE_OFFSET2(module_core_size, rx)); >>>> if (strlen(module_name) < MAX_MOD_NAME) >>>> strcpy(buf, module_name); >>>> else >>>> @@ -5997,6 +6053,8 @@ dump_kernel_table(int verbose) >>>> fprintf(fp, "%sIRQ_DESC_TREE_RADIX", others++ ? "|" : ""); >>>> if (kt->flags2 & IRQ_DESC_TREE_XARRAY) >>>> fprintf(fp, "%sIRQ_DESC_TREE_XARRAY", others++ ? "|" : ""); >>>> + if (kt->flags2 & KMOD_PAX) >>>> + fprintf(fp, "%sKMOD_PAX", others++ ? "|" : ""); >>>> fprintf(fp, ")\n"); >>>> >>>> fprintf(fp, " stext: %lx\n", kt->stext); >>>> diff --git a/symbols.c b/symbols.c >>>> index 2fecaee093a2..311fdb7df29e 100644 >>>> --- a/symbols.c >>>> +++ b/symbols.c >>>> @@ -1766,17 +1766,17 @@ store_module_symbols_v2(ulong total, int mods_installed) >>>> >>>> if (THIS_KERNEL_VERSION >= LINUX(2,6,27)) { >>>> nksyms = UINT(modbuf + OFFSET(module_num_symtab)); >>>> - size = UINT(modbuf + OFFSET(module_core_size)); >>>> + size = UINT(modbuf + MODULE_OFFSET2(module_core_size, rx)); >>>> } else { >>>> nksyms = ULONG(modbuf + OFFSET(module_num_symtab)); >>>> - size = ULONG(modbuf + OFFSET(module_core_size)); >>>> + size = ULONG(modbuf + MODULE_OFFSET2(module_core_size, rx)); >>>> } >>>> >>>> mod_name = modbuf + OFFSET(module_name); >>>> >>>> lm = &st->load_modules[m++]; >>>> BZERO(lm, sizeof(struct load_module)); >>>> - lm->mod_base = ULONG(modbuf + OFFSET(module_module_core)); >>>> + lm->mod_base = ULONG(modbuf + MODULE_OFFSET2(module_module_core, rx)); >>>> lm->module_struct = mod; >>>> lm->mod_size = size; >>>> if (strlen(mod_name) < MAX_MOD_NAME) >>>> @@ -1795,23 +1795,23 @@ store_module_symbols_v2(ulong total, int mods_installed) >>>> lm->mod_flags = MOD_EXT_SYMS; >>>> lm->mod_ext_symcnt = mcnt; >>>> lm->mod_init_module_ptr = ULONG(modbuf + >>>> - OFFSET(module_module_init)); >>>> + MODULE_OFFSET2(module_module_init, rx)); >>>> if (VALID_MEMBER(module_percpu)) >>>> lm->mod_percpu = ULONG(modbuf + OFFSET(module_percpu)); >>>> if (THIS_KERNEL_VERSION >= LINUX(2,6,27)) { >>>> lm->mod_etext_guess = lm->mod_base + >>>> - UINT(modbuf + OFFSET(module_core_text_size)); >>>> + UINT(modbuf + MODULE_OFFSET(module_core_text_size, module_core_size_rx)); >>>> lm->mod_init_size = >>>> - UINT(modbuf + OFFSET(module_init_size)); >>>> + UINT(modbuf + MODULE_OFFSET2(module_init_size, rx)); >>>> lm->mod_init_text_size = >>>> - UINT(modbuf + OFFSET(module_init_text_size)); >>>> + UINT(modbuf + MODULE_OFFSET(module_init_text_size, module_init_size_rx)); >>>> } else { >>>> lm->mod_etext_guess = lm->mod_base + >>>> - ULONG(modbuf + OFFSET(module_core_text_size)); >>>> + ULONG(modbuf + MODULE_OFFSET(module_core_text_size, module_core_size_rx)); >>>> lm->mod_init_size = >>>> - ULONG(modbuf + OFFSET(module_init_size)); >>>> + ULONG(modbuf + MODULE_OFFSET2(module_init_size, rx)); >>>> lm->mod_init_text_size = >>>> - ULONG(modbuf + OFFSET(module_init_text_size)); >>>> + ULONG(modbuf + MODULE_OFFSET(module_init_text_size, module_init_size_rx)); >>>> } >>>> lm->mod_text_start = lm->mod_base; >>>> >>>> @@ -9119,12 +9119,28 @@ dump_offset_table(char *spec, ulong makestruct) >>>> OFFSET(module_core_size)); >>>> fprintf(fp, " module_core_text_size: %ld\n", >>>> OFFSET(module_core_text_size)); >>>> - fprintf(fp, " module_init_size: %ld\n", >>>> + fprintf(fp, " module_init_size: %ld\n", >>>> OFFSET(module_init_size)); >>>> fprintf(fp, " module_init_text_size: %ld\n", >>>> OFFSET(module_init_text_size)); >>>> fprintf(fp, " module_module_init: %ld\n", >>>> OFFSET(module_module_init)); >>>> + fprintf(fp, " module_module_core_rx: %ld\n", >>>> + OFFSET(module_module_core_rx)); >>>> + fprintf(fp, " module_module_core_rw: %ld\n", >>>> + OFFSET(module_module_core_rw)); >>>> + fprintf(fp, " module_core_size_rx: %ld\n", >>>> + OFFSET(module_core_size_rx)); >>>> + fprintf(fp, " module_core_size_rw: %ld\n", >>>> + OFFSET(module_core_size_rw)); >>>> + fprintf(fp, " module_module_init_rx: %ld\n", >>>> + OFFSET(module_module_init_rx)); >>>> + fprintf(fp, " module_module_init_rw: %ld\n", >>>> + OFFSET(module_module_init_rw)); >>>> + fprintf(fp, " module_init_size_rx: %ld\n", >>>> + OFFSET(module_init_size_rx)); >>>> + fprintf(fp, " module_init_size_rw: %ld\n", >>>> + OFFSET(module_init_size_rw)); >>>> fprintf(fp, " module_num_symtab: %ld\n", >>>> OFFSET(module_num_symtab)); >>>> fprintf(fp, " module_symtab: %ld\n", >>>> -- >>>> 2.20.1 >>>> >>>> >>>> -- >>>> Crash-utility mailing list >>>> Crash-utility@xxxxxxxxxx >>>> https://www.redhat.com/mailman/listinfo/crash-utility >>> >>> >>> -- >>> Crash-utility mailing list >>> Crash-utility@xxxxxxxxxx >>> https://www.redhat.com/mailman/listinfo/crash-utility >>> -- Crash-utility mailing list Crash-utility@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/crash-utility